kézzel gzippelt tartalom

A mod_gzip és a hasonló on-the-fly tartalomtömörítéssel az a gondom, hogy a processzort eszi (ha nem is nagyon de azért jobban mintha nem tenné). Statikus tartalom esetén is jó ha sávszélességet spórolunk. Ez a megoldás pont ezt a tartalomtípust veszi célba. Ha létezik tömörítve az eredeti helyett azt szolgálja ki, így spórolva a processzoridővel és a sávszélességgel. A megoldás bővíthető a végtelenségig bármilyen fájltípusra.

AddType image/jpg jpg jpgz
AddEncoding gzip jpgz

RewriteEngine on
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_URI} ^(.*).jpg$
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME}.jpgz -f
RewriteRule ^(.*)$ $1.jpgz [L]

mj: ModRewrite debuggolás.
RewriteLog “logpath.log”
RewriteLogLevel 9

zendframework 1.7.1 csomag

Egy project miatt meg kellett csinálni rendesen a zendframework-ot. Ezért az ubuntu tárolóba felkerültek a nagyjából végleges zendframework deb csomagok. A függőségek most már be vannak állítva. Csináltam egy próba telepítést és felment minden szükséges csomag ahogy azt kell. Hiba még lehet, ha találok javítom.

más: Hamarosan érkezik 2 abev nyomtatvány is.

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.

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.

Zend Framework 1.5.2 debian csomag

Zubuntu alatt csináltam jó sok debian csomagot a fent nevezett kódkönyvtárból.

Egyenlőre nem lett se jóárasítva se repósítva, így ide tettem fel: http://workshop.connor.hu/ubuntu/deb/zendframework/
Pár dolgot még javítani kell benne (csomagok függőségei), ha azok megvannak felkerül a helyére.

(más: szemfüles franciák olaszok kiszúrták, hogy az aegisub nevű filmfeliratozó programból csináltam debian csomagot :))

új lendületben a php5 imagick

2007-ben, sok év pihenés után új lendületet vett az imageMagick php5 kiterjesztés fejlesztése.
Jelenleg az API-ja teljes egészében megtalálható a php.net-en és a hardy-ban egy -relatíve- friss és stabil verzió fog landolni.
Ha valaki nem szeret dokumentációt bújni azok számára remélhetőleg több íráson keresztül bemutatom, hogy mit és hogyan lehet a kiterjesztéssel.
Kedvcsinálónak egy egyszerű bélyegkép készítést nézzünk meg:

$image = new Imagick('file.png');
$image->thumbnailImage(800, 600);
$image->writeImage('file_thumb.jpg');
$image->destroy();

A thumbnailImage methódusnak átadhatunk úgy is méretet, hogy az egyik értéket null-nak vesszük. Ilyenkor a másik értékhez igazítja a méretet.

Létezik egy harmadik paraméter is, melyet ha megadunk akkor a következőképpen működik az átméretezés:

  • az átadott méreteknél kisebb a forráskép, nem történik átméretezés
  • egyéb esetben a nagyobb értékre méretezi át a képet.

folyt. köv.

lp robot

Örömömre szolgál bejelenteni a -gyors keresztségben- Launchpad robot névre keresztelt eszköz, első publikus alfa verzióját (v0.01a).

A program segítséget nyújt abban, hogy a rosettából a po fájlokat lementsük egy adott forráscsomag esetén.

Futtatásához php 5.2 cli szükséges. Program jelenleg csak azokat a fájlokat tudja letölteni amiket a rosetta azonnal kiad letöltésre. Amikhez levelet küld azokat jelenleg nem lehet letölteni.

További tervek:

  • leveleken keresztül küldött fájlok letöltése
  • po import
  • fordítás statisztika (amit ez a verzió is tud)
  • teljes rosetta indexelés
  • és még sok más…

Forrás: http://workshop.connor.hu/ubuntu/lp_robot.phps
Használata: http://workshop.connor.hu/ubuntu/lp_robot_example.phps

svn karakterkódolási probléma

