ホームページ バックエンド開発 PHPチュートリアル PHP拡張関数のパラメータの記述

PHP拡張関数のパラメータの記述

Dec 07, 2016 pm 03:27 PM
php

関数のパラメータ
関数の呼び出し元によって渡されたパラメータを取得する最も簡単な方法は、zend_parse_parameters() 関数を使用することです。カーネル内のマクロを使用して、zend_parse_parameters() 関数の最初のいくつかのパラメータを ZEND_NUM_ARGS() TSRMLS_CC の形式で直接生成できます。2 つの間にはスペースがありますが、コンマはありません。名前からわかるように、ZEND_NUM_ARGS() はパラメータの数を表します。 zend_parse_parameters() 関数に渡す必要がある次のパラメータは、printf の最初のパラメータと同様に、フォーマットに使用される文字列です。最も一般的に使用される記号のいくつかを以下に示します。
type_spec はフォーマット文字列で、一般的な意味は次のとおりです:
Parameter は型を表します
b ブール型
l Integer 整数型
d 浮動小数点浮動小数点型
s String 文字列
r リソース リソース
a Array 配列
o オブジェクト インスタンスオブジェクト
O 指定された型のオブジェクト インスタンス 特定の型のオブジェクト
z 非指定 zval 任意の型 ~
Z zval** 型
f 関数名やメソッド名を表す PHP5.1 ではそのようなものはないようです。 .. .. .
この関数は、printf() 関数と同様に、フォーマット文字列のフォーマットに 1 対 1 で対応します。一部の基本的なデータ型は、C 言語の型に直接マッピングされます。
ZEND_FUNCTION(sample_getlong) {

long foo;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"l", &foo) == FAILURE)
{ RETURN_NULL()
}
php_printf("パラメータは: %ldn", foo);
RETURN_TRUE;
}
一般的に、int と long の 2 つのデータ型のデータは同じであることが多いですが、例外もあります。したがって、特に 64 ビット プラットフォームでは、long 配列を int に入れるべきではありません。トラブルシューティングが難しいいくつかのバグが発生する可能性があります。したがって、zend_parse_parameter() 関数を通じてパラメータを受け取るときは、カーネルによってキャリアとして合意された型の変数を使用する必要があります。
パラメータはCのデータ型に対応します
b zend_bool
l long
d double
s char*, int 前者はポインタを受け取り、後者は長さを受け取ります
r zval*
a zval*
o zval*
O zval *, zend_class_entry*
z zval*
Z zval**
PHP 言語のすべての複合型パラメータは、カーネルによってカスタマイズされたデータ構造であるため、キャリアとして zval* 型を必要とすることに注意してください。パラメーターの型とキャリアが一貫していることを確認する必要があります。必要に応じて、配列を stdClass オブジェクトに変換するなど、型変換を実行できます。 s タイプと O (ヨーロッパの大文字) タイプは、両方とも 2 つのキャリアを必要とするため、別々に記述する必要があります。次の章では、PHP でのオブジェクトの具体的な実装について学習します。それでは、第 5 章で定義した関数を書き直してみましょう:
function sample_hello_world($name) {
echo "Hello $name!n"
}
拡張機能を記述するときは、zend_parse_parameters( ) を使用する必要があります。次の文字列を受け取ります:
ZEND_FUNCTION(sample_hello_world) {
char *name;
int name_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len) == FAILURE)
{
RETURN_NULL( ; 実行失敗し、FAILURE が返されます。
複数のパラメータを受信する必要がある場合は、次のように zend_parse_paramenters() のパラメータに受信キャリアを直接リストすることができます:
function sample_hello_world($name, $greeting) {
echo "Hello $greeting $ name!n";
}
sample_hello_world('John Smith', 'Mr.');
これは PHP 拡張機能で実装する必要があります:
ZEND_FUNCTION(sample_hello_world) {
char *name;
int name_len;
char *greeting ;
挨拶文
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&name, &name_len, &greeting, &greeting_len) == FAILURE) {
ITE(greeting,greeting_len);
php_printf(" ");
PHPWRITE(name, name_len); php_printf("!n");
}
上記で定義されたパラメータに加えて、パラメータを受け取る機能を強化するために次の 3 つのパラメータがあります。
型修飾子の意味
|その後のパラメータはオプションです。つまり、デフォルト値があります。
! PHP 言語で null 変数を受け取った場合、IS_NULL 型の zval にカプセル化するのではなく、C 言語で直接 NULL に変換されます。
/ 渡された変数が他の変数と zval を共有し、参照ではない場合、新しい zval の is_ref__gc==0 と refcount__gc==1 が強制的に分離されます。続けて、sample_hello_world() を書き換えます。次に、いくつかのパラメータのデフォルト値を使用します。これは、PHP 言語で次のようになります。 ') {
echo "Hello $greeting $name!n";
}
sample_hello_world('Ginger Rogers','Ms.');
現時点では、1 つだけ渡すことができます。パラメータをsample_hello_worldに渡すことも、2つのパラメータ全体を渡すこともできます。 では、同じ機能を拡張関数に実装するにはどうすればよいでしょうか? zend_parse_parameters では (|) パラメータを使用する必要があります。このパラメータの前のパラメータは必須とみなされ、このパラメータが渡されない場合、キャリアは変更されません。
ZEND_FUNCTION(sample_hello_world) {
char *name;
int name_len;
char *greeting = "Mr./Mrs."


if ( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
&name, &name_len, &greeting, &greeting_len) == FAILURE) {
RETURN_NULL()
}
php_printf("Hello "); );
php_printf(" ");
PHPWRITE(name, name_len);
php_printf("!n");
}
2 番目のパラメータを渡さない場合、拡張関数はキャリアを変更せずにデフォルトとみなされます。したがって、キャリアの値を自分で事前に設定する必要があります。多くの場合、これは NULL または関数ロジックに関連する値です。 IS_NULL タイプの zval を含む各 zval は、一定量のメモリ空間を占有する必要があり、CPU コンピューティング リソースがそれにメモリを適用し、初期化し、作業完了後に解放する必要があります。しかし、多くのコードはこれを認識していません。 null 値を zval の IS_NULL 型にラップするコードは数多くありますが、この操作は C 言語でパラメータを NULL として受け取ることができるため、拡張開発で最適化できます。この問題に関する次のコードを見てみましょう:
Zend_function(sample_arg_fullnull){zval *val; if (Z_TYPE_P(val) == IS_NULL) {
val = php_sample_make_defaultval(TSRMLS_C); }
...
}
ZEND_FUNCTION(sample_arg_nullok) {
zval *val; UM_ARGS() TSRMLS_CC, "z !」、
val(TSRMLS_C);2 つのコードは一見するとあまり違いがありませんが、最初のコードはより多くの CPU とメモリ リソースを必要とします。もしかしたらこのテクニックは普段はあまり役に立たないかもしれませんが、知らないよりは知っていた方が良いです。

強制分離
変数が関数に渡されると、それが参照されているかどうかに関係なく、その refcoung__gc 属性は 1 つ増加し、少なくとも 2 になります。 1 つのコピーはそれ自体であり、もう 1 つは関数に渡されるコピーです。この zval を変更する前に、事前に実際の 2 つのコピーに分割する必要がある場合があります。これは「/」フォーマット文字の役割です。これにより、コピーオンライト zval が事前に 2 つの完全な独立したコピーに分割されるため、次のコードで自由に操作できるようになります。そうしないと、受け取ったパラメータとその他の操作を分離することを常に自分自身に思い出させる必要があるかもしれません。 NULL フラグと同様に、この修飾子は影響を与える型の後に続きます。また、NULL フラグと同様に、この機能が必要かどうかは、実際に使用するまでわかりません。拡張機能が古いバージョンの PHP と互換性があるか、パラメータを受信するキャリアとして zval のみを使用したい場合は、zend_get_parameters() 関数を使用してパラメータを受信することを検討できます。 zend_get_parameters() は zend_parse_parameters() とは異なり、解析せずに直接取得します。まず、拡張実装のすべてのパラメーターのキャリアは zval 型である必要があります。
ZEND_FUNCTION(sample_onearg) {
zval *firstarg; firstarg.. . */
}
第二に、zend_get_parameters() は、受信が失敗したときに単独でエラーをスローすることはなく、デフォルト値のパラメーターを適切に処理することもできません。 最後の点は、コピーオンライトに準拠するすべての zval を自動的に強制的に分離し、新しいコピーを生成して関数に送信するという点で、zend_parse_parameters とは異なります。他の機能を使用したいが、この関数は必要ない場合は、zend_get_parameters_ex() 関数を使用してパラメータを受け取ることができます。 コピーオンライトの変数を分離しないように、zend_get_parameters_ex() のパラメータは zval* ではなく zval** 型になります。 この関数は、極端な問題が発生した場合にのみ使用される可能性がありますが、使い方は非常に簡単です。
zval **firstarg;
if (zend_get_parameters_ex(1, &firstarg)) == FAILURE) {
WRONG_PARAM_COUNT;
}
/* firstarg で何かを行う... */
}
zend_get_parameters_ex は後の段階で追加されるため、パラメータとして ZEND_NUM_ARGS() を必要としないことに注意してください。すでにNo moreになっています。
WRONG_PARAM_COUNT マクロは、上記の例でも使用されており、その機能は E_WARNING レベルのエラー メッセージをスローし、それを自動的に返すことです。

変数パラメーター
他に 2 つの zend_get_parameter_** 関数があります。これらは、多くのパラメーターの問題、または事前にパラメーターの数がわからない問題を解決するために特別に使用されます。 PHP 言語での var_dump() 関数の使用法を考えてみましょう。カーネルでのその実装は実際には次のようになります:
int i, argc = ZEND_NUM_ARGS() ;
zval ***args;

args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
if (ZEND_NUM_ARGS() == 0 || zend_get_parameters_array_ex(argc, args) = = FAILURE ] }
efree(args);
}
プログラムは最初にパラメータの数を取得し、次に、safe_emalloc 関数を通じて対応するサイズのメモリを適用して、これらの zval** 型パラメータを保存します。ここでは、zend_get_parameters_array_ex() 関数を使用して、関数に渡されたパラメータを args に埋め込みます。 zend_get_parameters_array() という関数もあるとすぐに思ったかもしれませんが、唯一の違いは、zval* 型パラメータを args に入力し、パラメータとして ZEND_NUM_ARGS() を必要とすることです。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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 および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles