Thứ Năm, 21 tháng 10, 2010

Tự build extension cho php

Tự build extension cho php


Mình viết tut này trên ubuntu , các distro khác có thể sẽ khác .

1.check out php5 source :

Mình sec check out từ svn vào thư mục /var/lib/php5 nhé .

sudo svn checkout  http://svn.php.net/viewvc/php/php-src/trunk

Nếu ngại sudo nhiều thì có thể dùng sudo su để thành root luôn cho tiện .

2. Cài php5-dev

sudo apt-get install php5-dev

3. Trong thư mục checkout về , trong thư mục ext sẽ có một file ext_skel.sh file này để sinh ra template cho một ext .

Trong ví dụ nay mình đang xây dựng thư viện simhash (http://knol.google.com/k/simple-simhashing#) .

Thư viện này để so sánh văn bản , hiện đã có implement bằng C .

chạy  sudo ./ext_skel --extname=simhash

để tạo thư mục và template cho extension mới .

cd simhash ( để vào thư mục simhash )

4. chạy sudo phpize để sinh ra các file giúp chung ta có thể build extension độc lập , mà không cần build toàn bộ php5 .

5. Viết code:

Có 2 file cần quan tâm là :

php_simhash :

Bạn phải thêm tên các hàm muốn xây dựng trong extension này :

PHP_MINIT_FUNCTION(simhash);
PHP_MSHUTDOWN_FUNCTION(simhash);
PHP_RINIT_FUNCTION(simhash);
PHP_RSHUTDOWN_FUNCTION(simhash);
PHP_MINFO_FUNCTION(simhash);
PHP_FUNCTION(simhash);
PHP_FUNCTION(confirm_simhash_compiled);

Hàm bôi đậm là mình thêm vào nhé .

File Simhash.c

Khai báo các hàm

const zend_function_entry simhash_functions[] = {
PHP_FE(confirm_simhash_compiled,    NULL)        /* For testing, remove later. */
PHP_FE(simhash, NULL)
{NULL, NULL, NULL}    /* Must be the last line in simhash_functions[] */
};

implement hàm  :

tạm thời cứ print ra Hello, world nhé .

PHP_FUNCTION(simhash)
{
php_printf("Hello, world!\n");
}


6. sudo ./configure

7. sudo make

8. ls modules/

kiểm tra xem có file simhash.so chưa .

Nếu có là ok .

Bạn deploy file simhash.so này bằng cách cấu hình lại php.ini rồi kiểm tra lại bằng phpinfo hoặc tự viết script nhé .

Thật ra trong cái ext của mình cũng có sẵn script test rồi (file simhash.php đấy).

Ngoài ra vấn đề parse các param truyền vào từ php và cách để return giá trị lại cho php caller cũng khá phức tạp .

Để parse param các bạn phải dùng hàm

zend_parse_parameters :


if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|b", &a, &b, &return_long) == FAILURE) {
RETURN_NULL();
}


hàm này hoạt động khá giống scanf chỉ khác formate string "ld|b = long - double - và zend_bool .

Cách return về dữ liệu cũng phải thực hiện qua các macro :

Kiều thế này .

RETURN_LONG(a + b);

Không có nhận xét nào:

Đăng nhận xét