PHP 開發效率高,但 CPU 密集型任務 (加密、解析、圖像處理) 性能受限。用 C 實現核心邏輯編譯為 .so 擴展,兼得 PHP 開發便利性與 C 執行效率。本文以「URL 字串轉超鏈接」為例,完整演示從 ext_skel 骨架生成到編譯安裝、調用驗證的全流程。
<?php
function strtolink($url, $name='', $openwin=0){
$name = $name=='' ? $url : $name;
$openwin = $openwin==1 ? ' target="_blank" ' : '';
return '<a href="'.$url.'" '.$openwin.'>'.$name.'</a>';
}
echo strtolink('https://blog.csdn.net/fdipzone', 'fdipzone blog', 1);
?>
ext_skel位於 PHP 源碼目錄 ext/ext_skel (或安裝後 /usr/bin/ext_skel)。
strtolink.skelstring strtolink(string url, string name, int openwin)
./ext_skel --extname=strtolink --proto=strtolink.skel
cd strtolink
config.m4 啟用擴展取消註釋 PHP_ARG_WITH 相關行:
PHP_ARG_WITH(strtolink, for strtolink support,
[ --with-strtolink Include strtolink support])
strtolink.cPHP_FUNCTION(strtolink) {
char *url = NULL, *name = NULL;
int argc = ZEND_NUM_ARGS();
int url_len, name_len;
long openwin = 0;
char *opentag, *result;
// 參數解析:s|sl 表示 url 必填,name/openwin 可選
if (zend_parse_parameters(argc TSRMLS_CC, "s|sl",
&url, &url_len, &name, &name_len, &openwin) == FAILURE) {
return;
}
// 業務邏輯 (與 PHP 版一致)
if (name == NULL || strlen(name) == 0) name = url;
opentag = (openwin == 1) ? " target=\"_blank\"" : "";
// spprintf 安全格式化分配字串
url_len = spprintf(&result, 0, "<a href=\"%s\" %s>%s</a>", url, opentag, name);
// 返回字串 (0 表示由引擎管理內存)
RETURN_STRINGL(result, url_len, 0);
// 佔位警告 (開發階段用,正式版移除)
php_error(E_WARNING, "strtolink: not yet implemented");
}
關鍵 API:zend_parse_parameters 類型映射 (s=string, l=long),spprintf 安全格式化,RETURN_STRINGL 返回二進制安全字串。
phpize
./configure
make
# 若報 PHP_FE_END 未定義 (PHP 版本差異),執行修正:
sed -i 's|PHP_FE_END|{NULL,NULL,NULL}|' strtolink.c
sed -i 's|ZEND_MOD_END|{NULL,NULL,NULL}|' strtolink.c
make clean && make
make test
成功後 modules/strtolink.so 生成。
# 複製到擴展目錄 (phpinfo 查看 extension_dir)
cp modules/strtolink.so /usr/lib/php5/20090626/
# 修改 php.ini 載入
echo 'extension="strtolink.so"' >> /etc/php.ini
# 重啟 Apache/PHP-FPM
service httpd restart
# phpinfo() 驗證出現 strtolink 區塊

圖1 phpinfo 中顯示新擴展
<?php
echo strtolink('https://blog.csdn.net/fdipzone', 'fdipzone blog', 1)."\r\n";
echo strtolink('https://blog.csdn.net/fdipzone', 'fdipzone blog', 0)."\r\n";
echo strtolink('https://blog.csdn.net/fdipzone', 'fdipzone blog')."\r\n";
echo strtolink('https://blog.csdn.net/fdipzone', '', 1)."\r\n";
echo strtolink('https://blog.csdn.net/fdipzone', '')."\r\n";
echo strtolink('https://blog.csdn.net/fdipzone', NULL, NULL)."\r\n";
?>
輸出:正確生成帶/不帶 target、名稱回退 URL 等各種超鏈接 HTML。
| 優點 | 缺點 |
|---|---|
| 極致性能 (C 速度) | 開發調試複雜 (需 C/GDB 技能) |
| PHP 代碼極簡 (直接調用) | 維護成本高 (雙語言上下文切換) |
| 無縫調用第三方 C 庫 | 迭代週期長 (修改→編譯→重啟→驗證) |
適用場景:高頻調用、CPU 密集、依賴 C 庫 (如圖像處理、加解密、協議解析)。不適用:業務邏輯頻繁變更、團隊缺 C 能力、原型驗證階段。
PHP 擴展開發是「以空間換時間、以複雜換性能」的架構決策。掌握 ext_skel、Zend API、編譯鏈、部署流程,能讓你在性能瓶頸面前多一把「C 語言手術刀」。建議先在測試環境完整跑通流程,再評估引入生產。