PHP7擴展開發(一):hello world

起步

最近在看 《PHP擴展開發中文教程》 的pdf版。PHP的解釋器是用C語言寫的,因此PHP擴展天然也是用C 語言了。php

擴展是什麼

用過php的人必定也用過php擴展。php自己帶有86個擴展,擴展是對php語言功能的一個延伸,php的核心由兩部分組成:最底層的 Zend引擎PHP內核 。ze把腳本解析成機器可讀的符號,也會處理內存管理,變量做用域,程序調度。PHP內核則主要涉及主機環境(Apache,IIS,Nginx),處理與主機的通訊。編程

動機

當php自身不知足需求的時候就能夠本身去造輪子了。採用C語言開發還能必定程度上解決性能問題,而php是我最喜歡的一門編程語言,寫擴展的機會天然不放過,更重要的是能夠 裝逼php7

新建擴展

咱們要寫個擴展代替如下的功能:編程語言

<?php
function hello() {
    return 'hello world';
}

個人開發環境是:工具

  • 系統: Ubuntu 16.04性能

  • PHP: 7.0+測試

  • gcc :4.8.4
    PHP已經提供了工具用來建立擴展,並初始化代碼:ext_skelspa

$ cd php-src/ext
$ ./ext_skel --extname=hello

工具會在當前目錄生成 hello 文件夾。code

修改配置文件

cd到hello,工具已經初始化了目錄,打開配置文件 config.m4:blog

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(hello, for hello support,
dnl Make sure that the comment is aligned:
dnl [  --with-hello             Include hello support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(hello, whether to enable hello support,
dnl Make sure that the comment is aligned:
dnl [  --enable-hello           Enable hello support])

dnl 是註釋符,表示當前行是註釋。這段話是說若是此擴展依賴其餘擴展,去掉PHP_ARG_WITH段的註釋符;不然去掉PHP_ARG_ENABLE段的註釋符。顯然咱們不依賴其餘擴展或lib庫,因此去掉PHP_ARG_ENABLE段的註釋符:

PHP_ARG_ENABLE(hello, whether to enable hello support,
Make sure that the comment is aligned:
[  --enable-hello           Enable hello support])

書寫代碼

工具生成的hello.c,寫上咱們的實現:

PHP_FUNCTION(hello)
{
    zend_string *strg;
    strg = strpprintf(0, "hello world.");
    RETURN_STR(strg);
}

添加到編譯列表裏:

const zend_function_entry hello_functions[] = {
    PHP_FE(hello, NULL)  /*添加這行*/
    PHP_FE(confirm_hello_compiled,  NULL)       /* For testing, remove later. */
    PHP_FE_END  /* Must be the last line in hello_functions[] */
};

編譯與安裝

$ phpize
$ ./configure --with-php-config=/usr/local/php7/bin/php-config
$ make & make install

修改php.ini,開啓擴展,若找不到能夠用phpinfo()查看使用哪一個配置文件.

extension=hello.so

寫個腳本:<?php echo hello(); 不出意外就能看到輸出了。

額外:不使用工具寫擴展

一個擴展(爲避免與寫過的hello衝突,採用world做爲名字),至少包含3個文件: config.m4php_world.hworld.c 。一個是phpize用來準備編譯擴展的配置文件,一個是引用包含的頭文件,一個是源碼文件。

config.m4

PHP_ARG_ENABLE(world, whether to enable world support,
Make sure that the comment is aligned:
[  --enable-world           Enable hello support])

if test "$PHP_WORLD" != "no"; then
    AC_DEFINE(HAVE_WORLD,1,[ ])
    PHP_NEW_EXTENSION(world, world.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
fi

php_world.h

#ifndef PHP_WORLD_H
#define PHP_WORLD_H


extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry
#define PHP_WORLD_VERSION "0.1.0"
#define PHP_WORLD_EXTNAME "world"

#endif

world.c

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

#include "php.h"
#include "php_world.h"

PHP_FUNCTION(world)
{
    zend_string *strg;
    strg = strpprintf(0, "hello world. (from world module)");
    RETURN_STR(strg);
}

const zend_function_entry world_functions[] = {
    PHP_FE(world, NULL)
    PHP_FE_END
};
zend_module_entry world_module_entry = {
    STANDARD_MODULE_HEADER,
    PHP_WORLD_EXTNAME,
    world_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    PHP_WORLD_VERSION,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_WORLD
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(world)
#endif

編譯安裝:

$ phpize
$ ./configure --with-php-config=/usr/local/php7/bin/php-config
$ make & make install

測試:
同樣須要在php.ini添加extension=world.so

20161118144823.png

不使用工具的精簡的一個擴展完成。

相關文章
相關標籤/搜索