編譯安裝php7.3.12 和 php7.3.12 開發ext拓展

linux系統

php源碼包下載地址:https://www.php.net/downloads.php

PHP 7.3開始,開發拓展,取消了 ./ext_skel 命令工具,

要使用 php ext_skel.php 命令的形式創建拓展

一、下載源碼包解壓後,編譯安裝php

#下載源碼包  php-7.3.12.tar.gz
[root@localhost package]# wget https://www.php.net/distributions/php-7.3.12.tar.gz
[root@localhost package]# ll
total 143964
-rw-r--r--. 1 root root  19457403 Nov 22 14:48 php-7.3.12.tar.gz

#解壓
[root@localhost package]# tar -zxvf php-7.3.12.tar.gz
[root@localhost package]# ll
total 143968
drwxr-xr-x. 14 1000 1000      4096 Jul  3 19:30 php-7.3.12
-rw-r--r--.  1 root root  19457403 Nov 22 14:48 php-7.3.12.tar.gz

#安裝php運行環境
[root@localhost package]# yum install libxml libxml2 libxml2-devel -y
[root@localhost package]# yum install openssl openssl-devel -y
[root@localhost package]# yum install curl libcurl libcurl-devel -y
[root@localhost package]# yum install libjpeg-devel -y
[root@localhost package]# yum install libpng-devel -y
[root@localhost package]# yum install freetype-devel -y
[root@localhost package]# yum install libicu-devel -y
[root@localhost package]# yum install glibc-headers gcc-c++ -y
[root@localhost package]# yum -y install libxslt libxslt-devel
[root@localhost package]# yum install libzip-devel -y
[root@localhost package]# yum install autoconf -y

# 安裝 php 調試跟蹤工具
[root@localhost etc]# yum install strace -y

#安裝 libzip
[root@localhost package]# yum remove libzip -y
[root@localhost package]# wget https://nih.at/libzip/libzip-1.2.0.tar.gz
[root@localhost package]# tar -zxvf libzip-1.2.0.tar.gz
[root@localhost package]# cd libzip-1.2.0
[root@localhost libzip-1.2.0]# ./configure
[root@localhost libzip-1.2.0]# make && make install
[root@localhost libzip-1.2.0]find /usr/local -iname 'zipconf.h'
[root@localhost libzip-1.2.0]ln -s /usr/local/lib/libzip/include/zipconf.h /usr/local/include

#添加搜索路徑到配置文件
echo '/usr/local/lib64
/usr/local/lib
/usr/lib
/usr/lib64'>>/etc/ld.so.conf

#更新配置
ldconfig -v


#切換目錄 ,編譯安裝 php-7.3.12
[root@localhost package]# cd php-7.3.12
[root@localhost php-7.3.12]# ./configure --prefix=/usr/local/php7.3.12 --with-config-file-path=/usr/local/php7.3.12/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-iconv-dir --with-freetype-dir=/usr/local/freetype --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 --enable-intl --enable-pcntl --enable-ftp --with-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --with-gettext --disable-fileinfo --enable-opcache --with-xsl

[root@localhost php-7.3.12]# make clean

[root@localhost php-7.3.12]# make && make install


#查看php 版本,安裝完畢
[root@localhost php-7.3.12]# /usr/local/php7.3.12/bin/php -v
PHP 7.3.12 (cli) (built: Nov 22 2019 16:44:43) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.12, Copyright (c) 1998-2018 Zend Technologies


具體配置php可參考另一篇文章,這裏不多說:https://blog.csdn.net/daily886/article/details/79504404

 

二、開始拓展配置

# 回到 php-7.3.12 編譯包的解壓目錄下面 ,切換到 ext 目錄
[root@localhost php-7.3.12]# cd ext

# 查看拓展使用方法
[root@localhost ext]# /usr/local/php7.3.12/bin/php ext_skel.php --help
php ext_skel.php --ext <name> [--experimental] [--author <name>]
                 [--dir <path>] [--std] [--onlyunix]
                 [--onlywindows] [--help]

  --ext <name>		The name of the extension defined as <name>
  --experimental	Passed if this extension is experimental, this creates
                        the EXPERIMENTAL file in the root of the extension
  --author <name>       Your name, this is used if --std is passed and
                        for the CREDITS file
  --dir <path>		Path to the directory for where extension should be
                        created. Defaults to the directory of where this script
 			lives
  --std			If passed, the standard header and vim rules footer used
 			in extensions that is included in the core, will be used
  --onlyunix		Only generate configure scripts for Unix
  --onlywindows		Only generate configure scripts for Windows
  --help                This help


#創建hello world 拓展
[root@localhost ext]# /usr/local/php7.3.12/bin/php ext_skel.php --ext hello_world
Copying config scripts... done
Copying sources... done
Copying tests... done

