MultiServis.Net //PHP El Kitabı

<<= Önceki Sayfa | PHP Ana Sayfa | Sonraki Sayfa =>>

PHP kaynak koduna C ile yazilmis yeni bir fonksiyon eklemek - BOLUM 1 Yazar: Serkan Tarih: 01/03/02

Problem : Kendi hazirladiginiz C fonksiyonlarini, PHP betikleri icinden kullanmak istiyorsunuz.

Cozum : Ornek bir "C Programi" hazirlayip, PHP icerisine yerlestirelim.Ardindan PHP'yi bu yeni ekledigimiz fonksiyon ile derleyip sisteme tekrar yukleyelim...

> PHP_FUNCTION(sample_function)
> {
> char *ret = NULL,
> *fmtstr;
> zval **arg1, **arg2, **arg3;
> if (ZEND_NUM_ARGS() != 3 ||
> zend_get_parameters_ex (3, &arg1, &arg2, &arg3) == FAILURE) {
> WRONG_PARAM_COUNT;
> }

> /* arg1 is an int */
> convert_to_long_ex (arg1);
> /* arg2 is a double */
> convert_to_double_ex (arg2);
> /* arg3 is a string */
> convert_to_string_ex (arg3);

> fmtstr = "arg1 is %d, arg2 is %f and arg3 is %s, arg3 has a length of %d";

> /* Not the best allocation for integer values
> * but sufficient for the needs of this simple program.
> */

> ret = emalloc(strlen(fmtstr) + 10 + 20 + Z_STRLEN_PP(arg3));
> sprintf(ret, fmtstr, Z_LVAL_PP(arg1), Z_DVAL_PP(arg2),Z_STRVAL_PP(arg3), Z_STRLEN_PP(arg3));
> RETURN_STRING(ret, 0);
> }

Tartisma :

Bu ornek fonksyion PHP betikleri icerisinden asagidaki sekilde cagrilabilir :

> echo sample_function (23, 23.34003, "Hello World");

Bunun sonucunda asagidaki gibi bir ifade donecektir :

> arg1 is 23, arg2 is 23.34003 and arg3 is Hello World, arg3 has a length of 11

Program nasil calisiyor?

Satir 1 - PHP foksiyonu olarak deklare ediyoruz.
Satir 4 - arg1,arg2 ve arg3'u zval degiskenleri olarak deklare ediyoruz.zval asagidaki yapiya sahiptir :

> typedef _zval_struct zval;

> /* Notice that is a union, meaning only one of the entries exists at a single time */
> typedef union _zval_value {
> long lval; /*the long value */
> double dval; /*The double value */
> struct {
> char *val; /* The value of the string */
> int len; /* The length of the string */
> } str;
> char chval;
> HashTable *ht; /* If it is an array */
> struct {
> zend_class_entry *ce;
> HashTable *properties;
> } obj; /* Object properties */
> } zvalue_value;

> /* The actual zval struct itself, aliased by the typedef above */

> struct _zval_struct {

> zvalue_value value; /* Value of argument */
> zend_uchar type; /* Type of the argument */
> zend_uchar is_ref; /* Whether or not the argument is a reference */
> zend_ushort refcount; /* The reference count on the argument */
> };

Satir 5 - Fonksiyonumuza 3 tane argumentin gecirildigine emin oluyoruz.ZEND_NUM_ARGS () fonksiyona gecirilen argument sayisini dondurur.

Satir 6 - zend_get_parameters_ex () fonksiyonu ile yazdigimiz fonksiyona gecirilen degiskenlerin icindeki degerler "zval" degerleri olarak deklare ediliyor.

Satir 7 - Bu islem basarisiz olursa, hatayi rapor et.
Satir 11 - arg1'i long'a cevir.
Satir 13 - arg2'yi double'a cevir.
Satir 15 - arg3'u string'e cevir.
Satir 18 - String formatini olustur.
Satir 19 - Hafizaya yerlestir.
Satir 20 - Donecek degeri olustur.
Satir 21 - Donecek degeri dondur.

Ek Aciklama :

