PHP拡張の拡張関数におけるパラメータの受け渡し例とパラメータの取得例を詳しく解説
はじめに
前回の記事でphp拡張機能の拡張フレームワークを自動生成したことで、php拡張機能のフレームワークについては基本的にはある程度理解できたといえます。と重要なポイントは説明しましたが、やはり重要なのは PHP_FUNCTION の関数をどのように記述するかです。
この記事では主に、PHP が拡張機能を呼び出すときにパラメーターを渡す方法と、拡張機能が呼び出しを受け取る方法を記録します。自分のメモとして
テキスト
1. zend_parse_parameters
関数によって渡されるパラメータを取得するには、zend_parse_parameters 関数を使用できます。注意してください。公式に生成されたデフォルト関数もこの関数を使用してパラメータを受け取ります。 この機能の使い方は? まず、この本はPHPのscanfのように読んで使えます。 (この関数に詳しくない方は、こちらからお読みください)zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, &参数1,&参数2…);
対応するCの型 | 説明 | |
---|---|---|
long | 符号付き整数 | |
double | 浮動小数点 | |
char *, int | バイナリ文字列、length | |
zend_ bool | 論理型 (1 または ) 任意の型オブジェクトの | |
zval * | 指定されたタイプのオブジェクト。対象オブジェクトのクラス型を指定する必要があります | |
zval * | zval を何も操作せずに指定する必要があります | |
ここで特に注意が必要な点が2つあります | 1に対応するc型は2つあります。ここのパラメータは文字列型です。はい。これは、zend_parse_parameters() 関数を使用する場合、次のように使用する必要があることを示しています:zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len) ログイン後にコピー | 1 つは文字列の内容を表し、もう 1 つは文字列の長さを表します。 2. zval とは何ですか? |
ps: typedef については説明しません。すでに誰かが非常にうまく書いているので、typedef の使用法の概要をクリックしてください | これにも 3 つのことが含まれます。パラメーターを受信する機能を強化するには: | |
| | その前のパラメーターはすべて必要であり、その後のパラメーターは必要ありません。デフォルト値があります。 |
/
渡された変数が他の変数と zval を共有し、参照ではない場合、新しい zval の is_ref__gc==0 と refcount__gc==1.
“|”和”!”将在下文有具体例子讲解,关于”/”虽然大概懂意思,但没想到具体的例子。
走一波与php的交互
正常的样子
在PHP中
<?phpfunction my_function($msg) { echo "我收到参数啦: {$msg}!\n"; } my_function('咖啡色的羊驼');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *msg; int msg_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&msg, &msg_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(msg, msg_len); php_printf("!\n"); }
两个参数的样子
在PHP中
<?phpfunction my_function($email, $msg) { echo "我收到参数啦: {$email}、 {$msg}!\n"; } my_function('123456@qq.com', '咖啡色的羊驼');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *email; int email_len; char *msg; int msg_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&msg, &msg_len,&email, &email_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(email, email_len); PHPWRITE(msg, msg_len); php_printf("!\n"); }
两个参数,其中一个可选且有默认值
<?phpfunction my_function($email, $msg = '咖啡色的羊驼') { echo "我收到参数啦: {$email}、 {$msg}!\n"; } my_function('123456@qq.com');
如果my_function写成PHP扩展:
ZEND_FUNCTION(my_function) { char *email; int email_len; char *msg = "咖啡色的羊驼"; int msg_len = sizeof("咖啡色的羊驼") - 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",&msg, &msg_len,&email, &email_len) == FAILURE){ RETURN_NULL(); } php_printf("我收到参数啦:"); PHPWRITE(email, email_len); PHPWRITE(msg, msg_len); php_printf("!\n"); }
这里说明了”|”的使用
参数为null时,省内存的写法
先来不省的写法
ZEND_FUNCTION(my_function) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&val) == FAILURE) { RETURN_NULL(); } }
省内存
ZEND_FUNCTION(my_function) { zval *val; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!",&val) == FAILURE) { RETURN_NULL(); } }
这里例子用上了”!”,每个zval,包括IS_NULL型的zval,都需要占用一定的内存空间,需要cpu的计算资源来为它申请内存、初始化,并在它们完成工作后释放掉。但是很多代码都都没有意识到这一点。有很多代码都会把一个null型的值包裹成zval的IS_NULL类型,在扩展开发里这种操作是可以优化的,我们可以把参数接收成C语言里的NULL。
所以就差了一个!,第二个例子就更省了内存。
2.zend_get_arguments()
用法
例子是最好的用法讲解,上例子:
ZEND_FUNCTION(my_function) { zval *email; if (zend_get_parameters(ZEND_NUM_ARGS(), 1, &email)== FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"至少需要一个参数"); RETURN_NULL(); } // ... }
区别与特点
1.能够兼容老版本的PHP,并且只以zval为载体来接收参数。
2.直接获取,而不做解析,不会进行类型转换,所有的参数在扩展实现中的载体都需要是zval类型的。
3.接受失败的时候,不会自己抛出错误,也不能方便的处理有默认值的参数。
4.会自动的把所有符合copy-on-write的zval进行强制分离,生成一个崭新的copy送到函数内部。
综合评价:还是用zend_parse_parameters吧,这个函数了解下即可,不给力。
3.zend_get_parameters_ex()
用法
ZEND_FUNCTION(my_function) { zval **msg; if (zend_get_parameters_ex(1, &msg) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"至少需要一个参数"); RETURN_NULL(); } // ...}
不需要ZEND_NUM_ARGS()作为参数,因为它是在是在后期加入的,那个参数已经不再需要了。
区别与特点
1.此函数基本同zend_get_parameters()。
2.唯一不同的是它不会自动的把所有符合copy-on-write的zval进行强制分离,会用到老的zval的特性
综合评价:极端情况下可能会用到,这个函数了解下即可。
zend_get_parameter_**
这个包括:zend_get_parameters_array_ex()和zend_get_parameters_array()
用法
ZEND_FUNCTION(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); WRONG_PARAM_COUNT; } for (i=0; i<argc; i++) { php_var_dump(args[i], 1 TSRMLS_CC); } efree(args); }
这个有点复杂,需要解释一下:
程序首先获取参数数量,然后通过safe_emalloc函数申请了相应大小的内存来存放这些zval**类型的参数。这里使用了zend_get_parameters_array_ex()函数来把传递给函数的参数填充到args中。
是的
这个参数专门用于解决像php里面的var_dump的一样,可以无限传参数进去的函数的实现
区别与特点
1.用于应对无限参数的扩展函数的实现。
2.zend_get_parameters_array与zend_get_parameters_array_ex唯一不同的是它将zval*类型的参数填充到args中,并且需要ZEND_NUM_ARGS()作为参数。
综合评价:当遇到确实需要处理无限参数的时候,真的要用这个函数了。zend_parse_parameters真的做不到啊~
总结
抛开一切,最少也要学会zend_parse_parameters()的用法。好的。扩展函数传参数的技能get了。
以上がPHP拡張の拡張関数におけるパラメータの受け渡し例とパラメータの取得例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホット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)

ホットトピック











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

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

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

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

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

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用して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で後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

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