Az imént futottam bele egy érdekes problémába az svn verziókezelővel kapcsolatban. Php-n keresztül exec függvényhívásokkal hívogatok svn parancsokat. Egyszer arra lettem figyelmes hogy az update nem fut le a logban pedig ezt az üzenetet találtam:

svn: Can't convert string from native encoding to 'UTF-8':
svn: szerverv?\195?\161laszt?\195?\161s.png

A tárolóban volt olyan fájl aminek a nevében ékezet is volt és a fájlrendszer utf-8. Az exec parancsot átírva látszott, hogy mi a gond (bár a hibaüzenet is mutatja):

locale; svn update .

A kimenetben LC_ALL=C volt, vagyis a natív karakter kódolás az alapértelmezett.
Megoldás:

export LANG=hu_HU.utf-8; svn update .

apache 1.3 és 2, php 4 és 5 egy szerveren

Adott a feladat: egy szerveren belül szeretnénk futtatni olyan oldalakat, amik php4-et és php5-t használnak. A feladat már korábban sem jelentett gondot, abban az esetben, ha az egyiket modulként, a másikat cgi-ként telepítettük. Ez esetben, akár egy vhost-on belül más kiterjesztéssel is működhetett a megoldás (.php és .php5). Ha nem igény az, hogy egy vhoston belül használnánk mind a kettő verziót, akkor egy másik megoldást is használhatunk, ami az oldalak proxyzásán alapul. Ezzel a megoldással fájdalommentesen migrálhatnuk -a szolgáltatás szüneteltetése nélkül is akár- apache 1.3 php4-ről apache2 php5-re. Az elv a következő:

Tegyük fel, hogy régi jól beállított rendszerünk apache 1.3 és php4. E mellé szeretnénk beüzemelni az apache2 és php5-ös párost. Az libapache2-mod-php5 és az apache2 csomagok telepítésével, feltesszük az apache2-t és a php5-t. Telepítés után az apache2 nem fog elindulni és az /etc/init.d/apache2 start parancs se fogja indítani. Ez azért van mert az /etc/default/apache2 fájlban egy az indítást gátoló opció van. Miután áttettük az apache2-t a például a 8080-as portra, már elindíthatjuk nyugodt szívvel az opció megváltoztatásával és az /etc/init.d/apache2 start parancs kiadásával.

Ezek után az apache-ban arra a hosztra, amin szeretnénk php5-t látni, beállítjuk az apache-ot, hogy proxy-zza tovább a beérkező kéréseket a 8080-as portra. Az apache2-ben pediglen beállítjuk, hogy szolgálja ki a 8080-as porton az kért oldalt. Ha nem szeretnénk, hogy közvetlenül meghívják a 8080-as porton lévő oldalakat akkor a kívülről érkező kéréseket a tűzfal beállításban blokkolhatjuk (alapból tíltó tűzfal esetén ez nem jelent gondot ha korábban nem engedélyeztük). A megoldás ezzel készen is van, és az apache-ok újratöltésével beizzítottuk a rendszert.

Hátránya annyi csupán, hogy egy hoszton belül nem lehet futtatni a két féle php verziót (talán rewrite-al meg lehetne oldani?!). És persze a proxy-zás miatt lassulás is bekövetkezhet, a kiszolgálás sebességében. Persze mérni még nem mértem a megoldást így nem tudom hogy mennyivel lassabb a kiszolgálás sebessége.

Következő érdekes migrációs kérdés lehet még a mysql 4.0-ról mysql 5.0-re és windowsról linuxra :). Ez utóbbival hamarosan részletesen is fogok foglalkozni, hiszen most éppen egy irodai gép migrációjával foglalkozom.

php izé, meg a pecl

Következő néhány percben a pecl.php.net-en található egyik php modult fogjuk lefordítani. A pecl a php birnáris kiterjesztéseinek gyüjtőhelye. Hasonló mint a pear csak kevesebb modul található meg a gyüjteményben, és van amit már nem is fejlesztenek. Viszont amit fejlesztenek az egész jól használható és mivel bináris, ezért nagyon gyors is! Continue reading