PHP擴展開發教程1 - 相關開發技術對比及介紹

PHP擴展是高級PHP程序員必須瞭解的技能之一,對於一個初入門的PHP擴展開發者,怎麼才能開發一個成熟的擴展,進入PHP開發的高級領域呢?本系列開發教程將手把手帶您從入門進入高級階段。
本教程系列在linux下面開發(推薦使用centos),php版本用的是5.6,並假設您有必定的linux操做經驗和c/c++基礎。
有問題須要溝通的朋友請加QQ技術交流羣32550793和我溝通。

開發php擴展有好幾種技術方法和框架,對於初學者來講,最好可以選擇一個最容易下手,最快出效果的框架,這樣才能提高學習的興趣。下面逐一對比一下各個技術框架,讓你們可以找到最適合本身的。php

1、使用ext-skel C語言開發

ext-skel是PHP官方源碼裏提供的生成php擴展的工具,能夠生成一個c語言框架的php擴展的骨架。html

PHP 官方對擴展開發者很是不友好,源代碼中提供的Zend API極其難用,API複雜並且凌亂,充斥着各類宏的寫法。Zend API坑很是多,普通開發者很容易踩到坑裏。出現各類莫名其妙的core dump問題。Zend API幾乎沒有任何文檔,開發者若是要真正掌握這項技能須要付出大量的學習時間。

以上是swoole插件開發者的肺腑之言,可見用這個方法來開發插件,對咱們初學者來講將是對自信心極嚴重的打擊。幸虧有大神們爲咱們準備了其餘開發php擴展的方法,不用學習zend api,不用精通c語言,也照樣能開發php擴展,並且生成的擴展運行速度不會比c語言開發的相差太多。linux

2、使用zephir 類php語言開發

Zephir提供了一種相似php的高級語言語法的方式,來自動生成擴展的c語言代碼,使編寫php擴展變得很是的簡單。不過這種開發方式帶來了一個問題,就是因爲他用的不是c/c++語言開發,那就沒辦法直接利用現有的各類c/c++開發庫來實現強大的功能。因此感受上有點雞肋。c++

3、使用PHP-X C++語言開發

php-x是知名的swoole擴展開發者根據多年的開發經驗,提煉出來的一套基於c++的擴展開發框架。從文檔來看,這是一個比較容易上手的開發框架,數據類型很齊全,和php cpp的開發風格很是類似,但本人尚未去體驗使用。
按照php-x官方的文檔,開發出來的擴展只支持PHP7以上,這是一個遺憾。程序員

4、使用phpcpp C++語言開發

PHP CPP是我重點推薦的php擴展開發框架,簡明易懂,功能強大,開發效率高,代碼易維護,執行速度快。算法

PHP CPP是一款免費的php開發擴展庫,主要針對C++語言,能夠進行類集合的擴展和構建,採用簡單的計算機語言,讓擴展變得更有趣更有用,方便開發者進行維護和編寫,易於理解、維護輕鬆而且代碼優美。用C ++編寫的算法看起來與用PHP編寫的算法幾乎徹底相同。若是你知道如何在PHP中編程,你能夠很容易地學習如何在C ++中作一樣的。編程

  • 優勢一:不須要Zend引擎知識。

Zend引擎的內部太複雜,Zend引擎的代碼是一團糟,而且大可能是無證的。可是PHP-CPP庫已經在很是容易使用的C ++類和對象中封裝了全部這些複雜的結構。你可使用C ++寫出驚人的快速算法,而沒必要直接調用Zend引擎,甚至無需查看Zend引擎源代碼。使用PHP-CPP,您能夠編寫本地代碼,而無需處理PHP的內部。segmentfault

  • 優勢二:支持全部重要的PHP功能

使用PHP-CPP,您能夠像使用普通PHP腳本同樣輕鬆地處理變量,數組,函數,對象,類,接口,異常和命名空間。除此以外,你可使用C ++的全部功能,包括線程,lambda和異步編程。centos

  • 優勢三:支持PHP 5.X,PHP7的擴展開發

PHP-CPP有兩套擴展開發框架,分別支持PHP 5.X,PHP7,雖然框架代碼有兩個,可是接口倒是同樣的。因此若是你要開發兼容多個版本的php擴展,不會花費你額外太多時間作兼容。api

5、各開發框架的 hello world 擴展源碼大比拼

下面列出各個框架的hello world擴展源碼,從源碼長度和複雜度,就能有個直觀感覺。
ext-skel生成的c擴展源碼明顯可讀性極差,也極難理解。
zephir的擴展源碼最相似php語法,最容易入手,但難以加入成熟的c/c++庫代碼。
PHP-X和PHP CPP的源碼風格很類似,都是標準的c++語言,都很容易看懂。不難想象,這兩種方式開發擴展必然是最合適的,由於咱們既能利用c++的封裝簡化開發,又能直接調用市面上各個成熟c++庫爲咱們服務。

ext-skel的hello world源碼

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

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_helloworld.h"

static int le_helloworld;

PHP_FUNCTION(confirm_helloworld_compiled)
{
    char *arg = NULL;
    int arg_len, len;
    char *strg;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
        return;
    }

    len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "helloworld", arg);
    RETURN_STRINGL(strg, len, 0);
}

PHP_MINIT_FUNCTION(helloworld)
{
    return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(helloworld)
{

    return SUCCESS;
}

PHP_RINIT_FUNCTION(helloworld)
{
    return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(helloworld)
{
    return SUCCESS;
}

PHP_MINFO_FUNCTION(helloworld)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "helloworld support", "enabled");
    php_info_print_table_end();

}

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

zend_module_entry helloworld_module_entry = {
    STANDARD_MODULE_HEADER,
    "helloworld",
    helloworld_functions,
    PHP_MINIT(helloworld),
    PHP_MSHUTDOWN(helloworld),
    PHP_RINIT(helloworld),        /* Replace with NULL if there's nothing to do at request start */
    PHP_RSHUTDOWN(helloworld),    /* Replace with NULL if there's nothing to do at request end */
    PHP_MINFO(helloworld),
    PHP_HELLOWORLD_VERSION,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLOWORLD
ZEND_GET_MODULE(helloworld)
#endif

zephir的hello world源碼

namespace Test;
class Hello
{
    public function say()
    {
        echo "Hello World!";
    }
}

PHP-X的hello world源碼

#include <phpx.h>
using namespace std;
using namespace php;

//聲明函數
PHPX_FUNCTION(say_hello);

//導出模塊
PHPX_EXTENSION()
{
    Extension *ext = new Extension("hello-world", "0.0.1");
    ext->registerFunction(PHPX_FN(say_hello));
    return ext;
}

//實現函數
PHPX_FUNCTION(say_hello)
{
    echo("hello world");
}

PHP CPP的hello world源碼

#include <phpcpp.h>
void say_hello(Php::Parameters &params)
{
    Php::out << "hello world" << std::endl;
}
extern "C" {
    PHPCPP_EXPORT void *get_module() 
    {
        static Php::Extension extension("helloworld", "1.0");
        extension.add("say_hello", say_hello);
        return extension;
    }
}

參考文獻

如何基於 PHP-X 快速開發一個 PHP 擴展
PHP-X中文幫助
5分鐘PHP擴展開發快速入門
zephir中文網
zephir英文官網
zephir安裝和演示開發
phpcpp英文官網
phpcpp英文幫助
phpcpp中文幫助

相關文章
相關標籤/搜索