PHP擴充套件開發系列01 – 我要成為一名老司機

JeRuen發表於2019-05-11

PHP擴充套件開發系列01 – 我要成為一名老司機

1. 關於擴充套件的教程貌似挺全了,為啥還寫?

  1. 記錄下我寫擴充套件的歷程

  2. 自認為會寫的更容易理解

  3. 我的宗旨就是 “先用再識” 程式碼寫著寫著就知道原理了 或者說邊寫邊學, 邊學邊寫

2. 那麼你首先要具備哪些預備知識? 答:你需要先過科目一

  1. C 為啥放第一位?

  2. PHP 不會?那寫什麼PHP擴充套件?

  3. PHP的編譯安裝

  4. phpize 和 php-config 這個靠你們自己去了解了

  5. 關於PHP編譯 前期非必須,但是要知道的 (no-debug, non-zts, debug, zts)

  6. 問?搜? — 有時候不一定要問或者搜才能找到解決的答案。

  7. 找! — 找出別人擴充套件真麼寫的 (php-src/ext)。不但有答案,還有思想。

至於 PHP ZEND 原理啥的, 很重要, 很重要, 很重要, 但是這裡暫時放一邊,沒事可以去了解了解。

3. 先看看剛上車的司機是什麼樣的? (示例程式碼) 最後有註釋版的

程式碼說明

  1. 這是一個很簡單的擴充套件, 簡單到沒有功能

  2. 副檔名稱 laosiji

  3. 目前看來 這只是一個只會裝B(啥都不會)的司機

  4. 三個檔案

  5. config.m4

  6. php_laosiji.h

  7. 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

5. 作為司機的一本基本開車動作 (擴充套件的編譯安裝等)

  1. phpize

  2. ./configure 這裡要注意下 php-config

  3. make

  4. make install

  5. 載入 .so 擴充套件檔案

6. 點火啟動 試試我們的擴充套件

<?php
var_dump(extension_loaded(`laosiji`));

// 自己去了解下 dl 函式
// @ 只是為了不出現那煩人的 提示
// 為了避免不必要的麻煩 建議在 php.ini 載入 擴充套件
@dl(`laosiji.so`);

var_dump(extension_loaded(`laosiji`));

7. 小節

差不多就到這裡了。這次主要說了下寫PHP擴充套件要準備的一些基本知識。當然有些人可能對上面提到部分概念沒深入瞭解。
比如 PHP不同編譯方式(debug, nts..)<這個你看別的擴充套件原始碼的時候就會注意到>、phpize、php-config 具體作用。
phpize、php-config 一定要注意,這裡提醒你這回遇到坑。

後面再來慢慢學習老司機的各種姿勢。包括,函式,函式引數,函式返回值,物件,類,名稱空間等等等。

8. 註釋版程式碼

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

參考

簡單擴充套件 https://github.com/imlaosiji/…

相關文章