PHP内核的学习--创建PHP扩展
PHP内核的学习--创建PHP扩展
PHP取得成功的一个主要原因之一是它拥有大量的可用扩展。web开发者无论有何种需求,这种需求最有可能在PHP发行包里找到。PHP发行包包括支持各种数据库,图形文件格式,压缩,XML技术扩展在内的许多扩展。
扩展API的引入使PHP3取得了巨大的进展,扩展API机制使PHP开发社区很容易的开发出几十种扩展。现在,两个版本过去了,API仍然和PHP3时的非常相似。扩展主要的思想是:尽可能的从扩展编写者那里隐藏PHP的内部机制和脚本引擎本身,仅仅需要开发者熟悉API。
有两个理由需要自己编写PHP扩展。第一个理由是:PHP需要支持一项她还未支持的技术。这通常包括包裹一些现成的C函数库,以便提供PHP接口。例如,如果一个叫FooBase的数据库已推出市场,你需要建立一个PHP扩展帮助你从PHP里调用FooBase的C函数库。这个工作可能仅由一个人完成,然后被整个PHP社区共享(如果你愿意的话)。第二个不是很普遍的理由是:你需要从性能或功能的原因考虑来编写一些商业逻辑。
假设你正在开发一个网站,需要一个把字符串重复n次的函数。下面是用PHP写的例子:
function util_str_repeat($string, $n){
$result = "";
for($i = 0; $i
$result .= $string;
}
return $result;
}
util_str_repeat("One", 3);// returns "OneOneOne".
util_str_repeat("One", 1);// returns "One".
假设由于一些奇怪的原因,你需要时常调用这个函数,而且还要传给函数很长的字符串和大值n。这意味着在脚本里有相当巨大的字符串连接量和内存重新分配过程,以至显著地降低脚本执行速度。如果有一个函数能够更快地分配大量且足够的内存来存放结果字符串,然后把$string重复n次,就不需要在每次循环迭代中分配内存。
为扩展建立函数的第一步是写一个函数定义文件,该函数定义文件定义了扩展对外提供的函数原形。该例中,定义函数只有一行函数原形util_str_repeat() :
string util_str_repeat(string str, int n)
函数定义文件的一般格式是一个函数一行。你可以定义可选参数和使用大量的PHP类型,包括: bool, float, int, array等。
保存为util.def文件至PHP原代码目录树下(即与ext_skel文件放在同一目录下,我的目录是/usr/share/php5/)。
然后就是通过扩展骨架(skeleton)构造器运行函数定义文件的时机了。该构造器脚本就是ext_skel。假设你把函数定义保存在一个叫做util.def的文件里,而且你希望把扩展取名为util,运行下面的命令来建立扩展骨架:
sudo ./ext_skel --extname=util --proto=util.def
执行之后,我这里报了如下错误:
./ext_skel: 1: cd: can't cd to /usr/lib/php5/skeleton
Creating directory util
awk: cannot open /create_stubs (No such file or directory)
Creating basic files: config.m4 config.w32 .svnignore util.c./ext_skel: 216: ./ext_skel: cannot open /skeleton.c: No such file
php_util.h./ext_skel: 234: ./ext_skel: cannot open /php_skeleton.h: No such file
CREDITS./ext_skel: 238: ./ext_skel: cannot open /CREDITS: No such file
EXPERIMENTAL./ext_skel: 242: ./ext_skel: cannot open /EXPERIMENTAL: No such file
tests/001.phpt./ext_skel: 247: ./ext_skel: cannot open /tests/001.phpt: No such file
util.php./ext_skel: 251: ./ext_skel: cannot open /skeleton.php: No such file
rm: cannot remove ‘function_entries’: No such file or directory
rm: cannot remove ‘function_declarations’: No such file or directory
rm: cannot remove ‘function_stubs’: No such file or directory
[done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/util/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-util
5. $ make
6. $ ./php -f ext/util/util.php
7. $ vi ext/util/util.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/util/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
很明显是/usr/lib/php5/skeleton路径的错误,编辑ext_skel文件,将/usr/lib/php5/skeleton修改为/usr/share/php5/skeleton,然后移除掉生成的util文件夹,再次执行之前的命令,成功后提示如下:
Creating directory util
Creating basic files: config.m4 config.w32 .svnignore util.c php_util.h CREDITS EXPERIMENTAL tests/001.phpt util.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/util/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-util
5. $ make
6. $ ./php -f ext/util/util.php
7. $ vi ext/util/util.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/util/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
然后采用静态编译的方式编译扩展。为了使扩展能够被编译,需要修改扩展目录util/下的config.m4文件。扩展没有包裹任何外部的C库,你需要添加支持–enable-util配置开关到PHP编译系统里(–with-extension 开关用于那些需要用户指定相关C库路径的扩展)。找到如下内容:
dnl PHP_ARG_ENABLE(util, whether to enable util support,
dnl Make sure that the comment is aligned:
dnl [ --enable-util Enable util support])
将前面的dnl 去掉,修改为如下结果:
PHP_ARG_ENABLE(util, whether to enable util support,
Make sure that the comment is aligned:
[ --enable-util Enable util support])
然后修改util.c文件,找到如下代码:
PHP_FUNCTION(util_str_repeat)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
long n;
if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE)
return;
php_error(E_WARNING, "util_str_repeat: not yet implemented");
}
将其修改为如下代码:
PHP_FUNCTION(util_str_repeat)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
long n;
char *result; /* Points to resulting string */
char *ptr; /* Points at the next location we want to copy to */
int result_length; /* Length of resulting string */
if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE)
return;
/* Calculate length of result */
result_length = (str_len * n);
/* Allocate memory for result */
result = (char *) emalloc(result_length + 1);
/* Point at the beginning of the result */
ptr = result;
while (n--) {
/* Copy str to the result */
memcpy(ptr, str, str_len);
/* Increment ptr to point at the next position we want to write to */
ptr += str_len;
}
/* Null terminate the result. Always null-terminate your strings
even if they are binary strings */
*ptr = '\0';
/* Return result to the scripting engine without duplicating it*/
RETURN_STRINGL(result, result_length, 0);
}
里面的具体内容,就不在这里说了,之后会慢慢写到。
然后就是编译,安装。在util目录下,命令如下(命令可能都需要加sudo):
phpize
./configure
make
make test
make install
然后配置生成的扩展文件,在php5.5版本中,进入到/etc/php5/mods-available目录下,创建util.ini文件,写入如下内容:
extension=util.so
然后enable util扩展
sudo php5enmod util
最后,重启php-fpm
sudo service php5-fpm restart
创建一个php文件,测试一下,测试文件如下:
for ($i = 1; $i
print util_str_repeat("CraryPrimitiveMan ", $i);
print "\n";
}
?>
执行结果如下:
CraryPrimitiveMan
CraryPrimitiveMan CraryPrimitiveMan
CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan
这样我们就成功创建了一个包含简单的PHP函数的扩展。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在Ubuntu22.04上安裝Linux核心可以按照以下步驟進行操作:更新系統:首先,確保你的Ubuntu系統是最新的,執行以下命令更新系統軟體包:sudoaptupdatesudoaptupgrade下載核心檔案:訪問Linux核心官方網站()下載所需的核心版本。選擇一個穩定版本並下載原始碼檔案(以.tar.gz或.tar.xz為副檔名),例如:wget解壓縮檔:使用下列指令解壓縮下載的核心原始碼檔案:tar-xflinux-5.14.tar. xz安裝建置依賴:安裝建置核心所需的工具和相依性。執

