27 มี.ค. 2556

สร้าง PHP Extension

ให้อ่าน http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/ คู่ไปด้วย
แต่ในบทความนี้จะไม่ใช้ phpize + m4 เพื่อ build extension

*เฉพาะกรณีที่ใช้  Visual Studio + Visual GDB

ลง php-devel เพื่อ ใช้ libphp5.so
yum install php-devel
เพื่อให้มัน ใช้ใน *nix ได้ จะต้อง define ตอนเราใช้ std function มันจะได้ไม่เผลอไปใช้ ของ Visual Studio

#ifdef _MSC_VER

#define _X86_ 1

#define _HAVE_STDC 1

#define __GNUC__ 1  //<-----*

- php_tcg.h
#pragma once 

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"

#ifdef DEBUG

#endif

-flags.mak x86
INCLUDE_DIRS := /usr/include/php /usr/include/php/Zend /usr/include/php/main /usr/include/php/TSRM
LIBRARY_DIRS := /usr/lib/httpd/modules/ 
LIBRARY_NAMES := libphp5.so
-flags.mak x64
INCLUDE_DIRS := /usr/include/php /usr/include/php/Zend /usr/include/php/main /usr/include/php/TSRM
LIBRARY_DIRS := /usr/lib64/httpd/modules/ 
LIBRARY_NAMES := libphp5.so
-flags.mak ถ้าใช้ GCC compile *
CFLAGS := -ggdb -ffunction-sections -fPIC 

-php_tcg.cpp
//--predefine function
PHP_MINIT_FUNCTION(php_tcg);
PHP_MSHUTDOWN_FUNCTION(php_tcg);
PHP_RINIT_FUNCTION(php_tcg);
PHP_RSHUTDOWN_FUNCTION(php_tcg);
PHP_FUNCTION(tcg_init);
PHP_FUNCTION(tcg_test);

// list of custom PHP functions provided by this extension
// set {NULL, NULL, NULL} as the last record to mark the end of list
static zend_function_entry tcg_functions[] = 
{
 PHP_FE(tcg_dll_gen, NULL)
 PHP_FE(tcg_init, NULL)
 {NULL, NULL, NULL}
};


zend_module_entry php_tcg_module_entry = 
{
#if ZEND_MODULE_API_NO >= 20010901
 STANDARD_MODULE_HEADER,
#endif
 PHP_MY_EXTENSION_EXTNAME,
 tcg_functions,
 PHP_MINIT(php_tcg), 
 PHP_MSHUTDOWN(php_tcg),
 PHP_RINIT(php_tcg), 
 PHP_RSHUTDOWN(php_tcg),
 NULL, // name of the MINFO function or NULL if not applicable
#if ZEND_MODULE_API_NO >= 20010901
 PHP_MY_EXTENSION_VERSION,
#endif
 STANDARD_MODULE_PROPERTIES
};

PHP_INI_BEGIN()
        //ลอง config ใน php.ini
        //[php_tcg]
        //config_string_1 = "/var/www";
        //config_numeric = 1;
        PHP_INI_ENTRY("php_tcg.config_string_1", "/var/www", PHP_INI_ALL, NULL)
 PHP_INI_ENTRY("php_tcg.config_numeric", "1" , PHP_INI_ALL, NULL)
PHP_INI_END()

PHP_MINIT_FUNCTION(php_tcg)
{
 REGISTER_INI_ENTRIES();
 return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(php_tcg)
{
 UNREGISTER_INI_ENTRIES();
 return SUCCESS;
}

PHP_RINIT_FUNCTION(php_tcg)
{
 return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(php_tcg)
{
 return SUCCESS;
}

ZEND_GET_MODULE(php_tcg)

PHP_FUNCTION(tcg_init)
{
        //function test init - check path ว่ามีอยู่จริง
 struct stat buf;
 int i = stat ( INI_STR("php_tcg.config_string_1") , &buf );
 if ( i != 0 )
 {
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP_TCG : Invalid path.");
  RETURN_FALSE;
 }
 RETURN_TRUE;
}

PHP_FUNCTION(tcg_test)
{ 
        //function test - รับ parameter เป็น string
        //อย่าลืม #include sys/stat ด้วย
        //ดู เพิ่มที่ http://devzone.zend.com/317/extension-writing-part-ii-parameters-arrays-and-zvals/
 char *username;
 int username_len;
 //get username
 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &username, &username_len) == FAILURE) 
 {
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP_TCG : Invalid username param.");
  RETURN_FALSE;
 }
        //ลอง config แบบ bool
       bool _config_bool = INI_BOOL("php_tcg.config_numeric");
       if( _config_bool )
       {
                        //return เป็น array แบบ assoc
                        array_init(return_value);
                        add_assoc_string(return_value, "username", username ,1 );
                        add_assoc_long(return_value, "abc", 200);
                        add_assoc_string(return_value , "str" , "ลองๆ" , 1);
                        RETURN_ZVAL(return_value,1,0);
       } 
       else
       {
                        //return เป็น string
                        RETURN_STRING("Hello World", 1);
       }
}

-test.php
if (tcg_init())
                {
                    $ret_arr = tcg_test('abc');
                    if ($ret_arr != FALSE)
                    {
                        var_dump($ret_arr);
                    }
}

ไม่มีความคิดเห็น:

แสดงความคิดเห็น