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 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Linux カーネルを Ubuntu22.04 にインストールするには、次の手順に従います。 システムを更新します。 まず、Ubuntu システムが最新であることを確認し、次のコマンドを実行してシステム パッケージを更新します。 sudoaptupdatesudoaptupgrade カーネル ファイルをダウンロードします。公式 Linux カーネル Web サイト () から必要なカーネル バージョンをダウンロードします。安定したバージョンを選択し、ソース コード ファイル (.tar.gz または .tar.xz 拡張子付き) をダウンロードします。例: wget ファイルを解凍します。次のコマンドを使用して、ダウンロードしたカーネル ソース コード ファイルを解凍します: tar-xflinux-5.14 .tar.xz ビルドの依存関係をインストールする: カーネルのビルドに必要なツールと依存関係をインストールします。実行する

Linux のカーネル起動シーケンスの変更 1. RHEL6/CentOS6 のカーネル起動シーケンスの変更 /etc/grub.conf ファイルを確認して、システムのカーネルの状況を確認します。ドキュメントによると、システムには 2.6.32-573.18.1.el6.x86_64 と 2.6.32-431.23.3.el6.x86_64 という 2 つのカーネル バージョンがあります。カーネルのバージョンは上から下にリストされています。 grub.conf ファイルでは、デフォルトのパラメータを調整することで、システムの起動時に使用するカーネルのバージョンを決定できます。デフォルト値は 0 で、システムが最新のカーネル バージョンを起動することを意味します。値 0 は、grub.conf ファイルにリストされている最初のコンテンツに対応します。

Android システムは Linux カーネルに基づいていますか? Android システムは、世界で最も広く使用されているモバイル オペレーティング システムの 1 つであり、常に Linux カーネルに基づいて開発されていると言われています。しかし、実際の状況はどうなのでしょうか?この問題について調べてみましょう。まず、Linux カーネルについて理解しましょう。 Linux カーネルは、オープン ソース オペレーティング システム カーネルとして、1991 年に Linus Torvalds によって初めてリリースされました。これは、And を含む多くのオペレーティング システムに優れた基盤を提供します。

Linux カーネルの main 関数の分析と分析 Linux カーネルは大規模で複雑なシステムであり、main 関数は重要な役割を果たします。システム全体のエントリ ポイントであり、さまざまなサブシステム、ドライバー、カーネル モジュールの初期化を担当します。オペレーティング システム全体を起動します。この記事では、Linux カーネルの主な機能を分析して、その主要な機能と実行フローを具体的なコード例を通じて示します。 Linux カーネルでは、main 関数のエントリ ポイントは init/main.c ファイルの start_k です。

タイトル: Linux カーネルの底部で使用されるプログラミング言語の探索 Linux カーネルは、オープンソースで安定した信頼性の高いオペレーティング システム カーネルとして、コンピュータ分野で幅広い用途に使用されています。 Linux カーネルを深く理解するには、一番下で使用されるプログラミング言語を関与させる必要があります。実際、Linux カーネルは主に C 言語で書かれています。C 言語は効率的で柔軟性があり、保守が容易なプログラミング言語であり、オペレーティング システムの開発に非常に適しています。この記事では、Linux カーネルの底部を詳細な観点から探っていきます。

Linux カーネル ソース コードの格納場所の詳細な説明 Linux カーネル ソース コードは、Linux オペレーティング システムの中核部分であり、オペレーティング システムのさまざまな機能の実装コードが含まれています。 Linux カーネルのソース コードがどこに保存されているかを理解するには、まず Linux カーネルの組織構造を理解する必要があります。 Linux カーネルのソース コードは通常、/usr/src/linux または /usr/src/linux- ディレクトリに保存されます。このディレクトリには、たくさんの

Ubuntu カーネルのコンパイルとインストールには、特定の専門スキルと実務経験が必要です。一般的な手順は次のとおりですが、このプロセスには特定のリスクが伴う可能性があるため、注意して続行してください。始める前に、重要なデータとシステムを必ずバックアップしてください。ソース コードを入手する: Ubuntu 公式 Web サイト () またはカーネル開発者の Web サイト () にアクセスして、最新のカーネル ソース コードをダウンロードします。ソース コードを /usr/src などの適切なディレクトリに解凍します。コンパイルの依存関係をインストールする: カーネルの構築に必要な依存関係をインストールします。ターミナルを開き、次のコマンドを実行します: sudoapt-getinstallbuild-essentiallibncurses-devbisonflexlibssl-devlibelf-d

現在最も人気のあるシステムは win10 システムですが、もちろんアップグレードの準備をしているユーザーもいますが、そのようなユーザーが最も懸念しているのは win10 のパフォーマンスが win7 と比較して向上しているかどうかです。実際、全体的にはまだ改善の余地があり、互換性も良好です。 win10 のパフォーマンスは win7 と比較して向上していますか? 回答: win10 のパフォーマンスは win7 と比較して向上しています。パフォーマンスは主にハードウェアに関連しているため、全体的な改善はそれほど大きくありません。ただし、Win10 システムは多くの最適化が行われているため、より優れた支援を提供できます。さらに、Microsoft は win7 アップデートをサポートしなくなったため、将来的には win10 が最も一般的なシステムになるでしょう。 win10 と win7 の比較機能: 1. 構成: win7 は発売されてから 10 年以上が経過し、多くのことを経てきました。