Linux修改核心(kernel)啟動順序一、RHEL6/CentOS6修改核心啟動順序檢視/etc/grub.conf檔案以決定係統核心狀況。根據檔案顯示,系統有兩個核心版本,分別為2.6.32-573.18.1.el6.x86_64和2.6.32-431.23.3.el6.x86_64。核心版本從上到下列出。在grub.conf檔案中,可以透過調整default參數來決定係統啟動時使用哪個核心版本。預設值為0,表示系統將啟動最新的核心版本。值為0對應grub.conf檔案中列出的第一個內

安卓系統究竟是不是基於Linux核心?安卓系統作為目前全球使用最廣泛的行動作業系統之一,一直被稱為基於Linux核心開發的。然而,真正的情況究竟如何呢?讓我們來探討一下這個問題。首先,讓我們來了解Linux核心。 Linux內核作為一個開源的作業系統內核,是由LinusTorvalds於1991年首次發布的。它為許多作業系統提供了良好的基礎,包括And

Linux核心主函數解析與分析Linux核心是一個龐大而複雜的系統,其中的主函數起著至關重要的作用,它是整個系統的入口點,負責初始化各種子系統、驅動程式和核心模組,最終啟動整個作業系統。本文將針對Linux核心主函數進行解析與分析,透過具體的程式碼範例來展示其關鍵功能和執行流程。在Linux核心中,主函數的入口點位於init/main.c檔案中的start_k

標題:探究Linux核心底層所使用的程式語言Linux核心作為一個開源、穩定、可靠的作業系統內核,在電腦領域有廣泛的應用。而要深入了解Linux內核,就不得不涉及其底層所使用的程式語言。事實上,Linux核心主要是用C語言編寫的,這是一個高效、靈活且易於維護的程式語言,非常適合用於作業系統的開發。本文將從細節的角度探討Linux內核底

Linux核心原始碼存放位置詳解Linux核心原始碼是Linux作業系統的核心部分,它包含了作業系統的各種功能的實作程式碼。要了解Linux核心原始碼的存放位置,我們首先需要了解Linux核心的組織結構。 Linux核心原始碼通常存放在/usr/src/linux或/usr/src/linux-目錄下。在這個目錄中,包含了豐

現在比較受歡迎的系統是win10系統了,當然也有正在準備升級的用戶,這些用戶最關心的就是win10比win7效能有提升嗎?其實整體來說還是有一些些提升的,相容性也不錯哦。 win10比win7性能有提升嗎:答:win10比win7性能是有提升的。整體的提升並不是很大,因為性能主要和硬體掛鉤。但是win10系統進行了很多的優化因此可以更好的輔助。而且微軟已經不支援win7的更新了,因此win10將會是後期最常見的系統。 win10比win7對比特色:1、配置:win7已經推出了十幾年的時間了,經過了很多

前言LINUX,這個開源的作業系統,一直以來都在為全球的開發者提供穩定而強大的環境,不論是伺服器,還是嵌入式設備,甚至是超級計算機,Linux都發揮著關鍵的作用,為了滿足不同的需求,我們常常需要對Linux核心進行客製化與安裝,我們就以Debian系統為例,探討如何安裝核心以及核心頭檔。 Debian安裝核心在Debian系統中,安裝新的核心相對直接,可以透過apt指令進行,你需要更新你的套件列表,執行以下指令:```sqlsudoapt-getupdate```你可以使用以下指令來安裝新的內核:s
