Closed JindrichPilar closed 10 years ago
BaseException jsem udělal jako předka všech vyjímek co vyhazuje knihovna, aby se jednoduše dalo zjistit, že chyba jde z komunikace se skautisem.
Funkce setStorage má využití, pokud si chceš nastavit vlastní místo pro uložení informací ať kvůli zvyklosti či bezpečnosti. Já to využívám s Nette pro nastavení uložiště přes Nette Session, protože jsem měl problém s přemazáváním. Takto mám vše pod Nette Session a jede to vpohodě.
Problem je ze BaseException neni nikde deklarovan. Tedy pri pokusu vytvorit a hodit vyjimku aplikace spadne.
setStorage bohuzel nefunguje presne tak jak by mela. V kodu je priklad:
příklad použití: $skautIS->setStorage(&\Nette\Environment::getSession()->getSection("__" . __CLASS__), TRUE);
volani funkce(&promenna) bylo odstraneno z PHP. (V PHP5.4+ fatal error) Z dokumentace:
Note: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.
Tedy na serverech s aktualnim PHP funkce funguje tak ze pole apod. se predaji hodnotou, coz neni uplne to co je zamysleno (z toho co jsi psal). Take by nebylo spatne v definici funkce type hintnout ArrayAccess, ktery je potrebny pro spranvou manipulaci s ukladani dat. Na druhou ArrayAccess neni kompatibilni s array (trochu na hlavu). Ovsem pokud by se vynucoval ArrayAccess, musel by to byt objekt -> automaticky predavan referenci.
Omlouvám se, měl jsem konflikt při psuh a nevšiml jsme si ho, už je to tam.
K setStorage jsem doplnil type hint, jak jsi psal (https://github.com/sinacek/SkautIS/blob/master/src/SkautIS/SkautIS.php#L161).
Co se týká předávání referencí, tak to co píšeš je, když bych měl referenci v deklaraci třídy a ne ve volání funkce. Chvilku to bylo špatně, ale od doby co tam je příklad, tak by to mělo být už ok.
Tohle je pouze pro dokumentaci, type hint by byl takhle:
public function setStorage(ArrayAccess $storage, $leaveValues = false) {
}
Naopak, reference se maji vynucovat pri definici funkce. Pro jistotu jsem to zkousel a funkce(&promenna) mi spadne (PHP 5.4)
Jo, tak vynucovat to nehci, už z toho důvodu co píšeš nahoře. Chci možnost zadat array i ArrayAccess, je to tak marginalni funkciolita podle mě, že by si uživatel měl načíst dokumentaci co tam má poslat.
Když udělam deklaraci public function setStorage(&$storage, $leaveValues = false) {...}, tak pak mi to hází chybu "PHP Strict standards: Only variables should be passed by reference in ..." na PHP 5.4.4
Ono je tam problemu vic, tady je ukazka tech ktere me napadli pri cteni kodu.
S polem to stejne nefunguje. (protoze se tam pristupuje ->init["cokoliv"]) Muselo by se pole pretypovat na objekt ($skautIS->setStorage((object)$arr);)
$skautIS = \SkautIS\SkautIS::getInstance();
$arr = array();
$skautIS->setStorage($arr);
$skautIS->setAppId("123a456b789d"); //PHP Warning: Attempt to modify property of non-object in
Predani reference za behu 5.4+nefunguje
//error_reporting(0); // aby se to nezasavilo pri warningu
require 'vendor/autoload.php';
$skautIS = \SkautIS\SkautIS::getInstance();
$arr = array();
$skautIS->setStorage(&$arr); // PHP Fatal error: Call-time pass-by-reference has been removed in
$skautIS->setAppId("123a456b789d"); // neprovede se
var_dump($skautIS->getAppId()); // neprovede se
S objektem funguje spravne i bez &. Naopak s & spadne
error_reporting(0); // aby se to nezasavilo pri warningu
require 'vendor/autoload.php';
$skautIS = \SkautIS\SkautIS::getInstance();
$obj = new stdClass();
$skautIS->setStorage($obj);
$skautIS->setAppId("123a456b789d");
var_dump($skautIS->getAppId() === $obj->init['ID_Application']);
Co se tyce toho `PHP Strict standards: Only variables should be passed by reference`` Tak problem je nejspis v tom ze tam nedavas promenou ale data vytvaris ve volani fce, tedy takhle:
function zmenPole(&$arr) {
$arr[0] = "NE";
}
// Nemam vytvorenou promenou, proto nemuzu z ni vzit referenci.. a proto ji nemuzu predat funkci
zmenPole(array());
Spravne je to takto
function zmenPole(&$arr) {
$arr[0] = "NE";
}
$mojePole = array("ANO");
echo $mojePole[0]; //ANO
echo "-";
// tady mam z ceho vzit referenci
zmenPole($mojePole);
echo $mojePole[0]; //NE
Pokud jsi pro, mohl bych doplnit nejake unit testy
Tak já to mám u sebe jinak než jsem si myslel, mam to použité bez referencí(upravil jsem tedka i zdrojak). Ta moje chyba se vyřešila, když jsem to rozdělil na dva řádky. $storage = \Nette\Environment::getSession()->getSection("" . __CLASS); $this->context->skautIS->setStorage($storage, TRUE);
Ok, upravil jsem to podle tvých rad, díky.
Určitě budu rád za cokoliv, čím někdo přispěje ke knihovně, takže i za unit testy.
Mohu se zeptat co je za třídu
BaseException
?A druhy dotaz. K čemu má sloužit funkce setStorage?