pecl kiterjesztés írása

A múltkori téma ürügyén elkezdtem php kiterjesztést írni és két dologra jöttem rá: régen programoztam c-ben és kissé alul dokumentált a téma.

Emlékeztető gyanánt és ha esetleg valakinek gyorsan kell valami használható leírás, egy-két bejegyzést szeretnék szentelni a témának, ahogy haladok. A leírás készítésekor feltételezek minimális előműveltséget (pl nem fogom leírni step by step mi kell a forgatáshoz).

Az alap telepítéshez a fejlesztői eszközökön kívül a php5-dev csomag kell (meglepő :), és a php5 forrása. Utóbbiban található meg az ext_skel parancs ami létrehoz egy üres kiterjesztést. php5-dev hozza magával a phpize programot ami az üres kiterjesztést fordítható állapotba hozza.

apt-get source php5
apt-get install php5-dev

Egy homokozó kiterjesztést fogunk csinálni amibe beleteszünk ezt-azt.

cd php5*/ext
./ext_skel --extname=sandbox

Szedjünk ki pár feleslegeset. Következő fájlokban fogunk turkálni leginkább:

  • config.m4
  • sandbox.c
  • php_sandbox.h

config.m4

Ahogy látjuk a commentek dnl karakterekkel kezdődő sorok.

Érdemes itt bennhagyni amit alapból betett, mert ha külső lib-hez akarunk binding-et készíteni akkor csak ki kell szedni pár megjegyzést és a fordítási paraméterekhez hozzá is adta ami kell.

sandbox.c

Ez egy lényeges fájl, ennek szerkesztésével fogjuk tölteni időnk nagy részét.

A szerkezete a következő (szokott lenni, még nem):

include-ok, publikus függvények argumentum listái, függvénybejegyzések (lista ami a php számára összefoglalja hogy mely függvény milyen néven és arg. listával hívható), előzőek helyett lehetnek metódusok arg. listái vagy bejegyzések, modul összefoglaló, phpinfo táblázatot módosító hívások, php.ini definiálások, modul init és shoutdown hívások, erőforrás init és shoutdown hívások, függvények (metódusok) törzsei.

Nézzük mi nem kell ebből a fájlból:

/* If you declare any globals in php_sandbox.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(sandbox)
*/

...

	PHP_FE(confirm_sandbox_compiled,	NULL)		/* For testing, remove later. */

A sandbox_module_entry -t majd később vesszük kezelésbe, ez marad.

A PHP_INI_BEGIN kikommentezett részt ahogy van.

php_sandbox_init_globals se kell egyenlőre.

PHP_MINIT_FUNCTION, PHP_MSHUTDOWN_FUNCTION, PHP_RINIT_FUNCTION, PHP_RSHUTDOWN_FUNCTION.

PHP_MINFO_FUNCTION marad.

A PHP_FUNCTION(confirm_sandbox_compiled) -t a blokkot és a hozzá tartozó megjegyzéseket töröljük.

Térjünk vissza a sandbox_module_entry -hez és nézzük meg mi is ez:

zend_module_entry sandbox_module_entry = {
	STANDARD_MODULE_HEADER,
	"sandbox",
	sandbox_functions,
	PHP_MINIT(sandbox),
	PHP_MSHUTDOWN(sandbox),
	PHP_RINIT(sandbox),		/* Replace with NULL if there's nothing to do at request start */
	PHP_RSHUTDOWN(sandbox),	/* Replace with NULL if there's nothing to do at request end */
	PHP_MINFO(sandbox),
	"0.1", /* Replace with version number for your extension */
	STANDARD_MODULE_PROPERTIES
};

(mj: ifeket kiszedtem)

Ez a struktúra adja meg, hogy a php milyen hívást hol talál. Akármilyen nevet is adhatunk a többinek, ebben ha felsoroljuk, hogy mit hol talál a zend motor, akkor meg fogja találni.

  • Az elsővel és az utolsóval nem foglalkozunk, ezek jelenleg nem érdekesek.
  • következő a modul neve,
  • publikus függvény lista (zend_function_entry típusú sandbox_functions jelen példában)
  • modul inicializációs fv neve, ha nem használjuk NULL. Előbb töröltük tehát NULL.
  • modul leállításért felelős fv, ha nem használjuk NULL.
  • erőforrás init fv., vagy NULL
  • erőforrás kitisztító fv., vagy NULL
  • phpinfo táblázat bővítéséért felelős fv
  • verziószám, vagy NO_VERSION_YET

php_sandbox.h

Amiket kiszedtünk init, shoutdown és függvény fejlécek, innen is szedjük ki.

Első kódunk, helló világ.

Első függvényünk a következő fogja megcsinálni:

function hw()
{
  return 'Hello World\n';
}

A cben megír kód pedig így néz ki:

// Fv entry:

