深入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.178linux.com/55578

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

相关推荐

  • bash 函数

        函数可以让多条shell的命令组成语句块,实现代码重用和模块化编程。让我们在不用重复编写一些脚本,下面让我们来了解函数。 1,函数的简介 函数在脚本中使用应先定义,声明,再可以调用。 函数function 是由若干条shell 命令组成的语句块,实现代码重用和模块化编程。 函数与shell 程序形式上是相似的,…

    Linux干货 2016-08-24
  • find查找

    find查找是生产中最常见的日志查找工具 下面看看它的用法 基本用法: find    查找路径    查找标准    查找到以后的处理动作 查找路径:需要被查找的文件所在的路径,一定是个目录,默认情况下为当前的目录 查找的标准:查找的时候用什么方式去查找 处理动作:文件查找完毕后,需要对查找出来的…

    Linux干货 2017-05-08
  • Centos下实现多网卡绑定

    实现多网卡绑定在Centos6和Centos7可采用bonding方式,Centos7上team网络组也可实现,并且功能更强大。 Linux bonding 模块提供一种将多个网卡聚合成一块逻辑捆绑网卡的实现方法。 捆绑的网卡拥有多种模式,根据模式的特性,可实现网络负载均衡,网络冗余切换,提高网络吞吐量等功能。 大多流行Linux发行版都已装载bonding…

    Linux干货 2016-09-13
  • linux发展史——兽人永不为奴

      了解历史才能判断趋势。既然我们已经打算跳入运维这个坑,了解先烈的历史事迹是必须的。为什么说是必须的呢?现在我们处于一个知识时代,资本在追着知识跑,像海银资本这种vc都看不起中国的市场了,已经带着中国的资本在万恶资本主义的老美投资了。 1计算机硬件组成   操作系统成为了非常重要人类创造生产力的场所,很多人都开始追本…

    Linux干货 2016-10-14
  • 马哥教育网络班21期-第四周课程练习

    Do one thing at a time,and do well. 小僧近期忙的去尿尿的时间都要挤出来…..! 无人能理解 zZzz 复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。 编辑/etc/group文件,添加组hadoop。 手动编辑/etc/pass…

    Linux干货 2016-07-29
  • 给linux系统添加新的磁盘

    虚拟化环境中,我们经常会遇到需要增加磁盘容量的情况,通常有两种方式,第一种是添加一块新的硬盘,另一种是扩容原有磁盘,以下是添加新磁盘至linux系统的操作规范。注:具体磁盘信息可能有所不同。 ##查看新增加磁盘/dev/sdb的信息 [root@CentOS7 ~]# fdisk -l /dev/sdb   Disk /dev/sdb: 5368 …

    Linux干货 2016-11-11