PHP annotations

 ( raavi | 2018. október 12., péntek - 10:06 )

Sziasztok,

Tudnátok segíteni merre találok használható leírást, hogy hogyan lehet PHP custom annotation-t definiálni?
Pusztán csak a tanulás és kíváncsiság kedvéért.....
Alapvetően amit szeretnék egy elegáns megoldást a fügvény/method input validálásra. Bár nem vagyok benne biztos, hogy alkalmas lehet erre.

Pl.:
/**
* @ValidInputKeys=['key1'=>"int",'key2'=>"callable" .... ]
*/
public function myFunc($args = [])
{
....do something
}

Ezt atláltam de nem igazán fogtam fel:
https://php-annotations.readthedocs.io/en/latest/UsingAnnotations.html

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

A PHP nem tud ilyet. Amit linkeltél, abban gyakorlatilag egy saját PHP parsert implementáltak. Ez szerintem nagyon nem jó megközelítés.

Amit írsz, a "method input validálás", az type hint néven fut, és van a PHP-ben.

Cöcöcö. A tokenizer ismeri a T_DOC_COMMENT tokent, tehát egyrészt felismeri a parsere, másrészt saját parsert se kell írni, mert ott a token_get_all(), amivel vissza lehet kapni egy PHP fájl felparseolt tokenjeit. Plusz a Reflection része is ismeri a PHPDoc-ot. A debug_backtrace-val még azt is ki lehet szedni, hogy honnan volt a hívás helye és össze lehetne hozni egy ilyet:

class FoobarValidator
{
  public function validate($input) {...}
}

/**
 * @validator $param Foobar
 */
public function something($param)
{
  Validator::validate(func_get_args());
}

Más kérdés, hogy nem tenném, hanem írnék valami ilyet:

private static $s_validparams = [....];

public function something($param)
{
  if (!is_array($param)) throw new ArgumentException('param is not an array!');
  if (!in_array($param, self::$s_validparams)) throw new ArgumentException('....');

  ...
}

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Kösz, ma is tanultam valamit.

Köszönöm....hasznos, volt.

Megnéztem a tokenizert és azt írja magáról, hogy PHP verzió váltásnál nem garantálja a T_* constans neveket.
ReflectionClass::getDocComment string-ben adja vissza tokkal vonóval, parse-olni kell.

Így már értem, hogy csak egy cirkuszi mutatvány lenne ami feleslegesen növeli válasz időt.
Nem éri meg pusztán csak a forráskód olvashatósága miatt.

"és azt írja magáról, hogy PHP verzió váltásnál nem garantálja"

Igazából egy-egy major PHP verzió váltásakor semmi nem garanátlt. Mikor utoljára PHP-ban néztem évekkel ezelőtt az ez irányú részt, akkor még szó volt valamilyen parser cserénél, amikor változtak volna a token nevek, nem tudom, hogy hogy áll azóta ez a projekt.

"Nem éri meg pusztán csak a forráskód olvashatósága miatt."

Szerintem néhány normális, jól megválasztott nevű validáló függvény egy metódus elején és egy exception dobás teljesen érthető.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Ugy értem annotation-ként megadni.

Validáló fügvény...naná hogy.

Valahol itt akadtam el én is, hogy az annotation mégis csak a comment részben van.
Tehát azt még valahogy valamikor parse-olni kell, de a PHP engine-nek miért kéne comment-el foglalkoznia.
PHP-DOC-ot megértem, persze értelmezni kell a comment-et, de használja Doctrine\ORM is class metadata definiciónak
(hmmm... lehet csak entitiy generálásnál van szerepe, amikor meg jogos a parse-olás).

"type hint" -et akkor lehet használni ha pozició alapján adod át a paramétereket.
Named paraméterek esetén lehet hívogatni az is_*() fügvényeket. Vagy saját validation class.

Named paraméter átadás legnagyobb nehézsége az elgépelt "key". Erre lett volna egy szép megoldás, hogy ezeket és csak ezeket fogadom el.

"Tehát azt még valahogy valamikor parse-olni kell, de a PHP engine-nek miért kéne comment-el foglalkoznia."

Ld. előző kommentem. Megkülönbözteti a DOC commentet (van, ami abból generál API Doc-ot) és a sima kommentet.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Mivel a parse költséges mutatvány, az autoloader-be be lehet építeni, hogy az adott class betöltésekor parsolja és memcached-be vagy valami hasonló gyorsan elérhető helyre eltegye az infót. Ha a fájl módosításának a dátumát is figyeled, akkor a cache frissen tartását is könnyű megoldani,...

Amire még lehet használni az ilyen megoldásokat, hogy API esetén hívható-e a függvény (pl. javascript-ből), vagy automatikusan generálható a hívó oldalra is a validálások egy része. A yii framework használ ilyen megoldásokat, csak ott nem a commentben vannak ezek az infók.

Az, hogy mi a költséges, meg mi a nem, önmagában kijelenteni meglehetősen nagy botorság.

Anno előző munkahelyen pl. mi többnyire szartunk arra, hogy a PHP-ben mi van, hacsak nem volt valami látványosan lassú, inkább törekedtünk egy idő után arra, hogy a kód érthetőbb legyen. Ki lett mérve, az idő 90%-ában a PostgreSQL dolgozott. Innentől kezdve az, hogy a PHP mennyire volt gyors vagy lassú, irreleváns volt az esetek 95%-ában.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™


class Foo
{
/**
* @var integer
*/
public $bar;
}

jézusmária

--
debian,libreelec,openmediavault,ubuntu,windows,arch,lineageOS
zbook/elitebook/rpi3/nexus5_hammerhead

Egy XMLDoc/JavaDoc se néz ki sokkal jobban, ha rendesen kitöltöd.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Arra gondoltam hogy van egy $bar -od, aminek nincs típusa, de azért oda van kommentálva hogy int, ami vagy igaz vagy sem :)

--
debian,libreelec,openmediavault,ubuntu,windows,arch,lineageOS
zbook/elitebook/rpi3/nexus5_hammerhead

Ja hát PHP.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Azert function szinten megadhatod a tipust:

class $foo{

/**
* @var int
*/
public $bar;

public function valamiFunction(int $bar):void
{

}

}

---------------------------------------------
Support Slackware: https://paypal.me/volkerdi

Most már. Csak igazából itt a dilemmája a PHP-nek: ha nem csak valami <100 soros gyors, eldobható scriptre kell, akkor miért választanék PHP-t, ha választhatok valami nomrális nyelvet is helyette?

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Mert évek óta ezen a nyelven történik a projekt fejlesztése és senki sem akarja újraírni?

Új projekt kezdetekor. Meg egyébként is, nem csak nagy monolitikus szoftvert lehet írni.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

már RFC-ben van a typed properties is. egyesek 7.4-es php-t rebesgetnek.
https://wiki.php.net/rfc/typed-properties

PHP ilyen....
Egyébként van típusa csak nem te mondod meg, hanem az engine kitalája, meg castolja ha épp úgy kell neki.

Szedd le a 3.x -es symfony-t és nézzed ki belőle ott hogyan csinálják :) Ott a routingot is tudják annotációból kiszedni, illetve a doctrine 2 orm is abból szereti a modelleken belüli adatokat kikaparni.

elég a doctrine megfelelő csomagját, mert a symfony is az ő annotation parserüket használja.

https://www.doctrine-project.org/projects/doctrine-annotations/en/1.6/index.html

composer require doctrine/annotations

no tessék, +1