记录下我写扩展的历程php
自认为会写的更容易理解git
个人宗旨就是 "先用再识" 代码写着写着就知道原理了 或者说边写边学, 边学边写github
C 为啥放第一位?函数
PHP 不会?那写什么PHP扩展?学习
PHP的编译安装debug
phpize 和 php-config 这个靠大家本身去了解了code
关于PHP编译 前期非必须,可是要知道的 (no-debug, non-zts, debug, zts)对象
问?搜? -- 有时候不必定要问或者搜才能找到解决的答案。教程
找! --- 找出别人扩展真么写的 (php-src/ext)。不但有答案,还有思想。开发
至于 PHP ZEND 原理啥的, 很重要, 很重要, 很重要, 可是这里暂时放一边,没事能够去了解了解。
代码说明
这是一个很简单的扩展, 简单到没有功能
扩展名称 laosiji
目前看来 这只是一个只会装B(啥都不会)的司机
三个文件
config.m4
php_laosiji.h
laosiji.c
config.m4
PHP_ARG_ENABLE( laosiji, whether to enable laosiji support, [ --enable-laosiji Enable laosiji support] ) if test "$PHP_LAOSIJI" != "no"; then PHP_NEW_EXTENSION(laosiji, laosiji.c, $ext_shared) fi
php_laosiji.h
#define PHP_LAOSIJI_EXTNAME "laosiji" #define PHP_LAOSIJI_VERSION "1.0.0" // 加载config.h,若是配置了的话 #ifdef HAVE_CONFIG_H #include "config.h" #endif // 加载php头文件 #include "php.h"
laosiji.c
#include "php_laosiji.h" // module entry zend_module_entry laosiji_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_LAOSIJI_EXTNAME, /* 扩展名称 */ NULL, /* Functions */ NULL, /* MINIT */ NULL, /* MSHUTDOWN */ NULL, /* RINIT */ NULL, /* RSHUTDOWN */ NULL, /* MINFO */ #if ZEND_MODULE_API_NO >= 20010901 PHP_LAOSIJI_VERSION, /* 扩展版本 */ #endif STANDARD_MODULE_PROPERTIES}; #ifdef COMPILE_DL_LAOSIJI ZEND_GET_MODULE(laosiji) #endif
phpize
./configure 这里要注意下 php-config
make
make install
加载 .so 扩展文件
<?php var_dump(extension_loaded('laosiji')); // 本身去了解下 dl 函数 // @ 只是为了避免出现那烦人的 提示 // 为了不没必要要的麻烦 建议在 php.ini 加载 扩展 @dl('laosiji.so'); var_dump(extension_loaded('laosiji'));
差很少就到这里了。此次主要说了下写PHP扩展要准备的一些基本知识。固然有些人可能对上面提到部分概念没深刻了解。
好比 PHP不一样编译方式(debug, nts..)<这个你看别的扩展源码的时候就会注意到>、phpize、php-config 具体做用。
phpize、php-config 必定要注意,这里提醒你这回遇到坑。
后面再来慢慢学习老司机的各类姿式。包括,函数,函数参数,函数返回值,对象,类,命名空间等等等。
config.m4
dnl dnl 开头的语句 属于注释内容 dnl PHP_ARG_ENABLE 函数有三个参数 dnl 第一个参数 laosiji 扩展名称 (不用加引号) dnl 第二个参数 运行 ./configure 脚本时显示的内容 dnl 第三个参数 调用 ./configure --help 显示的帮助信息 dnl 最后去了接下 PHP_ARG_WITH 这里就先不提了 PHP_ARG_ENABLE( laosiji, whether to enable laosiji support, [ --enable-laosiji Enable laosiji support] ) if test "$PHP_LAOSIJI" != "no"; then dnl PHP_NEW_EXTENSION 函数声明 扩展的名称、须要的源文件名、扩展的编译形式 dnl 第一个参数 扩展的名称 dnl 第 2 。。 n-1 个参数 须要的源文件名 dnl 最后的$ext_shared参数用来声明这个扩展不是一个静态模块,而是在php运行时动态加载的。 dnl 若是咱们的扩展使用了多个文件,即可以将这多个文件名罗列在函数的参数里,如: dnl PHP_NEW_EXTENSION(laosiji, laosiji.c, laosiji_2.c, laosiji_3.c, $ext_shared) PHP_NEW_EXTENSION(laosiji, laosiji.c, $ext_shared) fi
php_laosiji.h
// 定义 扩展相关的宏 好比版本号 扩展名称等等。。 #define PHP_LAOSIJI_EXTNAME "laosiji" #define PHP_LAOSIJI_VERSION "1.0.0" // 加载config.h,若是配置了的话 #ifdef HAVE_CONFIG_H #include "config.h" #endif // 加载php头文件 // 这个 颇有必要哈 #include "php.h"
laosiji.c
#include "php_laosiji.h" // module entry // 1. laosiji_module_entry 扩展名称_module_entry // 2. PHP_LAOSIJI_EXTNAME /* 扩展名称 */ // 3. PHP_LAOSIJI_VERSION, /* 扩展版本 */ // 那些 NULL ? // 第一个你要记住 /* Functions */ 这行 想一想 php 中的函数 // 第二个你要记住 /* MINIT */ 想一想 class && object // 第三个你要记住 MINIT MSHUTDOWN RINIT RSHUTDOWN MINFO 慢慢来 不着急 zend_module_entry laosiji_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_LAOSIJI_EXTNAME, /* 扩展名称 */ NULL, /* Functions */ NULL, /* MINIT */ NULL, /* MSHUTDOWN */ NULL, /* RINIT */ NULL, /* RSHUTDOWN */ NULL, /* MINFO */ #if ZEND_MODULE_API_NO >= 20010901 PHP_LAOSIJI_VERSION, /* 扩展版本 */ #endif STANDARD_MODULE_PROPERTIES}; #ifdef COMPILE_DL_LAOSIJI ZEND_GET_MODULE(laosiji) #endif