深入Php底層,用c為php編寫拓展

1.前言

    

        隨著lamp/lnmp架構的流行,Php語言越來越得到廣泛的使用。php語言在表現層有著非常優異的表現,部署方便,開發迅速。但Php語言也有著天生短板以及局限性—-對多線程以及多進程的支持不甚如意,以及相對于靜態語言緩慢的執行速度。如今網站的數據越來越多,涉及到的密集型計算對性能的要求越來越高,php語言越來越難以滿足這種計算性能的要求,由于Php底層由c語言開發完成,用c語言更改php底層以及為Php語言編寫底層拓展是解決Php本身性能的一大方法。

        本文將以一個簡單實例來演示如何為Php編寫底層拓展,讀者掌握此方法后,可以根據具體的業務需求,為php編寫具有良好性能的底層拓展。如,筆者在工作中遇到過隨時計算用戶之間GPS距離的產品需求,涉及的計算量巨大。讀者遇到此類的需求,可以考慮在底層專門寫出c語言拓展來解決問題。本文成稿時間匆忙,紕漏之處在所難免,希望讀者指正。

2.編寫拓展

   2.1 自動生成框架

         

         請下載php源碼包,yum安裝的php沒有ext_skel這個文件。ext_skel這個文件就用來幫我們生成框架。具體的目錄如下:

[root@localhost~/tools/php-5.5.38/ext]> ll /root/tools/php-5.5.38/ext/ext_skel
-rwxr-xr-x. 1 1000 admins 8192 Jul 20 16:41 /root/tools/php-5.5.38/ext/ext_skel

             現在執行這個文件,生成一個helloWorld的框架:

[root@localhost~/tools/php-5.5.38/ext]> /root/tools/php-5.5.38/ext/ext_skel --extname=helloWorld
Creating directory helloWorld
Creating basic files: config.m4 config.w32 .svnignore helloWorld.c php_helloWorld.h CREDITS EXPERIMENTAL tests/001.phpt helloWorld.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/helloWorld/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-helloWorld
5.  $ make
6.  $ ./sapi/cli/php -f ext/helloWorld/helloWorld.php
7.  $ vi ext/helloWorld/helloWorld.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/helloWorld/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.

            

如上所示,ext_skel幫我們生成了helloWorld拓展的框架,里面包含了一個配置文件config.m4, c語言的頭文件php_helloWorld.h, 以及函數文件helloWorld.c(這個文件就是寫入c函數體的地方)。找到這些文件:

[root@localhost~/tools/php-5.5.38/ext/helloWorld]> ll
total 32
-rw-r--r--. 1 root chuji001 2178 Oct 30 02:54 config.m4
-rw-r--r--. 1 root chuji001  324 Oct 30 02:54 config.w32
-rw-r--r--. 1 root chuji001   10 Oct 30 02:54 CREDITS
-rw-r--r--. 1 root chuji001    0 Oct 30 02:54 EXPERIMENTAL
-rw-r--r--. 1 root chuji001 5296 Oct 30 02:54 helloWorld.c
-rw-r--r--. 1 root chuji001  514 Oct 30 02:54 helloWorld.php
-rw-r--r--. 1 root chuji001 2962 Oct 30 02:54 php_helloWorld.h
drwxr-xr-x. 2 root chuji001 4096 Oct 30 02:54 tests

    2.2 編輯文件

    編輯config.m4這個配置文件,找到如下配置行,去掉前面的dnl, 目的是方便之后configure編譯新開發出來的模塊:

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

     改為:

 10 PHP_ARG_WITH(helloWorld, for helloWorld support,
 11 Make sure that the comment is aligned:
 12 [  --with-helloWorld             Include helloWorld support])

接下來編寫c的頭文件,找到這一行:

 PHP_FUNCTION(confirm_helloWorld_compiled);      /* For testing, remove later. */

這一行是我們實際調用的函數名稱,讀者可以改成方便開發團隊調用的名稱,也可以不更改,這里筆者更改如下:

PHP_FUNCTION(helloWorld);       /* For testing, remove later. */

接下來更改編譯文件helloWorld.c函數文件:

 41 const zend_function_entry helloWorld_functions[] = {
 42         PHP_FE(confirm_helloWorld_compiled,     NULL)           /* For testing, remove late
    r. */
 43         PHP_FE_END      /* Must be the last line in helloWorld_functions[] */
 44 };

改為注冊好的函數名:

 41 const zend_function_entry helloWorld_functions[] = {
 42         PHP_FE(helloWorld,     NULL)           /* For testing, remove late
    r. */
 43         PHP_FE_END      /* Must be the last line in helloWorld_functions[] */
 44 };

接下來就是編寫自己的業務邏輯函數,筆者這里寫入一個簡單的helloWorld,讀者可根據自己的需求來編寫調用的函數:

154 PHP_FUNCTION(helloWorld)
155 {
156     zend_printf("hello world\n");
157 }


2.2 編譯生成拓展


      編譯php:

[root@localhost~/tools/php-5.5.38/ext/helloWorld]> /application/php5.5.34/bin/phpize
Configuring for:
PHP Api Version:         20121113
Zend Module Api No:      20121212
Zend Extension Api No:   220121212

        生成拓展:

 這個時候觀察目錄,多了一個configure編譯文件