zend_function_entry sandbox_functions[] = {
  PHP_FE(hw,  NULL)
  {NULL, NULL, NULL}
};

// hw proto:

PHP_FUNCTION(hw)
{
  char *string;

  string = "Hello World!\n";
  RETURN_STRING(string, 1);
}

// php_sandbox.h:

PHP_FUNCTION(hw);

config.m4 -be hogy forduljon ami kell:

...
dnl config.m4 for extension sandbox 

PHP_ARG_WITH(sandbox,for sandbox support,
[  --with-sandbox    Include Sandbox support])

if test "$PHP_SANDBOX" != "no"; then
....
phpize; ./configure; make

Ha a kezdő állapotot szeretnénk kialakítani a könyvtárban akkor phpize –clean parancsot adjuk ki.

A lefordult modul a modules mappában van. Én innen egy symlinket készítettem a php5 ext könyvtárába (/usr/lib/php5/20060613+lfs), és létrehoztam a /etc/php5/cli/conf.d könyvtárba egy sandbox.ini -t a megfelelő tartalommal. Aztán ha valamit átírok akkor csak make kell és már tesztelhető a végeredmény egy másik terminálban.

Nézzük mit csinál amit alkottunk:

connor@tudor:~/Desktop$ php -r "echo hw();"

Ha ügyesek voltunk hiba nélkül kiírja “Hello World!”.

Második függvény és egy paraméter

Csináljunk egy másik fv-t is. Ez a következőt fogja csinálni:

function hello_user($name)
{
  return 'Hello '. $name .'!\n';
}

Tehát itt már lesz paraméter is a fv-hez.

Megfelelő kódok:

  PHP_FE(hello_user,  NULL)

/* {{{ proto string hello_user()
   Say hello to user. */
PHP_FUNCTION(hello_user)
{
  zval **username;
  char *retval;
  int len;

  if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &username) == FAILURE)
  {
    WRONG_PARAM_COUNT;
  }
  convert_to_string_ex(username);

  len = spprintf(&retval, 0, "Hello %s!\n", Z_STRVAL_PP(username));
  RETURN_STRINGL(retval, len, 1);
}
/* }}} */

php_sandbox.h

PHP_FUNCTION(hello_user);

Egy kis magyarázat a hello user blokkhoz:

  • zend_get_parameters_ex olvassa be a paramétert
  • WRONG_PARAM_COUNT makró dobja a hibát
  • convert_to_string_ex alakítja mindenképp string-é (különben egy lebegőpontossal vagy egy logikaival meggyűlne a bajunk)
  • Z_STRVAL_PP makró stringet eredményez c szinten is.

Kód próba:

connor@tudor:~$ php -r "echo hello_user();"

Warning: Wrong parameter count for hello_user() in Command line code on line 1
connor@tudor:~$ php -r "echo hello_user("Connor");"
Hello Connor!
connor@tudor:~$

Végül…

Remélem a jövőben is lesz rá módom hogy írjak a tapasztalatokról, ha más nem akkor a tervezett szóelválasztásos kiterjesztés megírását fogom lekörmölni. Érdemes már elkészült kiterjesztéseket is megnézni és azokból tanulni (én is így teszek).

Eddigi munka forrása.

Megj: Mivel az írás gyak. a saját jegyzeteim a témában így biztos van benne félrevezető infó és féligazság. Ha valamire rájövök, hogy nem pont az ahogy én azt elképzeltem javítom, de szívesen várom a hozzáértők javításait is. Ugyanez igaz a későbbi írásokra is. Ezeknek megfelelőek kéretik olvasni a leírtakat.

abaqoos

http://webisztan.blog.hu/2008/10/15/mar_weben_is_mukodik_a_magyar_paypal

Szép, szép, csak:

A biztonságos kapcsolat sikertelen
A www.abaqoos.hu érvénytelen biztonsági tanúsítványt használ.
A tanúsítvány csak a következőre érvényes: *.abaqoos.com.
(Hibakód: ssl_error_bad_cert_domain)

Ezek után azért vakarja a jó magyar a fejét, főleg online fizetés esetén…

“selejt” kiszolgáló a folkrádiónak

Folkrádió listájára esett be ma:

Tegnap hosszú adásszünetre kényszerültünk, mert meghibásodott a
lejátszó szerverünk. Sikerült ideiglenesen orvosolni a
problémát, de hosszú távú, biztonságos megoldást csak egy új szerver
munkába állítása hozhat. Hála a sok egy százalékos felajánlásnak –
amit ezúttal is köszönünk -, ki tudjuk valahogy gazdálkodni egy új
szerver árát, de ha esetleg van a listán valaki, aki tud segíteni
valami olcsóbb megoldással (pl. tud leselejtezendő, de jó
szervergépről, vagy tud olyanról, aki adományként támogatná a
Folkrádiót egy szerverrel), akkor fejlesztésre (no meg jogdíjakra)
költhetnénk inkább a pénzt. A technikai részleteket Kemecsei Gáborral
kellene megbeszélni az info [kukac] folkradio [pont] hu címen.

