Başlangıç > Dökümanlar > PHP İçinde C ile Yazılmış Fonksiyon Eklemek

PHP İçinde C ile Yazılmış Fonksiyon Eklemek

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.

Yazar: NAVIGATOR

Reklamlar
Kategoriler:Dökümanlar Etiketler:, , , , , ,
  1. Henüz yorum yapılmamış.
  1. No trackbacks yet.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

%d blogcu bunu beğendi: