記錄下我寫擴展的歷程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