Ha valaki tud segíteni, tegye meg légyszíves.

szóelválasztás weben

Az ingatlanguru kapcsán kezdtem el gondolkodni azon, hogy hogyan lehetne automatikusan (kiszolgáló vagy kliens oldalon) szóelválasztást végezni. Erre azért van szükség mert ha sorkizárt szöveget akarunk megjeleníteni a weben akkor sajnos nem ússzuk meg a szóelválasztást. Viszont azt nem lehet kiszámolni hogy hova kell tenni az elválasztó jelet, a böngésző hol törné a szót. Erre megoldás a ­ tilde.
Ha az összes lehetséges elválasztási helyre ­ karaktert teszünk és ezt megjelenítjük a böngészőben sorkizárt módban, a böngésző automatikusan elválasztja a szöveget ha a szótaghatár ér a bekezdés szélére. Régóta létezik a libhnj és a Tipográl oldalról letölthető elválasztásiminta-gyűjtemény, de php alól ezeket nem lehet használni, nincs libhnj kiterjesztés php-hoz (pythonhoz találtam egyedül). A fentiek tükrében nincs más feladat mint írni egy kiterjesztést ami a libhnj bindingje. Írtam c-ben és php-ban egy kezdetleges próba programot ami egy adott szöveget feldolgoz és szavanként elvégzi az elválasztást. Így néz ki a kimenet:
http://workshop.connor.hu/tmp/hyphen_example.html
A php program miatt még nem tökéletes, de nem is az volt a cél, mint inkább a lib használatának megismerése ahhoz, hogy kiterjesztést tudjak írni php-hoz.

odt2png

Az unoconv és az imagemagick csomagok segítségével egészen egyszerűen lehet ezt a problémát megoldani. Ím a script ami elvégzi az átalakítást.


#!/bin/sh

if [ ! -f $1 ]; then exit; fi
unoconv -f pdf $1
convert -density 300x300 $(basename $1 odt)pdf $(basename $1 odt)png
rm $(basename $1 odt)pdf

újfajta spam

Van egy sanda gyanúm, hogy egy újfajta spam van kialakulóban. Most kaptam egy levelet a gmail-es címemre, miszerint épp most regisztráltam egy új weboldalra (külföldi). Valós felhasználónév, véletlenszerű jelszó. Első gondolatom az volt hogy valaki regisztrált a nevemben, de aztán rájöttem, hogy ennek így semmi értelme nem lenne, hiszen, véletlenszerűen generált jelszó esetén nincs értelme ilyesminek. Marad az a megoldás, hogy a spamlistát arra használja az oldal tulaja, hogy valós hozzáféréseket biztosít. Így egyszer legalább meg fogja látogatni az áldozat a weboldalt hiszen a valótlan regisztrációt törölni kell, nehogy visszaéljenek azzal.
Ötletes. De ettől függetlenül szarjon sünt az ilyen.

Ja, és a regisztrációt nem lehet törölni.

ráncfelvarrás

Kis ráncfelvarráson esett át a blog. Blogmotor frissítése, új téma, pár új bővítmény. A blogmotor az előző alatt nagyon régi volt már (2.0.x), és mivel nem sikerült úgy telepíteni, hogy 2.6 és aztán az upgrade script, egyesével kellett feltenni a 2.0.x és a 2.6 közti tizenakárhány verziót. Egy script-tel mindez 5 perc volt csak. 🙂
Jó munkás nagy munka után pihenni tér. Két hét szünet (az egyébként se gyakori posztolásban :)).

windows-on írt cdk ékezetei

A winen megírt cdk ékezetes fájljai hajlamosak nem jól megjelenni ubuntu alatt. Erre megoldás lehet egy opció megadás az fstab-ban. Az /etc/fstab fájlt szerkesszük rendszergazdai jogokkal. A következő sort:
/dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0

egészítsük ki a következőre:
/dev/scd0 /media/cdrom0 udf,iso9660 user,noauto,iocharset=utf8 0 0

emesene login error

Tegnap óta az emesene 1.0 nem engedett be, visszadobott “Server error 911” üzenettel. Pidgin viszont minden további nélkül beengedett. Átmeneti megoldást az jelentette hogy megváltoztattam az a-zA-Z0-9 jelszavamat, a-zA-Z jelszóra. Most beenged.

mail led

Hardy-n a mail ledes megoldást két dologgal kell kiegészíteni:

/etc/rc.local -ba beírni exit elé:

chown userneve:usergroupja /sys/devices/virtual/leds/asus:mail/brightness

A villogtatást a /sys/devices/virtual/leds/asus:mail/brightness -be való 0, 1 beírása végzi.