Archiwum

Posts Tagged ‘php’

AMFPHP i AS3 – szybki start.

18 kwietnia, 2012 1 komentarz

AMFPHP to otwarta biblioteka napisana w PHP będąca w zasadzie implementacją AMF dla tego języka. AMF (Action Message Format) jest z  kolei binarnym  formatem serializacji danych pomiędzy Flash a innymi językami – w tym przypadku oczywiście z PHP chociaż nie jest to jedyna dostępna platforma. Co nam to wszystko daje? Otóż umożliwia bezpośrednią, bardzo wygodną wymianę danych pomiędzy AS3 a PHP oraz co więcej pewnego rodzaju wyjście AS3 poza stronę klienta z przeskokiem na stronę serwera. Klasy oraz metody napisane w PHP (którego chociaż podstawowe opanowanie jest banalne) mogą być teraz wywoływane bezpośrednio z poziomu AS3, wykonane po stronie serwera a ewentualne wyniki (nawet bardzo złożone) zwrócone wprost do As3.

Przed erą AMFPHP komunikacja Flash-serwer wyglądała mniej więcej w ten sposób: Flash wczytywał jakiś plik php – a właściwie to wczytywał wynik działania danego pliku *.php, ponieważ Flash to client-side a php to server-side, a więc zanim Flash dorwie się do pliku to ten zostanie najpierw wykonany przez serwer. Wyglądało to tak że AS3 ładowało te same dane które mógł zobaczyć w przeglądarce użytkownik wpisując adres danego pliku *.php. Jeśli jakiś programista zapragnął coś do PHP przesłać np. aby zapisać to w bazie danych mógł to zrobić poprzez metody GET/POST lecz dane nie były przekazywane do jakiejś konkretnej funkcji czy obiektu php lecz raczej do pliku który był wywoływany. Co więcej za pomocą GET/POST dane przekazywane są na zasadzie „zmienna”=”wartosc_zmienne” – co jest może i dobre ale przy przekazywaniu niewielkich ilości danych. Wróćmy na chwilę jeszcze do wczytywania danych, jak wspomniałem Flash wczytywał nie sam plik php lecz efekt jego działania – oczywiste jest to że Flash nie mógł wczytywać jakiejś witryny web tylko coś co był w stanie zrozumieć i zinterpretować. W efekcie pliki php najczęściej generowały po prostu kod XML który był wczytywany przez AS3 i dalej obrabiany. Mało wygodne,  prawda? To spróbuj sobie wyobrazić jak wyglądała próba przesłania do php jakiejś tabeli – np. zawartości koszyka.

I tu wkracza AMFPHP – którego idea jest dość podobna do przedstawionej wyżej. Tak na prawdę obiekty (np. tabele) przesyłane przez AMF podlegają również „przerabiane” na coś co jest w stanie zrozumieć PHP i przesłane do niego. Nie jest to tym razem XML lecz dane przekształcane są do strumienia bajtów (co nazywamy serializacją chociaż tu bardziej by pasował marshalling) i jako takie przekazane do PHP który je deserializuje (proces w drugą stronę). Oczywiście cała realizacja tego zamysłu jest cholernie skomplikowana.

To teraz do dzieła bo okiełznanie tej bestii nie jest w cale takie trudne:) Po pierwsze ściagamy paczkę z AMFPHP – 2.0 stąd,

W rozpakowanym katalogu odnajdujemy folder „Amfphp” – i to jest w zasadzie wszystko co nam potrzeba, katalog ten należy skopiować na swój serwer php lub do odpowiedniego folderu serwera postawionego lokalnie.

Tak to powinno wyglądac jeśli wpiszemy adres naszego folderu „Amfphp”:

Teraz pora na kod PHP:

<?php
class TestClass {
  
    public function sqr($no){
        return $no*$no;
    }
}
?>

Jak widać łatwo prosto i przyjemnie, jedna klasa o nazwie TestClass posiadająca jedną publiczną funkcję „sqr”,  która przyjmuje jeden parametr – w naszym przypadku będzie to liczba. Funkcja oblicza kwadrat podanej liczby i zwraca wyliczoną wartość. Plik zapisujemy na serwerze w katalogu Amfphp/Services w folderze można tworzyć dalesze podfoldery zależnie od projektu. Wywołanie ponownie adresu amfphp pokaże na spisie nową klasę z jedną funkcją, klikając jej nazwę można w bardzo prosty sposób przetestować jej działanie (w pole „no” wpisujemy dowolną liczbę):

Strona Flasha – oto kod realizujący połączenie:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.NetConnection;
	import flash.net.Responder;

	/**
	 * ...
	 * @author andrzej nowak
	 */
	public class Main extends Sprite
	{
		private const _address:String = "http://localhost/Amfphp/";

		private var _nc:NetConnection;
		private var _res:Responder;

		public function Main():void
		{
			_nc = new NetConnection();
			_nc.connect(_address);

			_res = new Responder(onResult, onStatus);

			_nc.call("Test.TestClass.sqr", _res, 2);
		}

		private function onResult($ob:Object):void {
			trace("Wynik: " + $ob.toString());
		}

		private function onStatus($ob:Object):void {
			trace("Błąd");
		}
	}
}

a na outpucie:

Done(0)
[Starting debug session with FDB]
Wynik: 4

Do obsługi AMF potrzeba w sumie dwóch obiektów – klasy NetConnection oraz Responder.

_nc = new NetConnection();
_nc.connect(_address); 

Za pomocą metody „connect” obiektu klasy NetConnection łączymy się z serwerem wskazując na folder – np. http://twoja_domena/Amfphp/

_res = new Responder(onResult, onStatus);

Konstruktor klasy Responder otrzymuje nazwy dwóch funkcji, pierwsza zostanie wywołana kiedy serwer zwórci prawidłową odpowiedz druga natomiast gdy nieprawidłową. Funkcję Respondera można więc porównać do sortownika danych i jak każdy sortownik tak i Responder przekazuje paczki dalej – tak więc każda z funkcji wywoływana przez obiekt respondera otrzymuje jeden argument typu Object.
I na koniec wywołanie funkcji po stronie serwera:

_nc.call("TestClass.sqr", _res, 2);

Służy do tego metoda „call” otrzymująca faktycznie 3 argumenty:

  • 1 – w postaci String; nazwa klasy i po kropce nazwa funkcji jaką chcemy wywołać po stronie serwera, jesli klasa znajduje się w jakimś podfolderze wewnątrz /Amfphp/Services/ np. „Test” (/Amfphp/Services/Test/) należy nazwę tego folderu również uwzględnić – np. „Test.TestClass.sqr”
  • 2 – to obiekt respondera który bedzie analizował odpowiedzi tego wywołania
  • 3 – to właściwie tablica w której przekazujemy argumenty dla funkcji w PHP – w naszym przypadku jest to liczba „2”, jeśli funkcja oczekiwałaby większej ilości argumentów przekazujemy je po prostu dalej przedzielając przecinkiem – np: _nc.call(„TestClass.sqr”, _res, 2, 3, 6, „cos tam”)
Kategorie:AMFPHP, AS3, podstawy Tagi: , , ,