0x01 起步
PHP-X本身基于C++11開發,使用cmake進行編譯配置,首先,你需要確定所有依賴項已安裝好,包括:
- gcc-4.8 或更高版本
- PHP7.0 或更高版本,需要php7-dev 開發包
- cmake-2.8 或更高版本
然后安裝PHP-X,
git clone https://github.com/swoole/PHP-X.git cd PHP-X cmake . make -j 4 sudo make install
未出現任何編譯錯誤,會成功編譯出libphpx.so,并安裝到系統的lib目錄,頭檔案會復制到系統的include目錄,這時需要執行 sudo ldconfig重繪so檔案快取,
0x02 新建工程
使用任意開發工具,新建一個http://test.cc源檔案,首先需要引入phpx.h頭檔案,然后使用using引入phpx的命名空間,PHP官方未使用C++,因此phpx直接使用了php作為命名空間,
#include <phpx.h> using namespace std; using namespace php;
創建擴展使用PHPX_EXTENSION宏來實作,在這宏中只需要new Extension即可創建擴展,構造方法接受2個引數,第一個是擴展的名稱,第二個是擴展的版本號,在PHPX_EXTENSION宏中return這個擴展物件的指標,
PHPX_EXTENSION() { Extension *ext = new Extension("test", "0.0.1"); return ext; }
這里必須使用 new Extension,而不能直接在堆疊上創建物件
0x03 增加函式
一個PHP擴展的主要作用就是提供擴展函式,擴展函式由于是用C/C++代碼實作,因此它的性能會比PHP用戶函式性能高幾十甚至上百倍,在phpx中實作函式非常簡單,使用PHPX_FUNCTION來實作擴展函式,然后呼叫Extension::registerFunction來注冊擴展函式,
PHPX_FN是一個助手宏,實際上展開就是"cpp_hello_world", cpp_hello_world PHPX_FUNCTION展開后,包含了2個變數,第一個是引數args,第二個是回傳值retval
通過操作args和retval兩個變數,就可以實作函式的輸入和輸出
這里我們的代碼非常簡單,cpp_test($str, $n),呼叫這個函式回傳一個$n個$str的陣列,
1 #include <phpx.h> 2 using namespace std; 3 using namespace php; 4 5 //宣告函式 6 PHPX_FUNCTION(cpp_test); 7 8 PHPX_EXTENSION() 9 { 10 Extension *ext = new Extension("test", "0.0.1"); 11 ext->registerFunction(PHPX_FN(cpp_test)); 12 return ext; 13 } 14 15 //實作函式 16 PHPX_FUNCTION(cpp_test) 17 { 18 //args[1] 就是這個擴展函式的第 2 個引數 19 long n = args[1].toInt(); 20 21 //將回傳值 retval 初始化為陣列 22 Array _array(retval); 23 24 for(int i = 0; i < n; i++) 25 { 26 //args[0] 就是這個擴展函式的第 1 個引數 27 //append 方法表示向陣列中追加元素 28 _array.append(args[0]); 29 } 30 }
0x04 編譯擴展
撰寫一個Makefile檔案,內容如下:
1 PHP_INCLUDE = `php-config --includes` 2 PHP_LIBS = `php-config --libs` 3 PHP_LDFLAGS = `php-config --ldflags` 4 PHP_INCLUDE_DIR = `php-config --include-dir` 5 PHP_EXTENSION_DIR = `php-config --extension-dir` 6 7 test.so: test.cc 8 c++ -DHAVE_CONFIG_H -g -o test.so -O0 -fPIC -shared test.cc -std=c++11 ${PHP_INCLUDE} -I${PHP_INCLUDE_DIR} -lphpx 9 10 install: test.so 11 cp test.so ${PHP_EXTENSION_DIR}/ 12 clean: 13 rm *.so
php-config 這個工具是PHP提供的,使用php-config可以得到PHP的安裝路徑、頭檔案目錄、擴展目錄、其他額外的編譯引數等等,
這個Makefile支持了3個指令,make編譯,make clean清理,make install安裝到擴展目錄中,
這里可能需要root權限,使用sudo make install進行安裝
直接從網頁復制,可能會出現tab制表符被替換為空格,請手工編輯一下Makefile使用tab縮進 MacOS下需要在c++編譯引數中增加-undefined dynamic_lookup
撰寫好之后執行make install,就會編譯擴展并將擴展test.so安裝到PHP的擴展目錄中,這時需要修改php.ini加入extension=test.so加載擴展,
使用php -m來觀察你的擴展是否正常加載,
1 php -m 2 [PHP Modules] 3 Core 4 ctype 5 curl 6 date 7 dom 8 fileinfo 9 filter 10 gd 11 hash 12 iconv 13 inotify 14 json 15 libxml 16 mbstring 17 mcrypt 18 memcached 19 mongodb 20 mysqli 21 mysqlnd 22 openssl 23 pcntl 24 pcre 25 PDO 26 pdo_mysql 27 pdo_sqlite 28 Phar 29 posix 30 redis 31 Reflection 32 session 33 SimpleXML 34 sockets 35 SPL 36 sqlite3 37 standard 38 swoole 39 test 40 tokenizer 41 xml 42 xmlreader 43 xmlwriter 44 yac 45 zlib 46 zmq 47 48 [Zend Modules]
這里看到test,表明你的擴展已經加載成功了,現在就可以呼叫cpp_test這個擴展函式了,
0x05 執行
撰寫一個test.php,內容為:
1 <?php 2 var_dump(cpp_test("hello", 3)); 3 執行test.php: 4 5 php test.php 6 array(3) { 7 [0]=> 8 string(5) "hello" 9 [1]=> 10 string(5) "hello" 11 [2]=> 12 string(5) "hello" 13 }
可以看到執行結果符合預期,那么恭喜你,現在你已經成功地開發了一個PHP擴展了,是不是很簡單?
0x06 更多
上面的例子還比較簡單,只是撰寫了一個擴展函式,要真正在實際專案中使用PHP-X你還有很多作業要做,
- 需要C++的功底
- 了解更多PHP-X的 API
另外配合使用Eclipse等IDE工具,可以實作API自動提示和補齊,開發起來會更順手,
相比Zend API,PHP-X要簡單易用地多了,相信你不會花太多時間就可以掌握此項技能,在接下來我會撰寫更多教程,教大家如何使用PHP-X實作擴展類、資源、回呼函式等更復雜的功能,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/121019.html
標籤:PHP
