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

PHP kaynak koduna C ile yazilmis yeni bir fonksiyon eklemek - BOLUM 1
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 =>>