Mirin webspace

Nejbohatší život má ten, kdo žije s minimem nároků

31. 1. 2010 - Komentáře (2) PHP

Co to je PHP extension

Tak tedy zkusím něco začít o tom jak na PHP rozšíření. Tenhle a další zápisky budou spíš takové povídací, jako ukázka nějakého základního kódu může posloužit třeba include_path wrapper, můžete si ho projít projít a stáhnout z repository. Není to sice úplné hello world, ale zas tak daleko to od něj není. Psát PHP rozšíření není tak přímočarý proces jako psát PHP skript. Postup budu popisovat na Linuxu i když bych se opravdu neoznačil za nějakého Linuxového profíka, 90% času za počítačem trávím na Windows. Linux/Unix je ale základnou pro vývoj PHP a jeho použití pro vývoj extenze je zdaleka nejjednodušší a nejpoužívanější. Tak proč si to zbytečně komplikovat.

Příprava prostředí

Jako první krok by bylo vhodné stáhnout si zdrojové kódy aktuální verze PHP a přeložit si je klasickou kombinací

$ ./configure
$ make
$ make install

./configure --help vám sdělí množství voleb pro různé moduly, co zvolíte je na Vás. Samozřejmě můžete používat různé php-dev balíčky vaší distribuce a nainstalovat si tak pohodlně jen hlavičkové a .lib knihovny, ale doporučuji raději si PHP zkompilovat ručně někam do /usr/local apod.

Po make install budete mít nainstalovánu i podporu pro tvorbu a instalaci rozšíření pomocí skriptů phpize a pecl. Navíc zdrojáky PHP budete potřebovat stejně, protože v nich budete hledat jak o život, jak se co vlastně dělá.

Takže máme nainstalováno. Teď něco k tomu, z čeho se extenze skládá. Většinou jde o 3 a více souborů. Typicky je to

  1. extname.c - vlastní zdrojový kód pro naše rozšíření
  2. php_extname.h - hlavičkový soubor pro naše rozšíření
  3. config.m4 - trochu shellu a m4 vám zajistí, že si vaší extension všichni zkompilují pomocí staré známé výše popsané trojkombinace.

Extenze můžete psát jak v C, tak v C++. C drtivě převažuje. Exteze v C++ byste spočítali na prstech jedné ruky, většinou jde o wrappery nad C++ knihovnami. Jak extenze vlastně fungují a co v PHP představují? PHP core se skládá v podstatě ze tří částí:

  • Zend Engine
  • SAPI vrstva
  • Core rozšíření

Zend Engine obsahuje takové ty všemožné kompilátory našich skriptů do bytecode, a virtuální stroj, který ho interpretuje. Dále pak poskytuje základní API pro extenze, takže manipulaci s pamětí, manipulace s proměnnými, funkcemi, třídami, základními typy. Tuhle část budete v rozšíření velmi často používat.

SAPI vrstva zprostředkovává komunikaci s prostředím, ve kterém PHP běží. Může to být Apache Modul, IIS modul na Windows, CGI, nebo commnad line (CLI) SAPI. Poskytuje také stream přístup k I/O, stará se o save_mode, open_basedir.

Core rozšíření tvoří velkou část PHP. Když si stáhnete zdrojové kódy PHP, tak všechno co je v adresáří ext je rozšíření. Takže funkce na práce s poli, řetězci, datumy, matematické funkce, databáze, atd. To vše je v PHP jako rozšíření.

Rozšíření se dá charakterizovat zjednodušeně jako seznam funkcí, kterým Zend Engine předá řízení, když při vykonávání skriptu narazí na volání, které spadá do nějaké extenze. Až tahle zkompilovaná funkce v extenzi doběhne, tak vrátí hodnotu zpět Zend Engine a ten už s ní naloží dále tak, jak mu velí uživatelův skript. Většinou si jí uloží do proměnné a za chvíli zavolá další funkci z nějaké extenze atd.

Proč vlastně psát nějaké nativní extenze a co k tomu lidi vede?

  • Wrapper nad nějakou C/C++ knihovnou. Tady je to asi jasné. Máme nějakou pěknou céčkovou knihovnu a přihlásí se nám pár lidí, že by jí rádi využili i z PHP, tak holt budeme muset napsat rozšíření. Spousta příkladů se válí v PECLu, další tisíce různě po internetu.
  • Potřebujeme mít nějakou část naší aplikace opravdu rychlou. PHP je jak známou dost velký šnek co se týče rychlosti vykonávání kódu skriptů. Hůř už na tom bývalo jen Ruby a to se z příchodem Ruby 1.9 také změnilo. Tohle byl určíte důvode pro vznik spousty rozšíření u Yahoo a Facebooku.
  • Jen tak, když už vám to PHP leze vším možným a trochu céčka by nezaškodilo :-).

Proč se vlastně extenze píšou více v C a nikoli v C++ když C++ toho nabízí mnohem více? Důvod bude asi ten, že takové ty základní věci, se kterými se v C pracuje ne úplně dobře (řetězce, pole) jsou součástí Zend Engine. Dále pak každá extension nemusí pouze rozšiřovat PHP směrem do user space, ale také směrem k extension api, takže její funkcionalitu můžete využít přímo i ve své extension bez volání oklikou přes Zend Engine. Když si tedy vezmete Zend Engine jako základ pro práci s poli a řetězci a extensions v core, tak pak není moc důvodů používat C++.

Jinak samotné extension api je velmi konzervativní a od PHP 4 se příliš nezměnilo, jen se rozšířilo o objekty. Něco většího přijde až s PHP 6, ale to je ještě někde za horami. Jinak samozřejmě i PHP třídy a objekty se v extension píší v C, jen je tam trochu více maker. Obecně je psaní extension zejména ve stylu "všude nějaké makro", ale tak to bude asi ve všech jazycích, které mají API do C.

Příště možná něco k základu modulu a konfiguraci.


Komentáře (2)

  1. sNop - 1. 2. 2010 15:06

    Ahoj,

    super, super, konecne se dozvime co se skyva pod poklickou a uz se tesim na dalsi dil, tento serial by mohl byt i 10-dilny a pekne po malych krůčcích, nebo toto se muze hodit kazdemu, kdo v PHP-ku pravidelne dela a jednou pride doba, kdy bude treba si kvuli rychlosti PHP napsat svou vlastni jednoduchou extenzi a pak si otevru mirin.cz serial a nestratim se ;)

    Dik za namahavou praci ;)

  2. koubel - 1. 2. 2010 21:21

    [1] - třeba už to v budoucnu nebude potřeba, Facebook prý upekl nějaké přepsání core PHP, možná bude PHP kompilátor nebo něco na ten způsob -
    http://www.sdtimes.com/blog/post/2010/01/30/Facebook-rewrites-PHP-runtime.aspx

    Uvidíme jak to dopadne, myslím, že spousta lidí by zrychlení uvítalo minimálně provozovatelé wikipedie určitě.

Komentáře jsou uzavřeny.