PHP Extension Makefile 製作
2019獨角獸企業重金招聘Python工程師標準>>>
PHP Extension 是什么呢?很多寫PHP的工程師,或許不知道PHP Extension是怎么做出來的,其實PHP 的最底層是使用c 語言,每一句PHP 的語法,都是透過c 語言來實現,所以我們可以藉由c ,去加強PHP 的功能,讓PHP 更方便使用,一個正常的PHP Extension制作時,要先編寫config.m4 這個檔案,雖然這個檔案不難寫,不過他與Makefile的格式落差很大,這里就介紹如何使用Makefile 來編譯PHP Extension ,先介紹一下正常的PHP Extension編譯流程,phpize會建立Makefile檔案, ./configure 這個指令會自動檢查相關package 是否安裝
- 建立c code 與config.m4
- phpize (下Linux 指令phpize)
- ./configure
- make
- mv modules/xxx.so /extension : 將編譯出來的so檔,搬到extension目錄下,這樣就算完成一個PHP Extension
制作php extension Makefile
基實phpize的行為就是建立Makefile, libtool 等等工具,./configure就是檢查一些設定是否正常,以及路徑設定,即然我都要自已寫php extension了,那就跳過這兩個過程吧,自已寫Makefile。
- 首先我們先使用phpize ,自動生出一個Makefile,然后再把他改成我們想要的格式。
- phpize & mv Makefile Makefile.global : 把Makefile改成Makefile.global
修改Makefile.global成我們要的樣子Makefile.global范例
- 加入php 安裝的目錄PHP_DIR = /home/program/php (路徑自已修改吧)
- 將部分變數的值改到PHP_DIR ,如prefix = $(PHP_DIR),phpincludedir = $(PHP_DIR)/include/php
- phplibdir = $(SRC_PATH)/modules :指定編譯完成后,so檔的路徑
- PHP_PECL_EXTENSION = extension name //(注意名稱不要重覆)
- srcdir , builddir , top_srcdir , top_builddir ,修改至當前目錄,要用絕對目錄
簡化過后的Makefile
Makefile.global弄半天,最后終于簡化完成,以后要編譯php extension就方便多了,正式寫一個要用來編譯程式的Makefile ,你看! 下面的PHP Makefile 多么簡短。
Example
SRC_PATH = $ ( shell pwd ) LDEF = - DCOMPILE_DL_MyExtension CXXFILE = myClass . cc extension . cc EXTRA_CXXFLAGS = CXXOUTPUT = MyExtension include Makefile . global cp : sudo cp ./ modules / $ ( CXXOUTPUT ). so / home / php_extension /
make 的結果
Example
create myClass . lo create myClass . o create extension . lo create extension . o create MyExtension . la create MyExtension . so //最后產生MyExtension.so 成功
接收php 傳進來的變數的方式,使用zend_parse的function,有下列兩種,其中[sal,lsl]代表要接放的變數型態。
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sal",xxx,xx)
- zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,num_args TSRMLS_CC,"lsl", xx,xx,xx,xx)
- l : 代表long
- s : string
- a : array
- b : boolean
- d : double
- 回傳result 給php的方式有下列幾種
- RETURN_LONG : 回傳long
- RETURN_STRING : 回傳字串
- RETURN_DOUBLE : 回傳倍精數
- RETURN_BOOL : 回傳boolean (true or false)
建立一個php extension function
要寫一個extension function ,就是使用PHP_FUNCTION 這個function ,而傳進去的第一個參數,就是function 名稱,寫好之后,就可以在php 里使用simple("xxx");
Example
PHP_FUNCTION ( simple ) { char * str = NULL ; char * tmp = new char [ 50 ]; string result = "" ; int str_len = 0 ; if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC , "s" , & str ,& str_len ) == FAILURE ) { RETURN_NULL (); } sprintf ( tmp , "Your input string is [%s]" , str ); result = tmp ; delete [] tmp ; RETURN_STRING ( const_cast < char *>( result . c_str ()), 1 ); }
第二個范例是function entry 中定義的add ,主要功能是將第一個參數與第二個參數做加總的功能,在php extension 中,所有的數字回僨都是使用RETURN_LONG,不需要依int ,long,float 去判斷回傳值,這是由于php 變數型態很自由,不用區分得這么細。
Example
PHP_FUNCTION ( add ) { int num_args = ZEND_NUM_ARGS (); if ( num_args != 2 ) { RETURN_LONG ( 0 ); } int result = 0 , int1 , int2 ; if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC , "ll" , & int1 ,& int2 ) == FAILURE ) { RETURN_NULL (); } result = int1 + int2 ; RETURN_LONG ( result ); }
相關問題
warning: deprecated conversion from string constant to 'char*'
我升級gcc 4.2.0 后,編譯就會出現這個Warning,使用gcc 3.4.6 就沒事了。
第二招,碰到Warning不要停掉,在Makefile檔案中,將-Werror 這個屬性拿掉吧
undefined symbol:__gxx_personality_v0
因為你使用c++ 語法,但是卻沒有載入c++ 的library
解法:將Makefile 的CC 加上-lstdc++ ,加上這句后,編譯時,會自動載入/usr/lib/libstdc++.so。
Example
CC = cc - lstdc ++
錯誤: Invalid library (maybe not a PHP library)的處理
這代表,php在載入so檔時,找不到程序入口,c & c++的程序入口是main ,而php extension的程序入口是zend_module_entry ,但是因為我有使用到c++ 語法,c++有個特性,在編譯時,會自動亂改變數及function名稱。
Example
zend_module_entry MyExtension_module_entry
像這句語法,經過c++ 編譯后,就可能變成MyExtension_module_entryii,結果造成找不到程序入口而報錯。
解法就是多加一句extern "C"
Example
zend_module_entry MyExtension_module_entry = { } extern "C" { ZEND_GET_MODULE ( MyExtension ) }
為何要加extern "C" 呢?
我們知道C++ 有overloading 的功能,一個function 可以有多種不同的參數數量,可是c++ 是怎么辦到的呢,其實他在編譯程式的時候,就會自動做function name 的mapping ,例如下面的例子,可是單純的c 語言并不懂這個東西,所以當c 語言要去讀取c++ 的function 時,就必需加上extern "C" ,強迫c++ 不要亂改名稱,這樣c語言才能正確的執行function 。
Example
int test ( int a ){} int test ( char b , char c ){} //編譯后 test ( int a ) => test_1 ( int a ) test ( char b , char c ) => test_2 ( char b , char c )
轉載于:https://my.oschina.net/mickelfeng/blog/343420
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的PHP Extension Makefile 製作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用bat文件快速解决adb找不到设备的
- 下一篇: Solr搜索的排序打分规则探讨