Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu zend_framework Kanał ATOM (tag: zend_framework)

Autor wpisu: Marek, dodany: 24.10.2012 22:38, tagi: php, zend_framework

zf

Zend Framework ma to do siebie, że gdy obejrzymy zawartość plików jego biblioteki, zauważymy, że nagminnie korzysta z require_once. Pomimo, że wyrażenie to zabezpiecza  przed ponownym załadowaniem tego samego pliku do pamięci, to rozwiązanie ma swoje wady wydajnościowe. Za każdym razem, gdy parser PHP napotyka na swojej drodze require_once, czesze po dysku celem sprawdzenia czy dany plik istnieje. Nieważne, że ten plik został chwilę wcześniej załadowany do pamięci.

W przypadku, gdy w aplikacji opartej o zf używamy autoloadera, choćby poprzez wywołanie:

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

możemy zakomentować wszystkie wystąpienia w bibliotece Zenda wyrażenia require_once. Służy do tego np. zgrabna komenda:

cd /path/to/ZendFramework/library
find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
      -not -wholename '*/Application.php' -print0 | \
      xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'

Żeby nie być gołosłownym zrobiłem prosty test programem Apache Benchmark wywołując 10 tysięcy razy aplikację lokalnie utworzoną poprzez

zf create project zf-stat .

Po podlinkowaniu biblioteki frameworka wywołałem dwukrotnie polecenie:

ab -n 10000 localhost/stat-zf/public

Najpierw na „gołej” instancji Zend Framework 1.12.0, za drugim razem po zakomentowaniu require_once w bibliotece.

Zend Framework 1.12.0 z require_once:

