PHP扩展开发详解

学习背景

PHP extension提供了与C交互的接口,从个人的理解上,很好的提供了一种将固化、重复、性能要求高的行为下沉的机制,处于php内核与php应用空间之间,为程序员提供了一种利用php的前提下高性能(相对)完成任务的可能性,因此在工作中使用该模式完成一些相对底层、高效的操作。同时,因为PHP是在C语言之上的封装,极大提升了易用性,导致一些底层功能无法完成(例如swoole提供的线程粒度的调度),因此也需要这样的机制,使PHPER可以实现更丰富的功能。更关键的是可以分层、解耦,保证核心功能的下沉与单独维护。

参考资料

正文

简介

对于PHP扩展程序,在进行源码编译时有两种选择:1是将其编译到PHP应用程序中;2是以.so动态链接库的方式,单独编译。由于PHP通常对应的是前端开发,需求经常变化,因此保证PHP应用体积够小,功能简单。在实际生产环境中,大多采用方法2,以便于灵活调配功能。

而扩展PHP的功能,可以通过扩展或加入第三方包。目前有几种方法:

  • PECL:PHP Extension Community LibraryPHP扩展库,是使用c语言实现的PHP扩展,对语言本身外放方法。
  • PEAR:the PHP Extension and Application RepositoryPHP扩展与应用库,代码由PHP实现,逐渐被composer取代。
  • composer:PHP包管理工具,一般放在github、bitbucket上,使用composer管理的包,可以很轻松的利用SPL的autoload机制,将扩展的包打入自己的框架/项目。是目前比较火的PHP包管理方式。

PHP源码编译(MacOS 版本)

在开发PHP扩展前,首先要搞定环境。除了开发机以外,为了保证方便灵活,在本机(MacPro13’)上也构建一套php环境(实际上做这件事儿的意义并不算大,但是既然开始了,就必须都撸完,所以才有以下这么纠结的问题):

		# 1.从官方镜像源下载php源码包(7.1.3 tar.gz版本)
		wget  http://cn2.php.net/get/php-7.1.13.tar.gz/from/this/mirror
		# 2.解压
		tar zxvf php-7.1.13.tar.gz
		# 3.进入php工作目录,并且进行configure配置
		cd ./php-7.1.13
		# 4. 对源码进行config操作
		# 4.1 如果是从git上拉下来的源码需要用这个命令生成configure,依赖autoconfig应用,如果本机上没有
		./buildconf --force
		# 4.2 编译php,这里面几个需要注意的是 1. enable-fpm 连接nginx 如果是apache就用apx 2. enable-maintainer-zts 打开线程安全(生产环境都需要这个,之前看blog有一种解释是,类多线程的调度方式需要实现ts,异步回调的方式则不需要,所以渣浪这边的ts都disable,那么编写生产环境扩展的时候,除非是特殊情况,否则还是保证ts 3. 如果是写php扩展,实际上尽量打开debug开关 --enable-debug)
		./configure --prefix=/usr/local/php7 --with-config-file-path=/usr/local/php7/etc --with-config-file-scan-dir=/usr/local/php7/etc/php.d --enable-fpm --with-fpm-user=www --with-fpm-group=www --with-mysqli --with-pdo-mysql --with-iconv-dir --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-mbstring --with-mcrypt --enable-ftp --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --disable-fileinfo --enable-maintainer-zts --enable-debug
		# ps 由于mac环境与linux环境略有不同,在configure和make的过程中都会报错,按照参考资料中相关blog,一一处理即可(缺少头文件的,安装相关包,对configure文件和Makefile文件进行小幅修改)。主要调整configure、makefile中的相对路径保证可寻址。
		# 5. configure命令运行成功后,生成Makefile,然后直接make三连击~
		make
		make test  
		make install
		# 6. 为了更方便的使用生成全局的软连接,从某个版本开始mac上的/usr/bin目录的操作需要关闭mac的安全设置,所以用了另一个$PATH中的应用文件目录
		ln -s /usr/local/php7/bin/php /usr/local/bin/php7
		ln -s /usr/local/php7/bin/php-config /usr/local/bin/php7-config 
		ln -s /usr/local/php7/bin/phpize /usr/local/bin/php7ize
		ln -s /usr/local/php7/sbin/php-fpm /usr/local/sbin/php7-fpm
		# 7. 复制配置文件到相关位置(可以根据自己需要处理)
		cp php.ini-production /usr/local/php7/etc/php.ini
		cp sapi/fpm/init.d.php-fpm /etc/mach_init.d/php7-fpm
		chmod +x /etc/init.d/php7-fpm
		cp /usr/local/php7/etc/php-fpm.conf.default /usr/local/php7/etc/php-fpm.conf
		cp /usr/local/php7/etc/php-fpm.d/www.conf.default /usr/local/php7/etc/php-fpm.d/www.conf
	

####PHP扩展添加(MacOS 版本)

言归正传,如何将一个现有的extension源码添加入指定的PHP环境,分为以下几步(以鸟哥的taint为例):

    #我一般都会将扩展源码整理到PHP源码下的ext目录下,当前使用的PHP版本为7.1
	$git clone https://github.com/laruence/taint.git ./taint
	
	$cd ./taint
	
	#这一步在同时存在多个php版本的环境中尤其要注意,可以使用php -v 来确定当前版本,最好使用绝对路径处理
	$<your own php bin path>/phpize
	
	$./configure --with-php-config=<php-config path>
	
	$./make			#这里通常不选择make install,生成的.so/.la文件都在当前文件夹下的module文件中
	
	#去php.ini所在目录并修改,可以使用php -i | grep 'ini'查看这个文件在哪儿
	$vim <your own php lib path>php.ini
	
	#如果要在fast-cgi或者php_mod模式下生效,还需要重启http服务器
	$service php-fpm restart
	$apachectl restart
	
	#检查一下模块是否加载上了
	$<your own php bin path>/php -m | grep taint

PHP扩展新建(MacOS 版本)

要编写自己的扩展,首先需要在项目下创建一个项目(摆姿势),php提供了非常便利的工具,找到PHP的源文件夹下,进入扩展源码所在目录ext/内,使用扩展初始化创建工具ext_skel,例如我们创建名为test的扩展,会在当前文件夹下生成一个名为test的扩展文件包的新文件夹,里面包含有一个php extension所需的所有骨架文件:

$./ext_skel --extname=test	
	#程序在终端打印以下信息
	Creating directory test
	Creating basic files: config.m4 config.w32 .gitignore test.c php_test.h CREDITS EXPERIMENTAL tests/001.phpt test.php [done].
	
	To use your new extension, you will have to execute the following steps:
	
	1.  $ cd ..
	2.  $ vi ext/test/config.m4
	3.  $ ./buildconf
	4.  $ ./configure --[with|enable]-test
	5.  $ make
	6.  $ ./sapi/cli/php -f ext/test/test.php
	7.  $ vi ext/test/test.c
	8.  $ make

生成的扩展test目录结构如下:

$ tree
	.
	├── CREDITS
	├── EXPERIMENTAL
	├── config.m4				#unix类系统配置
	├── config.w32			#windows系统配置
	├── php_test.h			#
	├── test.c             #扩展
	├── test.php
	└── tests
	    └── 001.phpt

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券