RobotLoader::addClass – nespravna vynimka pri kolizii nazvov tried
- viktorc
- Člen | 21
V RobotLoader (Nette 1.0-dev 64b5b90 z 2010–09–17 pre PHP 5.2 bez prefixov) je jeden preklep a dve vaznejsie chyby.
- preklep RobotLoader::addClass: $class → $lClass na konci vyvolania InvalidStateException:
<?php
...
$lClass = strtolower($class);
if (!empty($this->list[$lClass]) && $this->list[$lClass][0] !== $file && is_file($this->list[$lClass][0])) {
spl_autoload_call($class); // hack: enables exceptions
//throw new InvalidStateException("Ambiguous class '$class' resolution; defined in $file and in " . $this->list[$class][0] . ".");
throw new InvalidStateException("Ambiguous class '$class' resolution; defined in $file and in " . $this->list[$lClass][0] . ".");
}
...
?>
- Vacsi problem je vsak ak sa vyskytne kolizia nazvov tried.
Konkretny priklad: subor nSMTPMailer/exceptions.php z nSMTPMailera definuje InvalidStateException a IOException, ktore su definuje aj Nette v Utils/exceptions.php.
Spravne by mal addClass vyhodit InvalidStateException s informaciou o duplicite tychto tried v oboch suboroch. Bohuzial (nezmyselnu) vynimku vyhodi uz spl_autoload_call:
Fatal error: Cannot redeclare class ArgumentOutOfRangeException in …\Nette\Utils\exceptions.php on line 39
Trieda ArgumentOutOfRangeException vsak nema koliziu (zobrazuje sa pravdepodobne preto, lebo je prva v Nette\Utils\exceptions.php). Potom da dost roboty najst pricinu problemu.
Je nutne volat v addClass pri zisteni kolizii nazvov tried pred vyhodenim vynimky spl_autoload_call?
Poznamky:
Ked som zakomentoval deklaraciu InvalidStateException
v nSMTPMailer/exceptions.php (zostala duplicitna IOException),
vyhodila sa (podla ocakavania) rovnaka nezmyselna vynimka.
Ked som vsak zakomentoval aj IOException a doplnil do oboch suborov definiciu TestException, vyhodila sa (nechapem preco) spravna vynimka InvalidStateException.
- Nefunguju vynimky pre RobotLoader v subore netterobots.txt. Problem je niekde v RobotLoader::scanDirectory, pravdepodobne pri definovani filtra pre Finder.
<?php
...
$iterator->append(Finder::find(String::split($this->acceptFiles, '#[,\s]+#'))
->from($dir)
->exclude(String::split($this->ignoreDirs, '#[,\s]+#'))
->filter(create_function('$file', 'list($disallow) = NClosureFix::$vars['.NClosureFix::uses(array(&$disallow)).'];
return !isset($disallow[$file->getPathname()]);
'))->getIterator()
);
...
?>
Pole $disallow sa naplni spravne, ale Finder porovnava aktualnu polozku (subor, ci adresar) s obsahom pola $disallow len pre adresare.
Chyby c. 1 a 3 su nove v Nette 1.0 (v 0.9.5 neboli). Chyba c. 2 je
stara, ale tam sa vdaka fungujucemu netterobots.txt pri
nSMTPMailer-i neprejavi.
Sorry, ze som sa tak rozkecal ;-)
- Filip Procházka
- Moderator | 4668
Já tam teda chybu nevidím a co se týče té vyjímky tak je naprosto logická, pokud máš nějaké rozšíření a to má u sebe třídy Nette, protože je postavené, aby šlo používat bez něj, tak se nemůžeš divit že budou nastávat kolize.
Třídy které jsou navíc smaž nebo jim dej namespace té knihovničky a uprav závislosti
- David Grudl
- Nette Core | 8228
„Fatal error“ není výjimka, ale fatal error. Nepoužíváš víc autoloadingů a nedělá problémy ten druhý? Já v RobotLoaderu žádnou chybu nevidím.
ale Finder porovnava aktualnu polozku (subor, ci adresar) s obsahom pola $disallow len pre adresare.
Ok, upravím aby porovnával i pro soubory.
- viktorc
- Člen | 21
Viac autoloadingov nepouzivam. Problem je len ked sa prekryju nazvy vynimiek z Utils/exceptions.php.
Vtedy Ladenka vypise:
„Compile Error
Cannot redeclare class ArgumentOutOfRangeException“ (nezavisle od toho, ktora
trieda je problem).
namiesto predpokladaneho:
„InvalidStateException
Ambiguous class…“
Ak je v addClass zakomentovane spl_autoload_call, vypise sa korektna vynimka so spravnym popisom duplicity. Ak to tam vsak musi z nejakeho dovodu zostat, tak to tam samozrejme nechaj. Toto sa asi prilis casto neprejavi.
Pri inych triedach, alebo vynimkach Nette to funguje spravne vzdy (aspon co som skusal).
- David Grudl
- Nette Core | 8228
Tu chybu nepíše robotloader, ale vzniká při načítání skriptu přes require. Vyvolá jej zřejmě druhý autoloader, což může být i NetteLoader. Řešením je neindexovat duplicitní třídy a třeba zmíněný soubor zakázat přes netterobots.txt
- David Grudl
- Nette Core | 8228
Omlouvám, ta chyba v překlepu $class → $lClass tam skutečně byla, opraveno.
Upravil jsem RobotLoader tak, aby nemusel spl_autoload_call
volat (to byl hack pro PHP 5.2, kde nelze při autoloadingu vyhodit výjimku).
Tak to snad už bude fungovat OK.