Success. The extension is now ready to be compiled into PHP. To do so, use the
following steps:

cd /path/to/php-src
./buildconf
./configure --enable-hello_world
make

Don't forget to run tests once the compilation is done:
make test TESTS=ext/hello_world/tests

Thank you for using PHP!


#切換到 hello_world 拓展目錄
[root@localhost ext]# cd hello_world
[root@localhost hello_world]# ll
total 16
-rw-r--r--. 1 root root 3004 Nov 22 17:03 config.m4
-rw-r--r--. 1 root root  246 Nov 22 17:03 config.w32
-rw-r--r--. 1 root root 2408 Nov 22 17:03 hello_world.c
-rw-r--r--. 1 root root  364 Nov 22 17:03 php_hello_world.h
drwxr-xr-x. 2 root root   54 Nov 22 17:03 tests


編輯 config.m4 ,內容如下:

dnl config.m4 for extension hello_world

dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary.

dnl If your extension references something external, use with:

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

dnl Otherwise use enable:

PHP_ARG_ENABLE(hello_world, whether to enable hello_world support,
dnl Make sure that the comment is aligned:
[  --enable-hello_world          Enable hello_world support], no)

if test "$PHP_HELLO_WORLD" != "no"; then
  dnl Write more examples of tests here...

  dnl # get library FOO build options from pkg-config output
  dnl AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
  dnl AC_MSG_CHECKING(for libfoo)
  dnl if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists foo; then
  dnl   if $PKG_CONFIG foo --atleast-version 1.2.3; then
  dnl     LIBFOO_CFLAGS=\`$PKG_CONFIG foo --cflags\`
  dnl     LIBFOO_LIBDIR=\`$PKG_CONFIG foo --libs\`
  dnl     LIBFOO_VERSON=\`$PKG_CONFIG foo --modversion\`
  dnl     AC_MSG_RESULT(from pkgconfig: version $LIBFOO_VERSON)
  dnl   else
  dnl     AC_MSG_ERROR(system libfoo is too old: version 1.2.3 required)
  dnl   fi
  dnl else
  dnl   AC_MSG_ERROR(pkg-config not found)
  dnl fi
  dnl PHP_EVAL_LIBLINE($LIBFOO_LIBDIR, HELLO_WORLD_SHARED_LIBADD)
  dnl PHP_EVAL_INCLINE($LIBFOO_CFLAGS)

  dnl # --with-hello_world -> check with-path
  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this
  dnl SEARCH_FOR="/include/hello_world.h"  # you most likely want to change this
  dnl if test -r $PHP_HELLO_WORLD/$SEARCH_FOR; then # path given as parameter
  dnl   HELLO_WORLD_DIR=$PHP_HELLO_WORLD
  dnl else # search default path list
  dnl   AC_MSG_CHECKING([for hello_world files in default path])
  dnl   for i in $SEARCH_PATH ; do
  dnl     if test -r $i/$SEARCH_FOR; then
  dnl       HELLO_WORLD_DIR=$i
  dnl       AC_MSG_RESULT(found in $i)
  dnl     fi
  dnl   done
  dnl fi
  dnl
  dnl if test -z "$HELLO_WORLD_DIR"; then
  dnl   AC_MSG_RESULT([not found])
  dnl   AC_MSG_ERROR([Please reinstall the hello_world distribution])
  dnl fi

  dnl # --with-hello_world -> add include path
  dnl PHP_ADD_INCLUDE($HELLO_WORLD_DIR/include)

  dnl # --with-hello_world -> check for lib and symbol presence
  dnl LIBNAME=HELLO_WORLD # you may want to change this
  dnl LIBSYMBOL=HELLO_WORLD # you most likely want to change this

  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  dnl [
  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $HELLO_WORLD_DIR/$PHP_LIBDIR, HELLO_WORLD_SHARED_LIBADD)
  dnl   AC_DEFINE(HAVE_HELLO_WORLDLIB,1,[ ])
  dnl ],[
  dnl   AC_MSG_ERROR([wrong hello_world lib version or lib not found])
  dnl ],[
  dnl   -L$HELLO_WORLD_DIR/$PHP_LIBDIR -lm
  dnl ])
  dnl
  dnl PHP_SUBST(HELLO_WORLD_SHARED_LIBADD)

  dnl # In case of no dependencies
  AC_DEFINE(HAVE_HELLO_WORLD, 1, [ Have hello_world support ])

  PHP_NEW_EXTENSION(hello_world, hello_world.c, $ext_shared)
fi

編輯 hello_world.c ,內容如下:

/* hello_world extension for PHP */
//for php 7.3.12


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "php_hello_world.h"

/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE() \
	ZEND_PARSE_PARAMETERS_START(0, 0) \
	ZEND_PARSE_PARAMETERS_END()
#endif

/*自定義函數開始*/
/* {{{ void hello_world_func()
*/
PHP_FUNCTION(hello_world_func)
{
    char *name;
    size_t name_len;
    zend_string *strg;

   #ifndef FAST_ZPP  //如果沒有定義 FAST_ZPP
        //,在PHP7之前一直使用zend_parse_parameters函數獲取參數
       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
            //ZEND_NUM_ARGS() 告訴Zend引擎要取的參數的信息, TSRMLS_CC 用來確保線程安全,返回值檢測是SUCCESS還是FAILURE。
            // | 代表後面的參數可不傳
            // s 小寫的s 代表字符串string
            // &name 把獲取的字符串傳址給 name
            // &name_len 把獲取的字符串長度傳址給 name_len
            php_printf("param error!"); // php_printf 是php拓展自帶的打印函數
            RETURN_NULL(); //返回空值
       }
   #else
        //在PHP7中新提供的方式。是爲了提高參數解析的性能
       ZEND_PARSE_PARAMETERS_START(0, 1) //第一個參數表示必傳的參數格式,第二個參數表示最多傳入的參數個數。
       		Z_PARAM_OPTIONAL // Z_PARAM_OPTIONAL 對應 |  代表後面的參數可不傳
       		Z_PARAM_STRING(name, name_len) //Z_PARAM_STRING 對應小寫的s 代表字符串string ,後面的參數代表zend_parse_parameters 的 &name 和 &name_len
       	ZEND_PARSE_PARAMETERS_END();
   #endif

    strg = strpprintf(0,"hello world %s!", name); //strpprintf是PHP爲我們提供的字符串拼接的方法。第一個參數是最大字符數,第二個是返回的字符串%s是需要替換的字符串,後面的是參數
    RETURN_STR(strg);
}
/* }}} */
/*自定義函數結束*/

/* {{{ void hello_world_test1()
 */
PHP_FUNCTION(hello_world_test1)
{
	ZEND_PARSE_PARAMETERS_NONE();

	php_printf("The extension %s is loaded and working!\r\n", "hello_world");
}
/* }}} */

/* {{{ string hello_world_test2( [ string $var ] )
 */
PHP_FUNCTION(hello_world_test2)
{
	char *var = "World";
	size_t var_len = sizeof("World") - 1;
	zend_string *retval;

	ZEND_PARSE_PARAMETERS_START(0, 1)
		Z_PARAM_OPTIONAL
		Z_PARAM_STRING(var, var_len)
	ZEND_PARSE_PARAMETERS_END();

	retval = strpprintf(0, "Hello %s", var);

	RETURN_STR(retval);
}
/* }}}*/

/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(hello_world)
{
#if defined(ZTS) && defined(COMPILE_DL_HELLO_WORLD)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(hello_world)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "hello_world support", "enabled");
	php_info_print_table_row(2, "author", "daily886"); /* Replace with your name */
	php_info_print_table_end();
}
/* }}} */

/* {{{ arginfo
 */
ZEND_BEGIN_ARG_INFO(arginfo_hello_world_test1, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO(arginfo_hello_world_test2, 0)
	ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO(hello_world_func, 0)
	ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO()
/* }}} */

/* {{{ hello_world_functions[]
 */
static const zend_function_entry hello_world_functions[] = {
	PHP_FE(hello_world_test1,		arginfo_hello_world_test1)
	PHP_FE(hello_world_test2,		arginfo_hello_world_test2)
	PHP_FE(hello_world_func,		hello_world_func)
	PHP_FE_END
};
/* }}} */

/* {{{ hello_world_module_entry
 */
zend_module_entry hello_world_module_entry = {
	STANDARD_MODULE_HEADER,
	"hello_world",					/* Extension name */
	hello_world_functions,			/* zend_function_entry */
	NULL,							/* PHP_MINIT - Module initialization */
	NULL,							/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(hello_world),			/* PHP_RINIT - Request initialization */
	NULL,							/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(hello_world),			/* PHP_MINFO - Module info */
	PHP_HELLO_WORLD_VERSION,		/* Version */
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_HELLO_WORLD
# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
# endif
ZEND_GET_MODULE(hello_world)
#endif

 

創建拓展

[root@localhost hello_world]# find / -name phpize
/usr/local/php7.3.12/bin/phpize
/package/php-7.3.12/scripts/phpize

[root@localhost hello_world]# /usr/local/php7.3.12/bin/phpize
Configuring for:
PHP Api Version:         20180731
Zend Module Api No:      20180731
Zend Extension Api No:   320180731


[root@localhost hello_world]# find / -name php-config
/usr/local/php7.3.12/bin/php-config
/package/php-7.3.12/scripts/php-config

[root@localhost hello_world]# ./configure --with-php-config=/usr/local/php7.3.12/bin/php-config

[root@localhost hello_world]# make && make install
Installing shared extensions:     /usr/local/php7.3.12/lib/php/extensions/no-debug-non-zts-20180731/

# php拓展 hello_world.so 生成成功
[root@localhost hello_world]# find / -name hello_world.so
/usr/local/php7.3.12/lib/php/extensions/no-debug-non-zts-20180731/hello_world.so
/package/php-7.3.12/ext/hello_world/modules/hello_world.so
/package/php-7.3.12/ext/hello_world/.libs/hello_world.so

加載 hello_world.so 拓展並使用


# 添加用戶
[root@localhost php-7.3.12]# /usr/sbin/groupadd -f nginx
[root@localhost php-7.3.12]# /usr/sbin/useradd -g nginx nginx


# 切換到 php 安裝目錄
[root@localhost php-7.3.12]# cd /usr/local/php7.3.12

# 切換到 etc 目錄
[root@localhost php7.3.12]# cd etc

# 查找 php.ini初始配置
[root@localhost etc]# find / -name php.ini*
/package/php-7.3.12/php.ini-development
/package/php-7.3.12/php.ini-production

# 複製到當前目錄
[root@localhost etc]# cp /package/php-7.3.12/php.ini-development php.ini
[root@localhost etc]# ll
total 80
-rw-r--r--. 1 root root  5407 Nov 22 16:56 php-fpm.conf.default
drwxr-xr-x. 2 root root    30 Nov 22 16:56 php-fpm.d
-rw-r--r--. 1 root root 71709 Nov 23 09:08 php.ini

########## 設置 php 全局
[root@localhost etc]# ln -s /usr/local/php7.3.12/etc/php.ini /etc/php.ini
[root@localhost etc]# ln -s /usr/local/php7.3.12/bin/php /usr/local/bin/php


# 編輯 php.ini 加入一行
[root@localhost etc]# vi php.ini

extension=hello_world


########## 設置 php-fpm 全局
[root@localhost etc]# ln -s /usr/local/php7.3.12/sbin/php-fpm /usr/local/bin/php-fpm
[root@localhost etc]# php-fpm -v
PHP 7.3.12 (fpm-fcgi) (built: Nov 22 2019 16:46:26)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.12, Copyright (c) 1998-2018 Zend Technologies

[root@localhost etc]# chmod -R 777 /usr/local/php7.3.12

############# 複製 php-fpm 配置文件
[root@localhost etc]# cp php-fpm.conf.default php-fpm.conf
[root@localhost etc]# cp php-fpm.d/www.conf.default php-fpm.d/www.conf

######### 配置 php-fpm.conf ################
[root@localhost etc]# vi php-fpm.conf
 
# 開啓 pid 和 log
pid = /usr/local/php7.3.12/var/run/php-fpm.pid
error_log = /usr/local/php7.3.12/var/log/php-fpm.log

# :wq 保存退出 ################
 
######### 配置 php-fpm.d/www.conf  ################
[root@localhost etc]# vi php-fpm.d/www.conf
 
# 大概 23 行,設置用戶和用戶組爲 nginx
user = nginx
group = nginx
 
# 大概 36 行,監聽端口 9000 
listen = 127.0.0.1:9000

# :wq 保存退出 ################

######### 查找 php-fpm 的系統啓動文件
[root@localhost etc]# find / -name init.d.php-fpm
/package/php-7.3.12/sapi/fpm/init.d.php-fpm
 
####### 複製啓動文件 到 etc/init.d目錄下
[root@localhost etc]# cp /package/php-7.3.12/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
 
############ 配置權限 並添加到自啓動列表
[root@localhost etc]# chmod 755 /etc/init.d/php-fpm
[root@localhost etc]# chkconfig --add php-fpm
[root@localhost etc]# chkconfig php-fpm on
 
########## 配置完畢
[root@localhost etc]# service php-fpm start
Starting php-fpm  done

[root@localhost etc]# php-fpm -m
[PHP Modules]
bcmath
cgi-fcgi
Core
ctype
curl
date
dom
filter
ftp
gd
gettext
hash
hello_world

# 加載 hello_world 拓展成功

使用拓展的函數

編輯一個 test.php 並保存,內容如下

<?php

$test = hello_world_test2();
echo $test;
echo "\r\n";

$str = hello_world_func("daily886 done");
echo $str;
echo "\r\n";

$str2 = hello_world_func();
echo $str2;
~                          

運行 test.php ,拓展運行正常

[root@localhost etc]# php test.php
Hello World
hello world daily886 done!
hello world `]!

 

------------------------------------------------------------

創建拓展參考:

https://www.php.cn/php-weizijiaocheng-392678.html

 

拓展使用參考:

https://www.jianshu.com/p/05616d23c0dc

https://segmentfault.com/a/1190000007575322

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章