Szerintem aki kicsit is foglalkozik a PHP-val, már látta, hogyan lehet egy SOAP web service-t létrehozni vele, ott van a beépített SoapServer megoldás, a közkedvelt nuSOAP, de nagyobb keretrendszerek is adnak rá támogatást.
Ami közös mindben, hogy nyűg meghegeszteni ezeket, mindnek megvan a maga problémája, vagy csak egyszerű ocsmány lesz az eredmény.
A napokban a PHP topikban is előjött egy ilyen témájú probléma, ezért megfordult a fejemben, hogy megpróbálom belefűzni a meglévő MVC-s keretembe azt, hogy létre tudjunk hozni egyszerűen web service-t PHP-val.
Ami alapból kikötés volt:
- nincs kézi WSDL irkálás
- nincs annotálás
- metódus paramétere csak complex type lehet (vagy void nyilván)
Amit el kell fogadni, hogy fosch lesz: osztályok kidekorálása service infókkal
Eredmény, egy service osztály:
<?php
/* namespace játék */
class SvcController extends WebService {
public static function __static() {
typeof(__CLASS__)->Attributes()->MethodAttributes()->Add("Method1", new Operation(typeof(new InPut()), "method1 leírása"))->Add("VoidMethod", new Operation());
}
public function Method1(InPut $in) {
/* ... */
return $out;
}
public function VoidMethod() {
/* ... */
}
}
Egy entitás:
<?php
/* namespace játék */
class InPut extends ObjectBase {
public static function __static() {
typeof(__CLASS__)->Attributes()->FieldAttributes()->Add("Field1", DataMember::Int())
->Add("Field2", DataMember::Complex(typeof(new P()), true));
}
public $Field1;
public $Field2;
}
Menet közben jött kikötések az entitásokra vonatkozóan:
- csak public field-ek lehetnek DataMember-ek
- típust meg kell határozni minden esetben (valamilyen primitív vagy complex)
- kollekcióként csak array() használható, szintén jelölni kell, ha ilyenről van szó
Amit meg kell figyelni a példakódokban:
- van egy típusokat leíró infrastruktúra a rendszerben (nyomai: typeof(/* class/interface neve vagy egy instance */), attribútumozás)
- a class loader meghív egy static constructor-t, hogy betöltse az osztály leírását
Ezen túlmenően csak azt kell csinálnunk, hogy a WebService nevű osztályból kell származtatnunk a sajátunkat, ugyanis ebben van a WSDL generálás és a kérések kiszolgálása előre megírva, nekünk csak a saját metódusainkat kell belerakni.
Megfigyelhető, hogy a service class nevében még a Controller szó is szerepel, igen, ez alapvetően az a rendszerben, ezt később valószínűleg le lesz cserélve a sokkal megfelelőbb Service-re, de ahhoz még egy ServiceHandler is kell...
Mögötte teljes routing működik, pl. ennek a service-nek a WSDL-jét egy ilyen URL-en keresztül érhetjük el: http://server/app/svc/wsdl
Természetesen egyéb funkciók is elérhetőek vagy lesznek hozzá, mint pl. a beépített dependency injection.
A cucc belsejében beépített PHP megoldások működnek, nem igényel semmi extrát (gyári SoapServer, miegymás), a WSDL gyártásáért reflection felel, persze nem annyi, mint amennyi egy annotációkat tartalmazóhoz kellene.