[root@localhost~/tools/php-5.5.38/ext/helloWorld]> ll
total 1244
-rw-r--r--. 1 root chuji001  79850 Oct 30 03:39 acinclude.m4
-rw-r--r--. 1 root chuji001 310225 Oct 30 03:39 aclocal.m4
drwxr-xr-x. 2 root chuji001   4096 Oct 30 03:39 autom4te.cache
drwxr-xr-x. 2 root chuji001   4096 Oct 30 03:39 build
-rwxr-xr-x. 1 root chuji001  45079 Oct 30 03:39 config.guess
-rw-r--r--. 1 root chuji001   1542 Oct 30 03:39 config.h.in
-rw-r--r--. 1 root chuji001   2166 Oct 30 03:09 config.m4
-rwxr-xr-x. 1 root chuji001  35782 Oct 30 03:39 config.sub
-rwxr-xr-x. 1 root chuji001 447850 Oct 30 03:39 configure

執行configure編譯,生成拓展, configure完成之后執行make(必要):

[root@localhost~/tools/php-5.5.38/ext/helloWorld]> ./configure --with-php-config=/application/php5.5.34/bin/php-config

 查看array_square_sum目錄的module目錄,會發現里面生成helloWorld.so,這個就是我們需要的擴展。

[root@localhost~/tools/php-5.5.38/ext/helloWorld/modules]> ll
total 28
-rw-r--r--. 1 root chuji001   823 Oct 30 03:46 helloWorld.la
-rwxr-xr-x. 1 root chuji001 23351 Oct 30 03:46 helloWorld.so

編寫php.ini的配置文件,為Php加入拓展:

 899 extension=helloWorld.so

將生成的拓展文件復制放入php默認的拓展文件目錄當中去:

[root@localhost~/tools/php-5.5.38/ext/helloWorld/modules]> cp helloWorld.so /application/php5.5.34/lib/php/extensions/no-debug-zts-20121212/

重啟httpd服務器,這個時候通過phpinfo你就可以看到自己編寫的拓展啦!如圖:

extension.png

編寫Php腳本即可直接調用這個函數:

  1 <?php
  2    helloWorld();
  3 ?>

顯示如圖:

hello.png



結語

    用c來為Php編寫拓展是一個深入的課題,筆者這里只是給出了簡單的例子,如讀者有需要,需找更加詳細的資料,本文的目的僅為入門。

原創文章,作者:21期王逸凡,如若轉載,請注明出處:http://www.www58058.com/55578

(0)
21期王逸凡21期王逸凡
上一篇 2016-10-29 19:57
下一篇 2016-10-29 20:15

相關推薦

  • 文本工具

    本文將介紹Linux下使用Shell處理文本時最常用的工具:find、grep、xargs、sort、uniq、tr、cut、paste、wc、sed、awk;提供的例子和參數都是最常用和最為實用的

    2017-11-25
  • Linux基礎知識(1)

    在開源的世界當中,有許多的開源協議,其中著名的有Apache、BSD和GPL協議,它們支撐了開源世界,使得讓那些開源程序變得豐富多彩,我們知道開源協定的發起人是Stallman,它主張的自由含義為自由學習和更改,自由使用;自由分發和自由創建衍生版。
    而Linux就是在這樣的開源協定下在1991年的10月份起義成功,同時,它也有它的哲學思想:

    2017-09-10
  • Linux基礎知識—文件系統和常用命令解讀

    一、    計算機組成         計算機組成(Computer Composition)指的是計算機系統結構(Computer Architecture)的邏輯實現,包括機器機內的數據流和控制流的組成及邏輯設計等。其任務是在指令集系統結構確定分配給硬件系…

    Linux干貨 2016-09-18
  • iptables-防火,防盜,防老王

        防火墻,其實說白了將,就是用于實現linux下訪問控制的功能的,它分為兩種方式,硬件防火墻和軟件防火墻。不過無論是在哪個網絡中,防火墻工作的地方一定是在網絡的邊緣。而我們的任務就是需要去定義防火墻如何工作的,這就是防火墻的策略,規則,以達到讓它對出入網絡的IP,數據進行檢測。     目前市…

    Linux干貨 2017-05-02
  • Javascript 裝載和執行

    一兩個月前在淘寶內網里看到一個優化Javascript代碼的競賽,發現有不少的人對Javascript的執行和裝載的基礎并不懂,所以,從那天起我就想寫一篇文章,但一直耽擱了。自上篇《瀏覽器渲染原理簡介》,正好也可以承前啟后。 首先,我想說一下Javascript的裝載和執行。通常來說,瀏覽器對于Javascript的運行有兩大特性:1)載入后馬上執行,2)執…

    Linux干貨 2016-07-10
  • 虛擬主機的實現

    示例1:基于ip 編輯配置文件,切換到最后一行,增加: <VirtualHost 192.168.1.117:80>     ServerName web1.ams.com     DocumentRoot "/vhosts/web1/htdocs" </VirtualHost&g…

    Linux干貨 2016-08-05
欧美性久久久久