Приветствую!
userxp попросил меня отписать здесь о возможных исправлениях для OpenSEF RC5 SP2, так что все "спасибы" и претензии к нему :-)
Итак, корень всех зол заключается в том, что OpenSEF почти всю табличку jos_opensef_sef вытягивает в массив в самом начале своей работы а после этого полным перебором (ужас!) искать там соответствие внутренняю УРЛ - внешняя УРЛ и наоборот. При этом, в случае, если сайт довольно обширный, и ЧПУ на нем много, массив получается просто огроменным. У меня на сайте с 17000 статей ПХП умирал с воем "не хватает памяти" при ограничении в 16Мб. Первый фикс был просто призван уменьшить количество записей, размещаемых в памяти. Но.. не тут-то было. Оказывается, OpenSEF этот же глобальный массив использует для всех-всех ссылок, котрые Джумла пытается привести "человеский вид" (перекрывается ф-я sefRelToAbs). Естесственно, простая фильтрация результатов запроса по REQUEST_URI нас уже не спасет. Пробуем следующий фикс:
В файле administrator/components/com_sef/sef.class.php находим ф-ю lookupOutgoing, комментируем то, что там есть, и заменяем вот этим:
function lookupOutgoing( $site_id, $url ) { // static method
global $opensef_aliases, $database;
$returnaliases = array();
/*
if ($site_id == null) $site_id = -1;
if (count($opensef_aliases) > 0) {
foreach($opensef_aliases as $aliases){
if ( $aliases->internal == $url ) {
$returnaliases[] = $aliases;
}
}
}
*/
if (!count($returnaliases))
{
$query = "SELECT * FROM #__opensef_sef WHERE published = '1'" .
"\nAND valid = '1'" .
"\nAND (direction IS NULL OR direction = '' OR direction = 'o')" .
"\nAND internal='$url'".
"\nORDER BY site_id DESC, published DESC, valid DESC, LENGTH(direction) DESC limit 1";
$database->setQuery( $query );
if ($database->loadResult())
{
$aliases = $database->loadObjectList();
foreach($aliases as $k=>$val)
{
$returnaliases[] = $val;
}
}
}
if (is_array( $returnaliases ) && count( $returnaliases )) {
$returnaliases = xclCastObjectList( $returnaliases, 'JosOpenSEFAlias' );
return $returnaliases[0];
}
$null = null;
return $null;
}
Если хостер додумался включить кеширование запросов для MySQL - работать будет отлично, в противном случае, придется Вам всем подождать, пока я не проверю свою идею с кешированием результатов для lookupOutgoing или кто-то другой не придумает чего-то получше.
Не забываем, что первый фикс тоже надо оставить (на самом деле, вообще надо убрать этот глобальный массив и запрос, который в него вытягивает данные, но я пока не знаю, как лучше всего это сделать).
Спасибо. Жду отзывов.