Time taken for tests:   2.725 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10000
Total transferred:      5700000 bytes
HTML transferred:       3150000 bytes
Requests per second:    3669.87 [#/sec] (mean)
Time per request:       0.272 [ms] (mean)
Time per request:       0.272 [ms] (mean, across all concurrent requests)
Transfer rate:          2042.80 [Kbytes/sec] received

Zend Framework 1.12.0 bez require_once:

Time taken for tests:   2.003 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10000
Total transferred:      5700000 bytes
HTML transferred:       3150000 bytes
Requests per second:    4992.42 [#/sec] (mean)
Time per request:       0.200 [ms] (mean)
Time per request:       0.200 [ms] (mean, across all concurrent requests)
Transfer rate:          2778.98 [Kbytes/sec] received

Jak widać już przy tak trywialnym teście czas jego trwania wzrósł prawie o połowę, żądania wzrosły z liczby 3669.87 do 4992.42,  średni czas żądania spadł z 0.272 ms do 0.200 ms, a transfer wzrósł z 2042.80 [Kbytes/sec] do 2778.98 [Kbytes/sec].

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: zleek, dodany: 11.09.2012 10:45, tagi: php, zend_framework

W minionym tygodniu została wydana stabilna wersja Zend Framework 2. Najnowsze wydanie można pobrać klikając ten link. Nowa wersja frameworka różni się dość znacząco od wersji oznaczanych cyfrą 1. Przede wszystkim wiele komponentów zostało napisanych od nowa znacznie ułatwiając ich implementację, a także usprawniając ich prędkość działania i stabliność. Co jednak wydaje się być najciekawszą [...]

Autor wpisu: Marek, dodany: 10.09.2012 09:15, tagi: php, zend_framework

zf2

Po ponad pięciu latach od wydania wersji 1.0.0 Zend Framework doczekał się stabilnej wersji 2.0.0.

Nie będę ględził, tylko odsyłam na odświeżoną stronę: http://framework.zend.com/ i do manuala: http://framework.zend.com/manual/2.0/en/index.html

Autor wpisu: batman, dodany: 07.07.2012 07:00, tagi: zend_framework

Wczoraj wieczorem pojawiła się informacja o wydaniu kolejnej, piątej już, bety Zend Frameworka 2. Według zapowiedzi jest to ostatnia beta, która po wyczyszczeniu śmieci i przygotowaniu dokumentacji, zmieni się w wersję RC. Kiedy to nastąpi? Jak tylko ukończone zostaną wspomniane (…)

Read the rest of this entry »

Autor wpisu: batman, dodany: 06.07.2012 07:00, tagi: zend_framework

Pamiętacie Zend_View? Za wiele z niego nie dało się wycisnąć. Ot zwykła klasa, która przyjmowała jakieś dane w kontrolerze, a następnie zwracała w widoku. Bez szaleństw. Wprawdzie pod maską kryło się wiele ciekawego kodu, ale i tak był to chyba (…)

Read the rest of this entry »

Autor wpisu: Diabl0, dodany: 05.07.2012 01:07, tagi: zend_framework, php

Tym razem poruszę jednocześnie dwie kwestie – tworzenie i obsługę webservices oraz zarządzanie uprawnieniami.

Zanim zaczniemy z autoryzacją i prawami dostępu musimy mieć usługi które udostępniamy. Nie wiem czy wszyscy zdają sobie sprawę że z pomocą ZF w miarę prosto i szybko można za jednym zamachem stworzyć usługi obsługiwane za pomocą trzech najbardziej obecnie popularnych protokołów: XML-RPC, Json-RPC i SOAP.

Stworzymy sobie kontroler do obsługi usług (w moim przypadku main_ServicesController) a w nim 3 metody – każda dla osobnego protokołu.

class main_ServicesController extends Mao_Controller_Action {
	/**
	 *
	 * Server JSON-RPC
	 */
	public function jsonAction()
	{
		$this->disableLayoutAndViews();

		$server = new Zend_Json_Server();

		$this->_setClasses($server);

		if ('GET' == $_SERVER['REQUEST_METHOD']) {
			$server
			->setTarget( 'http://' . $_SERVER['HTTP_HOST'] . '' . $this->view->url(array('module' => 'main', 'controller' => 'services', 'action' => 'json' )) )
			->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
			$smd = $server->getServiceMap();

			header('Content-Type: application/json');
			echo $smd;
			return;
		}

		echo $server->handle();
	}

	/**
	 *
	 * Server XML-RPC
	 */
	public function xmlAction()
	{
		$this->disableLayoutAndViews();

		Zend_XmlRpc_Value::setGenerator(new Zend_XmlRpc_Generator_XmlWriter());

	    // Specify a cache file
	    $cacheFile = APPLICATION_PATH . '/temp/xmlrpc.cache';

		$server = new Zend_XmlRpc_Server();

	    // Attempt to retrieve server definition from cache
	    if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
	        $this->_setClasses($server);

	        // Save cache
	        // @todo: uncomment when going live
	        //Zend_XmlRpc_Server_Cache::save($cacheFile, $server);
	    }

		echo $server->handle();

	}

	/**
	 *
	 * Server SOAP
	 */
	public function soapAction() {
		$this->disableLayoutAndViews();

		$serviceURL = $url = 'http://' . $_SERVER['HTTP_HOST'] . '' . $this->view->url(array('module' => 'main', 'controller' => 'services', 'action' => 'soap' ));

		// Generate WSDL relevant to code
		if (isset($_GET['wsdl'])){
		    $autodiscover = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex');
		    $this->_setClasses($autodiscover);
		    $autodiscover->handle();
		} else {
		    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
		    $this->_setClasses($server);
		    $server->handle();
		}
	}

    /**
     * Sets classes for servers
     *
     * @param object $server
     */
	protected function _setClasses( $server ) {

		if ( method_exists( $server, 'setClass' ) ) {
			$server->setClass( 'main_services_Auth', 'auth' );
			$server->setClass( 'shop_services_Products', 'products' );
			$server->setClass( 'shop_services_Orders', 'orders' );
		}
	}

}

Jeden kontroller, 3 akcje, 3 protokoły.

Skoro mamy już zdefiniowane usługi to czas zająć się autoryzacją i uprawnieniami.

Niestety żaden z protokołów nie ma odgórnie ustalonych zasad realizacji tego problemu i w sieci można się spotkać z wieloma sposobami. Ja zamiast każdorazowe przekazywanie pełnych danych logowania zdecydowałem się na tzw. tokeny. Jedna metoda służy do uwierzytelnienia i wystawienia tokena który natomiast jest przekazywany przy wywoływaniu kolejnych metod.

Za logowanie odpowiada klasa:


class main_services_Auth extends main_services_Abstract {

	/**
	 *
	 * Login and generate login token.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @param array $additional	optional additional informations (currently unused)
	 *
	 * @return array dod
	 */
	public function login( $username, $password, $additional = array() ) {

		// 1 - sprawdzamy usera i hasło
		$db = Zend_Registry::get ( 'db' );

		$authAdapter = new Zend_Auth_Adapter_DbTable ( $db );
		$authAdapter->setTableName ( 'users' );
		$authAdapter->setIdentityColumn ( 'username' );
		$authAdapter->setCredentialColumn ( 'password' );
		$authAdapter->setCredentialTreatment('MD5(?) AND active = 1');

		// Set the input credential values to authenticate against
		$authAdapter->setIdentity ( $username );
		$authAdapter->setCredential ( $password );

		$auth = Zend_Auth::getInstance ();
		$result = $auth->authenticate ( $authAdapter );

		if ($result->isValid ()) {
			//2 - sprawdzamy/generujemy token

			$tokensModel = new main_models_Services_LoginTokens();
			$tokenRow = $tokensModel->fetchTokenFor( $username, true );

			return array('status' => true, 'token' => $tokenRow->token);
		}

		return array('status' => false, 'error' => 'Unable to login');
	}
}

Jak widać dość typowe zendowska autoryzacja, jedyna różnica to to że po zalogowaniu nie zapisujemy danych użytkownika do Zend_Auth_Storate a jedynie zwracamy token logowania.

Samo generowanie tokena to:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 03.07.2012 10:00, tagi: zend_framework

Ostatnim razem podczas opisywania ZF2, skupiłem się tylko i wyłącznie na formularzach (siła przyzwyczajeń). Dzisiaj zaprezentuję sposób tworzenia modułów w Zend Framerowk 2. W przeciwieństwie do ZF1, moduły stanowią trzon aplikacji i w końcu można je bez większego problemu przenosić między aplikacjami.

Zanim jednak weźmiemy się za moduły, warto poznać nową strukturę katalogów ZF2, która znacząco odbiega od tego, do czego przyzwyczaił nas ZF1.

application_root/
    config/
        application.config.php
        autoload/
            global.php
            local.php
            // etc.
    data/
    module/
    vendor/
    public/
        .htaccess
        index.php

Najważniejszym katalogiem jest module, w którym znajdują się moduły aplikacji złożone z kontrolerów oraz widoków (o czym za chwilę). Równie ważnym katalogiem jest config, zawierający globalną konfigurację naszej aplikacji. Katalog vendor, jak sama nazwa wskazuje, zawiera wszystkie zewnętrzne biblioteki, z których będziemy korzystać, w tym ZF2.

Struktura pojedynczego modułu prezentuje się następująco.

module_root/
    Module.php
    autoload_classmap.php
    autoload_function.php
    autoload_register.php
    config/
        module.config.php
    public/
        images/
        css/
        js/
    src/
        <module_namespace>/
            <code files>
    view/
        <dir-named-after-module-namespace>/
            <dir-named-after-a-controller>/
                <.phtml files>

Plik Module.php odpowiada za inicjalizację modułu (jego odpowiednikiem w ZF1 jest Bootstrap.php). Pliki autoload_* służą do ładowania plików o niestandardowych nazwach (nie są wymagane). Katalog config zawiera konfigurację modułu, public – zasoby (grafiki, style oraz skrypty JavaScript), src – kontrolery, modele oraz wszystkie inne pliki wykorzystywane przez moduł, a view – widoki. Powyższa struktura katalogów została żywcem zaczerpnięta z dokumentacji do beta4 ZF2, a jej dokładny opis znajduje się pod adresem http://packages.zendframework.com/docs/latest/manual/en/zend.mvc.html#zend.mvc.intro.basic-application-structure.

Skoro wiemy już jak wygląda struktura katalogów w ZF2, pora utworzyć pierwszy moduł. Najlepiej będzie zabrać się do tego poprzez pobranie szkieletowej aplikacji dostępnej pod adresem https://github.com/zendframework/ZendSkeletonApplication/zipball/master. Po jej rozpakowaniu i uruchomieniu, zobaczymy coś takiego.

zf2_start_screen

Dodanie nowego modułu polega na utworzeniu w katalogu module podkatalogu o wybranej przez nas nazwie. Niech nazwą tą będzie Example. Wewnątrz katalogu Example musimy utworzyć katalogi config, src oraz view. Nie można zapomnieć o pliku Module.php. Zawartość klasy możemy bez żadnego problemu skopiować z pliku Module.php znajdującego się w module Application. Musimy tylko pamiętać o zmianie przestrzeni nazw na Example. Podejrzewam, że w finalnej wersji frameworka, plik ten będzie generowany automatycznie przez narzędzie wiersza poleceń.

Kolejnym krokiem będzie utworzenie kontrolera. W tym celu w katalogu src tworzymy katalog o takiej samej nazwie jak moduł (w naszym przypadku będzie to Example), a w nim katalog Controller. W tym katalogu tworzymy plik o nazwie IndexController.php.

namespace Example\Controller;

use Zend\Mvc\Controller\ActionController;
use Zend\View\Model\ViewModel;

class IndexController extends ActionController
{
    public function indexAction()
    {}
}

Kolejnym krokiem tworzenia modułu, jest dodanie widoku. Zrobimy to poprzez utworzenie wewnątrz katalogu view folderu o nazwie naszego modułu (example), a w nim struktury znanej z ZF1, czyli katalogu odpowiadającemu kontrolerowi (index) oraz pliku widoku odpowiadającemu akcji (index.phtml).

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.