Ajax aplikacijos su Zend_Json_Server

Kas yra AJAX ir kam jis naudojamas – šiame straipsnyje plačiau neaptarinėsime. Verta tik paminėti, kad norėdami savo programas optimizuoti – turite turinį krauti asinchroniškai ir vengti pilno puslapio perkrovimo (aišku jei tai įmanoma). Nesenai aptikau vieną įdomų sprendimą Zend Framework naudojančioms sistemoms.
Taigi pirmiausia paskiriame kokį nors kontrolerį mūsų ajax užklausoms, pavyzdžiui /ajax bus apdorojamas kontroleriu AjaxController. Jame apsirašome metodą __call kuris perims kreipimąsi į neegzistuojančius metodus.

<?php
class AjaxController extends Zend_Controller_Action
{
    public function preDispatch() {
	    $this->_helper->viewRenderer->setNoRender(true);
	}
 
    public function __call($name,$arguments) {
    	$action = $this->getRequest()->getActionName();
    	// tikrinam ar prasideda klase Main_ jei ne - metame lauk
    	$parts = explode('_', $action);
    	if (empty($parts[1])) throw new Zend_Exception('undefined class',500);
    	if ((string)$parts[0] !== 'Main') throw new Zend_Exception('restricted access',500);
    	$autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->registerNamespace('Main_');    	
    	$server = new Zend_Json_Server();
    	$server->setClass($action);
    	if ('GET' == $_SERVER['REQUEST_METHOD']) {		   
		    $server->setTarget(Zend_Registry::get('base_url').'ajax/'.$action)
		           ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
		    $smd = $server->getServiceMap();		    
		    header('Content-Type: application/json');
		    echo $smd;
		    return;
		}
    	$server->handle();
    }
}

Tuomet kataloge libraries susikuriame naują katalogą Main ir ten susikuriame naują failą Api.php su tokiu turiniu:

class Main_Api {
 
	public function getSmd($class) {
                 // Zend_Registry::get('base_url') gražina pilną svetainės adresą
		$client = new Zend_Http_Client(Zend_Registry::get('base_url').'ajax/'.$class, array(
    		'maxredirects' => 0,
    		'timeout'      => 30)
		);
		return $client->request(Zend_Http_Client::GET)->getRawBody();
	}
}

Iš PHP pusės viskas baigta, dabar keliaujame prie javascript

<script type="text/javascript" src="/js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="/js/json2.js"></script>
<script type="text/javascript" src="/js/jquery.zend.js"></script>
<script type="text/javascript" src="/js/jquery.zend.jsonrpc.js"></script>
<script type="text/javascript" src="/js/init.js"></script>

Čia galite juos visus parsisiųsti
Faile init.js yra mano aprašytas „AutoLoader“ objektas kuris kai tik jums prireiks pakraus reikalingą PHP klasę iš bibliotekos Main. Taip pat galite dinamiškai pasikrauti ir javascript failus, bet kalba ne apie tai dabar 🙂
Naudojimas šios sistemos yra itin paprastas:

alert(AutoLoader.getClass('Main_Test').sum(1,2));

Su javascript kreipsitės tiesiai į PHP klasę esančią libraries/Main/Test.php

class Main_Test {	
	public function sum($a,$b) {
		return $a+$b;
	}
}

Ar gali būti paprasčiau ir patogiau? Man atrodo ne 🙂 Dar vienas extra dalykas: jei kviesime objekto AutoLoader metodą getClass nurodę antrą parametrą true, tuomet užklausos bus siunčiamos asinchroniškai ir alert funkcija negaus jokio turinio. Tai yra todėl, kad pirmu atveju javascript laukia atsakymo iš serverio, o antru atveju – ne. Antras atvejis gali būti naudingas, kad išsaugome kokią informaciją serveryje ir mums nėra būtinybės gauti patvirtinimą apie sėkmingą transakciją ir panašiai.

Tikiuosi šis sprendimas privers bent nusišypsoti tuos, kurie nuolat naudoja AJAX savo sistemose, ir palengvins kasdienį darbą.

Žygimantas

Lead developer at Soundest. Zend Certified Engineer.

More Posts - Website

Žymos: , , ,

2 komentarai

Komentuoti: Ernestas Stankevičius Atšaukti atsakymą

El. pašto adresas nebus skelbiamas.