Web service jest opartym o sieć systemem informatycznym zaprojektowanym do wspierania wzajemnej interakcji maszyna-maszyna. W kontekście aplikacji webowej termin odnosi się do zbioru funkcji API, które są dostępne poprzez Internet i wykonywane są w zdalnym systemie utrzymującym udostępnianą usługę. Przykładowo: klient oparty o Flex może wywoływać funkcje zaimplementowane na serwerze utrzymującym aplikację opartą o PHP. Web service opiera się o SOAP, jako podstawową warstwę stosu protokołu komunikacyjnego.
Yii dostarcza klas CWebService i CWebServiceAction dla uproszczenia pracy związanej z implementacją Web service'u w aplikacji webowej. Poszczególne API pogrupowane są w klasy, zwane dostawcami usług. Dla każej z tych klas Yii generuje specyfikację WSDL określającą, jakie funkcje API są dostępne i jak powinny być wywoływane przez klienta. W momencie gdy funkcja API jest wywoływana przez klienta, Yii tworzy instancję odpowiedniego dostawcy usługi i wywołuje potrzebne API, aby zrealizować żądanie.
Uwaga: CWebService opiera się o [rozszerzenie PHP SOAP] (https://www.php.net/manual/en/ref.soap.php). Upewnij się, że je włączyłeś zanim wypróbujesz przykłady zawarte w tej części.
Jak wcześniej mówiliśmy, dostawca usługi jest klasą udostępniającą metody, które mogą być wywoływane zdalnie. Yii opiera się na komentarzach dla potrzeb dokumentacji - tzw. doc comment i na introspekcjach klas w celu identyfikacji, która z metod może być zdalnie wywoływana oraz jakie są jej parametry i zwracana wartość.
Rozpocznijmy od prostej usługi informującej o notowaniach giełdowych. Pozwala ona
klientowi uzyskać informację o notowaniu określonych akcji. Definiujemy dostawcę
usług jak pokazano niżej. Zwróć uwagę, że klasę dostawcy StockController
definiujemy jako rozszerzenie klasy CController. Nie jest to jednak wymagane.
Wkrótce krótko wyjaśnimy dlaczego.
class StockController extends CController
{
/**
* @param string the symbol of the stock
* @return float the stock price
* @soap
*/
public function getPrice($symbol)
{
$prices=array('IBM'=>100, 'GOOGLE'=>350);
return isset($prices[$symbol])?$prices[$symbol]:0;
//...return stock price for $symbol
}
}
Powyżej deklarujemy metodę getPrice
, która stanie się funkcją API Web
service'u za sprawą umieszczenia znacznika @soap
w jej sekcji doc comment.
Opieramy się na doc comment aby określić typ argumentów i zwracaną wartość.
Kolejne funkcje API mogą być deklarowane w analogiczny sposób.
Po zdefiniowaniu dostawcy usług musimy sprawić, by te usługi były dostępne
dla klientów. W tym celu utworzymy akcję kontrolera, aby udostępnić usługę.
Możemy to łatwo zrobić deklarując w klasie kontrolera akcję CWebServiceAction.
W naszym przykładzie wstawiamy ją do klasy StockController
.
class StockController extends CController
{
public function actions()
{
return array(
'quote'=>array(
'class'=>'CWebServiceAction',
),
);
}
/**
* @param string the symbol of the stock
* @return float the stock price
* @soap
*/
public function getPrice($symbol)
{
//...return stock price for $symbol
}
}
To wszystko co musimy zrobić by stworzyć Web service! Jeżeli spróbujemy teraz
wywołać akcję poprzez URL http://hostname/path/to/index.php?r=stock/quote
,
otrzymamy w odpowiedzi mnóstwo danych w formacie XML, które w rzeczywistości
stanowią kod WSDL dla web service'u, który właśnie stworzyliśmy.
Wskazówka: CWebServiceAction domyślnie zakłada, że bieżący kontroler jest dostawcą usługi. To dlatego definiujemy metodę
getPrice
wewnątrz klasyStockController
.
Aby dokończyć przykład stwórzmy klienta, który użyje usługi naszego web
service'u. Przykładowy klient napisany jest w PHP, ale mógłby być także
napisany także w innych językach, np. Java
, C#
, Flex
, itp.
$client=new SoapClient('http://hostname/path/to/index.php?r=stock/quote');
echo $client->getPrice('GOOGLE');
Uruchom powyższy skrypt w trybie webowym lub w konsoli, a powinieneś ujrzeć
wartość 350
, co jest ceną GOOGLE
.
Gdy deklarujemy metody i atrybuty klas, które mają być zdalnie dostępne, musimy określić typy danych dla parametrów wejściowych i wyjściowych. Mogą tu zostać użyte następujące proste typy danych:
xsd:string
;xsd:int
;xsd:float
;xsd:boolean
;xsd:date
;xsd:time
;xsd:dateTime
;xsd:string
;xsd:struct
;xsd:anyType
.Jeżeli jakiś typ nie występuje wśród powyższych typów prostych, traktowany
jest jako typ złożony, składający się z parametrów. Typ złożony reprezentowany
jest przez klasę, jego parametry są publicznymi atrybutami tej klasy
zawierającymi znacznik @soap
w ich sekcjach doc comments.
Możemy również użyć typu tablicowego poprzez dodanie []
na końcu typu
prostego lub złożonego. Tym sposobem definiujemy tablicę określonego typu.
W przykładzie poniżej zdefiniowano funkcję Web API getPosts
, która zwraca
tablicę obiektów Post
.
class PostController extends CController
{
/**
* @return Post[] a list of posts
* @soap
*/
public function getPosts()
{
return Post::model()->findAll();
}
}
class Post extends CActiveRecord
{
/**
* @var integer post ID
* @soap
*/
public $id;
/**
* @var string post title
* @soap
*/
public $title;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
W celu otrzymania od klienta (usługi) parametrów typu złożonego, aplikacja musi deklarować mapowanie z typów WSDL na odpowiednie klasy PHP. Jest to realizowane przez konfigurację atrybutu classMap klasy CWebServiceAction.
class PostController extends CController
{
public function actions()
{
return array(
'service'=>array(
'class'=>'CWebServiceAction',
'classMap'=>array(
'Post'=>'Post', // or simply 'Post'
),
),
);
}
......
}
Przez zaimplementowanie interfejsu IWebServiceProvider dostawca usług może przechwytywać zdalne wywołania metod. W (kodzie obsługi zdarzenia) IWebServiceProvider::beforeWebMethod dostawca może uzyskać dostęp do bieżącej instancji CWebService i odczytać nazwę metody aktualnie wywoływanej poprzez CWebService::methodName. Może wtedy zwrócić wartość false, jeżeli z pewnych powodów zdalna metoda nie powinna być wywoływana (np. nieautoryzowany dostęp).
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.