Seite 1 von 1
Timeout bei Aufruf der Frontend-Gruppenberechtigungen
Verfasst: Di 5. Aug 2008, 05:24
von achiboy
Hallo
Mit Contenido 4.8.7 kriege ich beim Aufruf der Frontend-Berechtigungen einer Gruppe einen Timeout.
[05-Aug-2008 06:14:49] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /xxx/xxx/xxx/contenido/includes/functions.general.php on line 761
Verfasst: Di 5. Aug 2008, 10:32
von tono
Wieviele Kategorien hast Du?
Wieviele davon sind geschützt?
Tritt das Problem nur mit einer Gruppe auf?
Gibt es Einträge im Errorlog?
Verfasst: Mi 6. Aug 2008, 08:41
von achiboy
Es sind etwa 60 Kategorien.
Davon sind 10 geschützt.
Das Problem tritt bei allen Gruppen auf
Es gibt keine Errorlog-Einträge ausser der geposteten Fehlermeldung
Das Problem tritt bei all meinen Installationen mit der aktuellsten Version auf.
Verfasst: Mi 6. Aug 2008, 09:10
von tono
Ist die angegebene Datei und Zeilennummer immer gleich? Warscheinlich nicht, oder?
Hast Du mal geschaut, ob irgendwelche Datenbanktabellen optimiert oder repariert werden müssten? (mit phpmyadmin z.B.)
Verfasst: Mi 6. Aug 2008, 09:47
von Dodger77
verschoben
Ich kann das nachvollziehen. Einfacher Test: lokal auf meinem XAMPP mit allen Kategorien des Beispielmandanten geschützt liegt die Ausführungszeit bei über 30 Sekunden.
Verfasst: Mi 6. Aug 2008, 09:49
von Dodger77
Habe folgendes gerade im SVN eingecheckt:
Datei "contenido/plugins/frontendlogic/category/category.php" ändern zu:
Code: Alles auswählen
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
*
* Requirements:
* @con_php_req 5.0
*
*
* @package Contenido Backend classes
* @version 1.1.1
* @author Andreas Lindner, Unknown
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*
* {@internal
* created
* modified 2008-08-06, Ingo van Peeren - replaced genericdb-code due to performance issues (ticket #)
*
* $Id:
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
cInclude("classes", "class.frontend.logic.php");
class frontendlogic_category extends FrontendLogic
{
function getFriendlyName ()
{
return i18n("Category", "frontendlogic_category");
}
function listActions ()
{
$actions = array();
$actions["access"] = i18n("Access category", "frontendlogic_category");
return ($actions);
}
function listItems ()
{
global $lang, $db, $cfg;
if (!is_object($db)) {
$db = new DB_Contenido;
}
$sSQL = "SELECT
b.idcatlang,
b.name,
c.level
FROM
".$cfg['tab']['cat']." AS a,
".$cfg['tab']['cat_lang']." AS b,
".$cfg['tab']['cat_tree']." AS c
WHERE
a.idcat = b.idcat AND
a.idcat = c.idcat AND
b.idlang = ".$lang." AND
b.public = 0
ORDER BY c.idtree ASC";
$db->query($sSQL);
while ($db->next_record()) {
$items[$db->f("idcatlang")] =
'<span style="padding-left: '.($db->f("level")*10).'px;">'.htmldecode($db->f("name")).'</span>';
}
return ($items);
}
}
?>
Gleiche Liste wird bei mir dann in 0,07 Sekunden erzeugt.
Verfasst: Mi 6. Aug 2008, 10:22
von tono
Ich konnte das Problem nicht reproduzieren.
Von > 30 sec. auf 0,7 nur durch weglassen der genericdb?? Da steckt doch garantiert ein Bug drin. Soviel Overhead produziert das auch wieder nicht.
Verfasst: Mi 6. Aug 2008, 10:45
von Dodger77
Ich habe einfach mit dem Beispielmandanten lokal auf XAMPP getestet. Mit einer geschützten Kategorie lag ich bei ca. 1 Sekunde. Je weiterer Kategorie kommt nochmal dasselbe hinzu.
Das lässt sich auch auf meinem Webserver reproduzieren. Dort zurzeit mit ca. 1,9 Sekunden je Kategorie.
Verfasst: Mi 6. Aug 2008, 11:05
von Dodger77
Das Problem tritt anscheinend durch das Hinzufügen des 2. JOIN auf:
Code: Alles auswählen
$cApiCategoryCollection->link("cApiCategoryTreeCollection");
Verfasst: Mi 6. Aug 2008, 11:26
von Dodger77
OK, fieser Bug. Aber wo ganz anders: "contenido/classes/drivers/mysql/class.gdb.mysql.php".
Die Methode "buildJoinQuery" macht folgendes:
Code: Alles auswählen
$join = "LEFT JOIN $destinationTable AS $destinationClass ON " . Contenido_Security::toInteger($sourceClass.$primaryKey) . " = " . Contenido_Security::toInteger($destinationClass.$primaryKey);
Das ist resultiert dann in einem
Verfasst: Mi 6. Aug 2008, 12:01
von Dodger77
OK, sehe gerade, das ist im SVN schon gefixt.
"contenido/classes/drivers/mysql/class.gdb.mysql.php" ändern in:
Code: Alles auswählen
<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* MySQL Driver for GenericDB
*
* Requirements:
* @con_php_req 5.0
*
*
* @package Contenido Backend classes
* @version 1.12
* @author Bjoern Behrens
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*
* {@internal
* created 2006-05-10
* modified 2008-05-23 Added Debug_DevNull and Debug_VisibleAdv
*
* $Id: class.gdb.mysql.php 659 2008-08-04 22:17:55Z HerrB $
* }}
*
*/
if(!defined('CON_FRAMEWORK')) {
die('Illegal call');
}
cInclude("classes", 'drivers/class.gdb.driver.php');
cInclude("classes", "class.security.php");
class gdbMySQL extends gdbDriver
{
function buildJoinQuery ($destinationTable, $destinationClass, $destinationPrimaryKey, $sourceClass, $primaryKey)
{
// Build a regular LEFT JOIN
$field = "$destinationClass.$destinationPrimaryKey";
$tables = "";
$join = "LEFT JOIN $destinationTable AS $destinationClass ON " .
Contenido_Security::toString($sourceClass . "." . $primaryKey) . " = " .
Contenido_Security::toString($destinationClass . "." . $primaryKey);
$where = "";
return array("field" => $field, "table" => $tables, "join" => $join, "where" => $where);
}
function buildOperator ($sField, $sOperator, $sRestriction)
{
$sOperator = strtolower($sOperator);
$sWhereStatement = "";
switch ($sOperator)
{
case "matchbool":
$sqlStatement = "MATCH (%s) AGAINST ('%s' IN BOOLEAN MODE)";
$sWhereStatement = sprintf($sqlStatement, $sField, $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "match":
$sqlStatement = "MATCH (%s) AGAINST ('%s')";
$sWhereStatement = sprintf($sqlStatement, $sField, $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "like":
$sqlStatement = "%s LIKE '%%%s%%'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "likeleft":
$sqlStatement = "%s LIKE '%s%%'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "likeright":
$sqlStatement = "%s LIKE '%%%s'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "notlike":
$sqlStatement = "%s NOT LIKE '%%%s%%'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "notlikeleft":
$sqlStatement = "%s NOT LIKE '%s%%'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "notlikeright":
$sqlStatement = "%s NOT LIKE '%%%s'";
$sWhereStatement = sprintf($sqlStatement, Contenido_Security::toString($sField), $this->_oItemClassInstance->_inFilter($sRestriction));
break;
case "diacritics":
cInclude("classes", "class.chartable.php");
if (!is_object($GLOBALS["_cCharTable"]))
{
$GLOBALS["_cCharTable"] = new cCharacterConverter;
}
$aliasSearch = array ();
$metaCharacters = array ("*", "[", "]", "^", '$', "\\", "*", "'", '"', '+');
for ($i = 0; $i < strlen($sRestriction); $i ++)
{
$char = substr($sRestriction, $i, 1);
$aliases = array ();
$aliases = array_merge($aliases, $GLOBALS["_cCharTable"]->fetchDiacriticCharactersForNormalizedChar($this->_sEncoding, $char));
$normalizedChars = $GLOBALS["_cCharTable"]->fetchNormalizedCharsForDiacriticCharacter($this->_sEncoding, $char);
foreach ($normalizedChars as $normalizedChar)
{
$aliases = array_merge($aliases, $GLOBALS["_cCharTable"]->fetchDiacriticCharactersForNormalizedChar($this->_sEncoding, $normalizedChar));
}
$aliases = array_merge($aliases, $normalizedChars);
if (count($aliases) > 0)
{
$aliases[] = $char;
$allAliases = array ();
foreach ($aliases as $alias)
{
$alias1 = $this->_oItemClassInstance->_inFilter($alias);
$allAliases[] = $alias1;
$allAliases[] = $alias;
}
$allAliases = array_unique($allAliases);
$aliasSearch[] = "(".implode("|", $allAliases).")";
} else
{
$addChars = array();
if (in_array($char, $metaCharacters))
{
$addChars[] = "\\\\".$char;
} else
{
$addChars[] = $char;
$vChar = $this->_oItemClassInstance->_inFilter($char);
if ($char != $vChar)
{
if (in_array($vChar, $metaCharacters))
{
$addChars[] = "\\\\".$vChar;
} else {
$addChars[] = $vChar;
}
}
}
$aliasSearch[] = "(".implode("|", $addChars).")";
}
}
$restriction = "'".implode("", $aliasSearch)."'";
$sWhereStatement = implode(" ", array ($sField, "REGEXP", $restriction));
break;
case "fulltext":
break;
case "in":
if (is_array($sRestriction))
{
$items = array();
foreach ($sRestriction as $key => $sRestrictionItem)
{
$items[] = "'".$this->_oItemClassInstance->_inFilter($sRestrictionItem)."'";
}
$sRestriction = implode(", ", $items);
} else {
$sRestriction = "'" . $sRestriction ."'";
}
$sWhereStatement = implode(" ", array($sField, "IN (", $sRestriction, ")"));
break;
default :
$sRestriction = "'".$this->_oItemClassInstance->_inFilter($sRestriction)."'";
$sWhereStatement = implode(" ", array ($sField, $sOperator, $sRestriction));
}
return $sWhereStatement;
}
}
?>
Verfasst: Mi 6. Aug 2008, 14:57
von tono
Dodger77 hat geschrieben:OK, sehe gerade, das ist im SVN schon gefixt.
Dann ist das auch der Grund warum der Fehler bei mir nicht reproduzierbar war.
Verfasst: Fr 8. Aug 2008, 05:42
von achiboy
muss ich die erste Änderung in der Datei "contenido/plugins/frontendlogic/category/category.php" rückgängig machen?
Verfasst: Fr 8. Aug 2008, 06:22
von Dodger77
Die kannst du auch problemlos so lassen.
Verfasst: Fr 8. Aug 2008, 06:23
von achiboy
besten Dank für eure Hilfe.