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.
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.
Yorum Yapınız
Yorum yapabilmek için giriş yapmalısınız.
Son yorumlar