PHPには、拡張機能の将来のテンプレート(ワイヤーフレーム)を生成する既製のツール./ext_skel(extフォルダーにあります)があります。 それらによって生成されるすべてとその理由を説明するのではなく(それについて何も理解せず、自分自身も何も知らない)、単にタスクが解決する最小限の編集を書き留めます。 プロセス全体はCentOS 7で行われます。
将来のmathstat拡張のフレームワークを作成します。これには、階乗()関数が含まれます。
[root@localhost ext]# ./ext_skel --extname=mathstat , mathstat. [root@localhost mathstat]# ls config.m4 config.w32 CREDITS EXPERIMENTAL mathstat.c mathstat.php php_mathstat.h tests
create extensionコマンドを実行すると、次のサポート情報が表示されます。
To use your new extension, you will have to execute the following steps: 1. $ cd .. 2. $ vi ext/mathstat/config.m4 3. $ ./buildconf 4. $ ./configure --[with|enable]-mathstat 5. $ make 6. $ ./sapi/cli/php -f ext/mathstat/mathstat.php 7. $ vi ext/mathstat/mathstat.c 8. $ make
PHP7では、生成後のbuildconfファイルはありません(おそらくこれらは以前のバージョンのPHPの残骸です)が、拡張機能のコンパイルはphpizeコマンドで始まることを知っています。 彼女は必要な./configureがあるファイルの束を「作成」します。 拡張機能のコンパイルのカスタムバージョンは、次のコマンドを順番に実行することで構成されていることを思い出してください。
Phpize -> ./configure -> make -> make test -> make install
この一連のコマンドをすぐに実行すると、明らかな理由でmake installが中断し、コピーのエラーが発生します。 誰かが知っているなら、なぜそうなのかをコメントに書き留めてください。
[root@localhost eugene]# make install Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20151012/ cp: cannot stat 'modules/*': No such file or directory make: *** [install-modules] Error 1
Phpizeは、config.m4の説明に基づいてファイルを作成します。 私が理解しているように、これは拡張機能が何であるか、外部ソースをプルアップするかどうかなどを説明する一種の宣言的な方法です...したがって、ソース内の他のPHP拡張機能を見て、ゼロからコンパイルエラーを最小限に抑えるためにできるだけ単純化することにしましたシート。 私は原則に基づいて行動します-「私はすべてのチェックマークを外します。」
このファイル(config.m4)を開き、このテキストのみを残します。 オプション「--enable-mathstat」は、これは単に外部ソース(ライブラリ)のない拡張機能であり、オンまたはオフにできることを示しています。 (dnlは行をコメントすることを意味します)
dnl $Id$ PHP_ARG_ENABLE(mathstat, whether to enable mathstat support, [ --enable-mathstat Enable mathstat support]) if test "$PHP_MATHSTAT" != "no"; then PHP_NEW_EXTENSION(mathstat, mathstat.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) fi
phpizeコマンドを再起動します。
[root@localhost mathstat]# phpize Configuring for: PHP Api Version: 20151012 Zend Module Api No: 20151012 Zend Extension Api No: 320151012 [root@localhost mathstat]# ls acinclude.m4 config.guess configure EXPERIMENTAL mathstat.c php_mathstat.h aclocal.m4 config.h.in configure.in install-sh mathstat.php run-tests.php autom4te.cache config.m4 config.w32 ltmain.sh missing tests build config.sub CREDITS Makefile.global mkinstalldirs
次に、使い慣れたコマンドを作成します。
./configure && make
テストを作成-最初に作成したテストを実行します。 これらのPHPテストについて、私は何らかの形ですでに簡単に書いています。
[root@localhost mathstat]# make install Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20151012/
今回は「make install」に合格し、php.iniに拡張機能を登録しようとします。
php.iniの場所を決定します。
[root@localhost mathstat]# php --ini Configuration File (php.ini) Path: /usr/local/lib Loaded Configuration File: /usr/local/lib/php.ini Scan for additional .ini files in: (none) Additional .ini files parsed: (none) viim /usr/local/lib/php.ini extension=mathstat.so ;zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so [root@localhost mathstat]# systemctl restart php-fpm [root@localhost mathstat]# php -m | grep -i math mathstat
php -mコマンド(インストールされているすべてのモジュールを調べる)は、すべてが正常であるように見え、mathstat拡張機能がロードされていると言います。
現在のディレクトリでmathstat.phpテストファイルを実行します
[root@localhost mathstat]# php mathstat.php Functions available in the test extension: confirm_mathstat_compiled Congratulations! You have successfully modified ext/mathstat/config.m4. Module mathstat is now compiled into PHP. [root@localhost mathstat]#
素晴らしい、何かがすでに機能しています。
2.階乗()関数の実装を開始します。
mathstat.cファイルを編集して、階乗()関数を追加します。
これを行うには、mathstatの「リスト」に関数を追加し、マクロを使用してスタブを作成します。 他の拡張機能と同様に、すべてを類推して行います。
const zend_function_entry mathstat_functions[] = { PHP_FE(confirm_mathstat_compiled, NULL) /* For testing, remove later. */ PHP_FE(factorial, NULL) PHP_FE_END /* Must be the last line in mathstat_functions[] */ };
スタブ関数の実装。 マクロラッパーで作成。 最終的にどのように機能するかはまだ明確ではありません。将来のために研究を自分に任せます。 同様の形式で行うだけです。
PHP_FUNCTION(factorial) { RETURN_LONG(1000); }
この場合、返されるデータのタイプごとに、独自のバージョンはRETURN_です。 インターネットで検索すると、可能なすべてのオプションが表示されます。 私たちには全体的な意味があります。 ここではすべてがシンプルに思えます。
次に、make clean && make && make installを繰り返します
[root@localhost mathstat]# make clean find . -name \*.gcno -o -name \*.gcda | xargs rm -f find . -name \*.lo -o -name \*.o | xargs rm -f find . -name \*.la -o -name \*.a | xargs rm -f find . -name \*.so | xargs rm -f find . -name .libs -a -type d|xargs rm -rf rm -f libphp.la modules/* libs/* Build complete. Don't forget to run 'make test'. [root@localhost mathstat]# make install Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20151012/ [root@localhost mathstat]# systemctl restart php-fpm [root@localhost mathstat]# systemctl status php-fpm ● php-fpm.service - The PHP FastCGI Process Manager Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2016-06-16 01:12:22 EDT; 5s ago Main PID: 32625 (php-fpm) CGroup: /system.slice/php-fpm.service ├─32625 php-fpm: master process (/usr/local/etc/php-fpm.conf) ├─32626 php-fpm: pool www └─32627 php-fpm: pool www Jun 16 01:12:22 localhost.localdomain systemd[1]: Started The PHP FastCGI Process Manager. Jun 16 01:12:22 localhost.localdomain systemd[1]: Starting The PHP FastCGI Process Manager...
php-fpmを再起動しても、何かが壊れていることは示されなかったため、拡張機能で関数の存在をテストしてください。 念のため、コンパイルに合格しても。
[root@localhost mathstat]# php mathstat.php Functions available in the test extension: confirm_mathstat_compiled factorial Congratulations! You have successfully modified ext/mathstat/config.m4. Module mathstat is now compiled into PHP.
関数の名前が表示され、さらに、PHPコードから既に呼び出すことができます。
[root@localhost mathstat]# php -a Interactive mode enabled php > echo factorial(1); 1000 php >
関数が以前に指定された値1000を呼び出して返したことがわかります。
引数を受け取り、それを渡すように関数に教えます。このため、関数の引数の説明を作成する必要があります。 PHPの他の拡張機能の類似点を調べます(bcmathを見ました)。 マクロの束ですが、形式は原則として理解可能です。
ZEND_BEGIN_ARG_INFO(arginfo_factorial, 0) ZEND_ARG_INFO(0, number) ZEND_END_ARG_INFO()
そして、その使用を機能に追加します。 NULLのままにすると、デフォルトはint型の引数型と見なされます。
/* {{{ mathstat_functions[] * * Every user visible function must have an entry in mathstat_functions[]. */ const zend_function_entry mathstat_functions[] = { PHP_FE(confirm_mathstat_compiled, NULL) /* For testing, remove later. */ PHP_FE(factorial, arginfo_factorial) PHP_FE_END /* Must be the last line in mathstat_functions[] */ };
関数の本体をわずかに修正します。
PHP_FUNCTION(factorial) { int argc = ZEND_NUM_ARGS(); long number = 0; if (zend_parse_parameters(argc, "l", &number) == FAILURE) { RETURN_LONG(0); } RETURN_LONG(number); }
zend_parse_parametersを使用します。これは、引用符( "")で囲まれた形式を使用して、渡された型の引数をチェックし、受け入れられた値をアドレスに設定します。 詳細はインターネットで簡単に見つけることができます。 階乗を実装するタスクについては、大きな知識はまだ必要ありません。
再コンパイル後に確認します(make clean && make && make install)。
[root@localhost mathstat]# php -r "echo factorial('80');"; 80[root@localhost mathstat]# php -r "echo factorial(80);"; 80[root@localhost mathstat]#
引数に文字列を渡すと、エラーが発生します。 実際にこれが最後までどのように機能するかはまだ明確ではありませんが、必要なタスクは完了しています。
[root@localhost mathstat]# php -r "echo factorial('aaaa');"; PHP Warning: factorial() expects parameter 1 to be integer, string given in Command line code on line 1 PHP Stack trace: PHP 1. {main}() Command line code:0 PHP 2. factorial() Command line code:1 Warning: factorial() expects parameter 1 to be integer, string given in Command line code on line 1 Call Stack: 0.2040 349464 1. {main}() Command line code:0 0.2040 349464 2. factorial() Command line code:1
関数の本体は充実しているように見えるため、ここで階乗計算アルゴリズム自体を実装します。 ご存知のように、アルゴリズムは再帰呼び出しに基づいています。同じことを行います。 関数compute()の本体を、後続の呼び出しで同じファイルmathstat.cに書き込みます。
static long calculate(long number) { if(number == 0) { return 1; } else { return number * calculate(number - 1); } } PHP_FUNCTION(factorial) { int argc = ZEND_NUM_ARGS(); long number = 0; if (zend_parse_parameters(argc, "l", &number) == FAILURE) { RETURN_LONG(0); } number = calculate(number); RETURN_LONG(number); }
コンパイル、再起動、確認します。
[root@localhost mathstat]# php -a Interactive mode enabled php > echo factorial(1); 1 php > echo factorial(2); 2 php > echo factorial(3); 6 php > echo factorial(4); 24 php > echo factorial(5); 120
驚くべきことに、これは機能します。 PHPですべてがどのように配置されているかについての基本的な知識がなく、C / C ++言語自体が大学から見えなかったため、この関数を実装するには3〜4時間しかかかりませんでした。 コードを記述するプロセス全体は、PHPの何らかのフレームワークでの作業に似ています。 ここで必要なのは、フレームワークとそのAPIのアーキテクチャを研究し、そのフレームワーク内で作業することだけです。
説明されているオプションには特に大きなコードはありませんが、githubへのリンクを残します