> Bilmeyenler icin kisa bir tekrar yapalim.Integer,Double ve String ne demektir?

> 1.Integer (Ondalik kisimi olmayan sayi veri tipi)
> 2.Double (Tam ve ondalik olmak uzere iki kisimdan olusan sayi veri tipi)
> 3.String ( Genel olarak bilinen karekter (yazi) veri formati.PHP icerisindeki betiklerde mutlaka " veya ' icerisine yazilmalidir.)

Eger PHP'nin kaynak kodunu incelerseniz gozunuze asagidaki gibi satirlar carpacaktir :

> pval **argument;

aslinda :

> zval **argument;

olmasi gereklidir.PHP 3 icerisinde butun argumentler zval'ler yerine pval'ler seklindeydi.PHP 3 kaynak kodunu PHP 4 kaynak koduna aktarabilmek icin , zval ve pval'leri ayni sey yapmak gerekli idi.Bu olay basitce "typedef" ile saglanmistir.

Ek Bilgi :

Bir degiskenin icine, fonksiyona gecirilen argument sayisini gidip getirmesini soylemek icin :

> PHP_FUNCTION(birfonksiyon)
> {
> zval **arg1, **arg2;
> int argcount = ZEND_NUM_ARGS();

> if (argcount > 2 || argcount < 0 || zend_get_parameters_ex(argcount,&arg1, &arg2) == FAILURE) {
> WRONG_PARAM_COUNT;
> }

> if (argcount > 0) {
> convert_to_long_ex(arg1);
> /* php_printf prints out to STDOUT */
> php_printf("%dn", Z_LVAL_PP(arg1));
> }

> if (argcount > 1) {
> convert_to_string_ex(arg2);
> php_printf("%sn", Z_STRVAL_PP(arg2));
> }

> php_printf("Above are %d printed out arguments", argcount);
> }

zend_get_parameters_ex () fonksyionu, yanlizca ilk argument ile verilen sayi kadar argumentle eslesir.Bu sebeple yanlizca sizin istediginiz sayidaki degisken fonksiyona argument olarak gecer.

PHP'ye bu yeni fonksiyonu eklemek :

1.Fonksiyonun kaynak kodunu dogru dosyanin icine yerlestirin; sample_function () fonksiyonu icin basic_functions.c PHP dosyasinin icine yerlestirme yapabiliriz.

2.Bu dosyanin icinde yukarilarda bir yerde asagidaki gibi satirlarin gectigi yeri bulunuz. (Eger bu fonksiyonu ext/standard icine yerlestiriyorsaniz, basic_functions.c dosyasinin icinde en yukarilarda bir yere bakmalisiniz.)

> function_entry MODULENAME_functions[] = {
> PHP_FE(somefunction, NULL)
> ...
> }

Kendi yazdiginiz fonksiyon icin asagidaki gibi bir satir ekleyebilirsiniz :

> PHP_FE(sample_function, NULL)

Simdi asagidaki gibi bir goruntu olmali :

> function_entry MODULENAME_functions[] = {
> PHP_FE(somefunction, NULL)
> PHP_FE(sample_function, NULL)
> ...
> }

3.Bu dosya icin var olan "header" dosyasina gidin."header" dosyalari genelde php_MODULENAME.h olarak isimlendirilen dosyalardir.

Bu dosyanin icinde bir cok deklarasyon goreceksiniz :

> PHP_FUNCTION(somefunction);

Siz asagidaki gibi bir satiri eklemelisiniz :

> PHP_FUNCTION(sample_function);

4.PHP'yi tekrar derleyin ve sisteme yukleyin.Betikleriniz isinden artik yeni fonksiyonunuzu cagirebilirsiniz.

Kaynak : ISBN 0-672-31924-1

Serkan Hadi Ceylani
serkan@turk-php.com

Kurko (08/10/01)
http://zend.com/zend/api.php burdaki url de daha genis acıklama var. Anladıgım kadarı ile sadece programı compile etmek yeterli, program extension olarak yukleniyor.

<?
dl("test.dll");
?>

Gibi.

<<= Önceki Sayfa | PHP Ana Sayfa | Sonraki Sayfa =>>