目录大纲
PHP-X
PHP-X是用来开发PHP扩展的库。
安装
1.依赖
# PHP-X本身基于C++11开发,使用cmake进行编译配置。首先,你需要确定所有依赖项已安装好
gcc-4.8 或更高版本
php-7.0 或更高版本,需要php7-dev包
cmake-2.8 或更高版本
2.安装PHP-X
git clone https://github.com/swoole/PHP-X.git
cd PHP-X
cmake .
make -j 4
sudo make install
新建工程
使用任意开发工具,新建一个test.cc源文件。首先需要引入phpx.h头文件。然后使用using引入phpx的命名空间。PHP官方未使用C++,因此phpx直接使用了php作为命名空间。
现成案例
cd example/cpp_test
make install
#创建按 cpp_test.ini
vi cpp_test.ini
###
extension=cpp_ext.so
手动编写扩展文件
vi mingz_ext.cc
#include <phpx.h>
using namespace std;
using namespace php;
//声明函数
PHPX_FUNCTION(cpp_test);
PHPX_EXTENSION()
{
Extension *ext = new Extension("test", "0.0.1");
ext->registerFunction(PHPX_FN(cpp_test));
return ext;
}
//实现函数
PHPX_FUNCTION(cpp_test)
{
//args[1] 就是这个扩展函数的第 2 个参数
long n = args[1].toInt();
//将返回值 retval 初始化为数组
Array _array(retval);
for(int i = 0; i < n; i++)
{
//args[0] 就是这个扩展函数的第 1 个参数
//append 方法表示向数组中追加元素
_array.append(args[0]);
}
}
编写一个Makefile文件
PHP_INCLUDE = `php-config --includes`
PHP_LIBS = `php-config --libs`
PHP_LDFLAGS = `php-config --ldflags`
PHP_INCLUDE_DIR = `php-config --include-dir`
PHP_EXTENSION_DIR = `php-config --extension-dir`
ming_ext.so: ming_ext.cc
c++ -DHAVE_CONFIG_H -g -o ming_ext.so -O0 -fPIC -shared ming_ext.cc -std=c++11 ${PHP_INCLUDE} -I${PHP_INCLUDE_DIR} -lphpx
install: ming_ext.so
cp ming_ext.so ${PHP_EXTENSION_DIR}/
clean:
rm *.so
** 执行make install ***
加载扩展
1 编写ming_ext.ini
extension=cpp_ext.so
2 复制到 /etc/php.d/
cp ming_ext.ini /etc/php.d/
查看扩展
php -m |grep 'ming_test'
执行
1 编写一个test.php,内容为:
var_dump(ming_test("hello", 3));
2 php 执行文件
php test.php
PHP-CPP
PHP-CPP是一个用于开发PHP扩展的C++库。PHP-CPP提供了一系列完善的文档、易于使用和扩展的类,让你可以相对快速的创建PHP的原生扩展。
环境准备
#GCC版本不能太低,因为需要支持c++11特性。我使用的版本:
gcc version 7.2.0
安装PHP-CPP
PHP-CPP区分PHP5和7系列,但是对外提供的API是一样的
git clone https://github.com/CopernicaMarketingSoftware/PHP-CPP.git
make
sudo make install
Hello World
vi main.cpp
代码如下
#include <phpcpp.h>
#include <iostream>
//这是PHP里面可以调用的接口函数
void say_hello()
{
//输出一段欢迎文字
Php::out << "hello world from my first extension" << std::endl;
}
/**
* 告诉编译器get_module是个纯C函数
*/
extern "C" {
/**
* 本函数在PHP进程一打开就会被访问,并返回一个描述扩展信息的PHP结构指针
*/
PHPCPP_EXPORT void *get_module()
{
// 必须是static类型,因为扩展对象需要在PHP进程内常驻内存
static Php::Extension extension("helloworld", "1.0.0");
//这里可以添加你要暴露给PHP调用的函数
extension.add<say_hello>("say_hello");
// 返回扩展对象指针
return extension;
}
}
PHP-CPP库定义了一个PHPCPP_EXPORT宏,它应该放在get_module()函数的前面。此宏确保get_module()函数是公共导出的,因此可由PHP调用。宏具有基于编译器和操作系统的不同实现。
编译
make
sudo make install
编译完成会在源码目录下看到 helloworld.so 这个扩展文件。
创建 helloword.ini
vi helloword.ini
代码如下
extension = helloworld.so
查看扩展
php -m | grep helloworld
测试
vi test.php
代码如下
say_hello();
编写 Makefile文件
#
# Makefile template
#
# This is an example Makefile that can be used by anyone who is building
# his or her own PHP extensions using the PHP-CPP library.
#
# In the top part of this file we have included variables that can be
# altered to fit your configuration, near the bottom the instructions and
# dependencies for the compiler are defined. The deeper you get into this
# file, the less likely it is that you will have to change anything in it.
#
#
# Name of your extension
#
# This is the name of your extension. Based on this extension name, the
# name of the library file (name.so) and the name of the config file (name.ini)
# are automatically generated
#
NAME = helloworld
#
# Php.ini directories
#
# In the past, PHP used a single php.ini configuration file. Today, most
# PHP installations use a conf.d directory that holds a set of config files,
# one for each extension. Use this variable to specify this directory.
#
INI_DIR = /usr/local/php56/etc/php.d/
#
# The extension dirs
#
# This is normally a directory like /usr/lib/php5/20121221 (based on the
# PHP version that you use. We make use of the command line 'php-config'
# instruction to find out what the extension directory is, you can override
# this with a different fixed directory
#
EXTENSION_DIR = $(shell php-config --extension-dir)
#
# The name of the extension and the name of the .ini file
#
# These two variables are based on the name of the extension. We simply add
# a certain extension to them (.so or .ini)
#
EXTENSION = ${NAME}.so
INI = ${NAME}.ini
#
# Compiler
#
# By default, the GNU C++ compiler is used. If you want to use a different
# compiler, you can change that here. You can change this for both the
# compiler (the program that turns the c++ files into object files) and for
# the linker (the program that links all object files into the single .so
# library file. By default, g++ (the GNU C++ compiler) is used for both.
#
COMPILER = g++
LINKER = g++
#
# Compiler and linker flags
#
# This variable holds the flags that are passed to the compiler. By default,
# we include the -O2 flag. This flag tells the compiler to optimize the code,
# but it makes debugging more difficult. So if you're debugging your application,
# you probably want to remove this -O2 flag. At the same time, you can then
# add the -g flag to instruct the compiler to include debug information in
# the library (but this will make the final libphpcpp.so file much bigger, so
# you want to leave that flag out on production servers).
#
# If your extension depends on other libraries (and it does at least depend on
# one: the PHP-CPP library), you should update the LINKER_DEPENDENCIES variable
# with a list of all flags that should be passed to the linker.
#
COMPILER_FLAGS = -Wall -c -O2 -std=c++11 -fpic -o
LINKER_FLAGS = -shared
LINKER_DEPENDENCIES = -lphpcpp
#
# Command to remove files, copy files and create directories.
#
# I've never encountered a *nix environment in which these commands do not work.
# So you can probably leave this as it is
#
RM = rm -f
CP = cp -f
MKDIR = mkdir -p
#
# All source files are simply all *.cpp files found in the current directory
#
# A builtin Makefile macro is used to scan the current directory and find
# all source files. The object files are all compiled versions of the source
# file, with the .cpp extension being replaced by .o.
#
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:%.cpp=%.o)
#
# From here the build instructions start
#
all: ${OBJECTS} ${EXTENSION}
${EXTENSION}: ${OBJECTS}
${LINKER} ${LINKER_FLAGS} -o $@ ${OBJECTS} ${LINKER_DEPENDENCIES}
${OBJECTS}:
${COMPILER} ${COMPILER_FLAGS} $@ ${@:%.o=%.cpp}
install:
${CP} ${EXTENSION} ${EXTENSION_DIR}
${CP} ${INI} ${INI_DIR}
clean:
${RM} ${EXTENSION} ${OBJECTS}