目次
PHP内核的学习--创建PHP扩展
ホームページ php教程 php手册 PHP内核的学习--创建PHP扩展

PHP内核的学习--创建PHP扩展

Jun 13, 2016 am 09:07 AM
カーネル

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函数的扩展。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Ubuntu 22.04 に Linux カーネルをインストールする方法 詳細なチュートリアル! Ubuntu 22.04 に Linux カーネルをインストールする方法 詳細なチュートリアル! Mar 01, 2024 pm 10:34 PM

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

Linux カーネルの起動シーケンスを変更する Linux カーネルの起動シーケンスを変更する Feb 23, 2024 pm 10:22 PM

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 システムは Linux カーネルに基づいていますか? Mar 14, 2024 pm 03:12 PM

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

Linuxカーネルの主な機能解析と解析 Linuxカーネルの主な機能解析と解析 Mar 14, 2024 am 11:27 AM

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

Linux カーネルの内部で使用されるプログラミング言語を探索する Linux カーネルの内部で使用されるプログラミング言語を探索する Mar 20, 2024 am 08:06 AM

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

Linuxカーネルのソースコード格納場所の詳細説明 Linuxカーネルのソースコード格納場所の詳細説明 Mar 14, 2024 pm 06:12 PM

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

Ubuntu のコンパイルとインストール カーネルのチュートリアル。 Ubuntu のコンパイルとインストール カーネルのチュートリアル。 Feb 19, 2024 pm 02:54 PM

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

win10のパフォーマンスはwin7と比べて向上していますか? 詳しい紹介 win10のパフォーマンスはwin7と比べて向上していますか? 詳しい紹介 Dec 23, 2023 am 09:04 AM

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

See all articles