深入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
下一篇 2016-10-29

相關推薦

  • 文件共享服務之SAMBA

    文件共享服務之SAMBA 文件共享服務之SAMBA 一、samba出現的意義 二、samba協議描述 三、samba為客戶端的實現 四、samba為服務端的實現 五、使用圖形界面配置SAMBA 一、samba出現的意義 首先nfs實現系統文件掛載linux與linux之間,linux到windows之間實現的并不是那么理想 FTP可以實現linux和wind…

    Linux干貨 2016-04-19
  • 磁盤管理(一)磁盤分區表類型與文件系統

    概述:本章介紹磁盤分區和文件系統,深度了解linux存儲數據所依賴到各個部分模塊。 設備文件 I/O Ports: I/O設備地址 一切皆文件: Linux為所有的設備文件都提供了統一的操作函數接口,方法是使用數據結構struct file_operations。這個數據結構中包括許多操作函數的指針,如open()、close()、read()和write(…

    Linux干貨 2016-09-01
  • Linux用戶和組管理

      用戶和組管理類命令的使用方法 Liunx用戶組管理命令: groupadd命令:添加組     命令用法:         groupadd [選項] group_name   &nbs…

    Linux干貨 2016-11-25
  • kickstart+ftp+dhcp+tftp實現centos6的無人值守安裝

    環境IP : 172.16.0.32 centos 6.6 一.安裝相關包 安裝圖形界面 [root@localhost ~]# yum groupinstall “Desktop” “X Window System” “Chinese Support” [root@localhost ~]# yum -y install dhcp tftp-server …

    Linux干貨 2017-06-03
  • 文件查找(find)

                                  …

    2017-04-11
欧美性久久久久