skaut / Skautis

PHP knihovna pro připojení do skautISu
BSD 3-Clause "New" or "Revised" License
12 stars 11 forks source link

BaseException #8

Closed JindrichPilar closed 10 years ago

JindrichPilar commented 11 years ago

Mohu se zeptat co je za třídu BaseException?

A druhy dotaz. K čemu má sloužit funkce setStorage?

sinacek commented 11 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ě.

JindrichPilar commented 11 years ago

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.

sinacek commented 11 years ago

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.

JindrichPilar commented 11 years ago

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)

sinacek commented 11 years ago

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

JindrichPilar commented 11 years ago

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

sinacek commented 11 years ago

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.