目次
型ヒントの実装
ホームページ バックエンド開発 PHPチュートリアル タイプヒントの実装_PHP チュートリアル

タイプヒントの実装_PHP チュートリアル

Jul 13, 2016 am 10:05 AM
タイプ

型ヒントの実装

PHP は型指定が弱い言語であり、メソッドにパラメーターを渡すときにデータ型が厳密にチェックされません。 ただし、メソッドに渡されるパラメーターを決定する必要がある場合があります。このため、PHP にはデータの種類を決定するための関数がいくつか用意されています。 たとえば、is_numeric() は、それが数値であるか、またはオブジェクト (instanceof) を決定するために使用される型演算子など、数値に変換できる文字列であるかを決定します。 instanceof は、特定のオブジェクトが指定されたオブジェクト クラスに由来するかどうかを判断するために使用されます。 instanceof 演算子は PHP 5 で導入されました。 これまでは is_a() が使用されていましたが、現在はその使用は推奨されていません。
非標準のオブジェクト型によって引き起こされる問題を回避するために、PHP5 では型ヒントの概念が導入されました。メソッドのパラメータを定義するときは、パラメータのオブジェクト タイプも定義します。 受信パラメータの型が、呼び出し時に定義されたパラメータの型と一致しない場合、エラーが報告されます。このようにして、オブジェクトの種類をフィルタリングしたり、データのセキュリティを保証したりできます。
PHP の型ヒント関数は、パラメーターがオブジェクトであるヒントにのみ使用できますが、整数、文字列、浮動小数点などの型ヒントには使用できません。 PHP5.1 以降、PHP は配列の型ヒントをサポートします。
型ヒントを使用するには、メソッド (または関数) のオブジェクト型パラメーターの前に既存のクラスの名前を追加するだけで、オブジェクト型だけでなく、抽象クラスやインターフェイスも指定できます。
配列の型ヒントの例:
関数 array_print(Array $arr) {
print_r($arr);}
array_print(1);
上記のコードには問題があり、今回紹介したタイプヒントがPHP5.1以降のバージョンで実行されると以下のエラーが報告されます。
キャッチ可能な致命的なエラー: array_print() に渡される引数 1 は配列である必要があります。
整数が与えられ、呼び出されました...
関数パラメータの整数変数を配列に変更すると、プログラムは通常どおり実行され、print_r 関数を呼び出して配列を出力します。 では、このタイプヒントはどのように実装されるのでしょうか? クラス内のメソッドであっても、呼び出す関数であっても、関数キーワードはその宣言のマークとして使用され、パラメーターの型は関数の宣言に関連しています。宣言の時刻ですが、呼び出されたときにのみ表示されます。 ここでは、タイプヒントの実装を 2 つの側面から説明します:
パラメータ宣言時の入力ヒント
関数またはメソッドを呼び出すときの入力ヒント
今の例を変更します:
関数 array_print(Array $arr = 1) {
print_r($arr);}
array_print(array(1));
前の例と比較すると、このコードは関数パラメータのデフォルト値を設定しますが、このデフォルト値は整数変数であり、パラメータによって与えられる型ヒント配列とは異なります。したがって、このコードを実行するとすぐに設定されます。プログラムが次のようにエラーを報告することを確認してください:
致命的なエラー: 配列型ヒントを含むパラメーターのデフォルト値
配列または NULL のみを指定できます
なぜすぐにエラーが表示されるのですか? デフォルト値の検出処理は中間コード生成段階で発生するため、実行時のエラー報告とは異なり、まだ中間コードが生成されておらず、中間コードを実行する処理もありません。 Zend/zend_ language_parser.y ファイルでは、関数のパラメータ リストがコンパイル時に zend_do_receive_arg 関数を呼び出すことがわかります。 この関数のパラメーター リストの 5 番目のパラメーター (znode *class_type) は、このセクションで説明する型ヒントと密接に関連しています。 このパラメーターの機能は、型ヒントで型を宣言することです。ここには 3 つの型があります。
空、つまりタイプヒントがありません
クラス名、ユーザー定義またはPHPでカスタマイズされたクラス、インターフェースなど
配列、コンパイル中に対応するトークンは T_ARRAY であり、配列文字列です
zend_do_receive_arg 関数では、基本的に上記の 3 つのタイプのクラス名に対して、class_type パラメーターに対して一連の操作が実行されます。存在しないクラスを使用した場合でも、プログラムはクラスが存在するかどうかを判断しません。クラス名。プログラムがエラーを報告すると、実パラメータで指定されたオブジェクトが指定されたクラスのインスタンスではないことも表示されます。
上記は型ヒントの宣言とその宣言過程でのパラメータのデフォルト値の判定の処理です。 次に、関数やメソッドを呼び出す際の型ヒントの実装を見てみましょう。
上記の宣言プロセスから、型ヒントに関連するコードをコンパイルするときに、PHP が Zend/zend_complie.c ファイル内の zend_do_receive_arg 関数を呼び出すことがわかります。この関数では、型ヒント判定のオペコードに値 ZEND_RECV が割り当てられます。オペコードのマッピング計算規則によれば、実行中に ZEND_RECV_SPEC_HANDLER が呼び出されることがわかります。 コードは次のとおりです:
static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS){
...//省略
if (param == NULL) {
char *space;
char *class_name = get_active_class_name(&space TSRMLS_CC);
zend_execute_data *ptr = EX(prev_execute_data);
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
…//省略
}
…//省略
} else {
…//省略
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
…//省略
}
...//省略}
上に示すように、ZEND_RECV_SPEC_HANDLER の最後の呼び出しは zend_verify_arg_type です。コードは次のとおりです:
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC){
...//省略
if (cur_arg_info->class_name) {
const char *クラス名;
if (!arg) {
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC) を返す;
}
if (Z_TYPE_P(arg) == IS_OBJECT) { // クラスオブジェクトパラメータであるため、渡されるパラメータはオブジェクトタイプである必要があります
// 次に、このオブジェクトがパラメータ プロンプト クラスのインスタンス オブジェクトであるかどうかを確認します。ここでは、サブクラス インスタンス オブジェクトを渡すことが許可されています
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
return zend_verify_arg_error(zf, arg_num, info, need_msg, class_name, "のインスタンス", Z_OBJCE_P(arg)->name TSRMLS_CC);
}
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { // パラメータは NULL ですが、これもチェックに合格します。
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC) を返します。
}
} else if (cur_arg_info->array_type_hint) { // 配列
if (!arg) {
ZEND_VERIFY_ARG_ERROR (ZF, ARG_NUM, CUR_ARG_INFO, "配列であること", "", "なし", "TSRMLS_CC)" を返します。
}
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
ZEND_VERIFY_ARG_ERROR (ZF, ARG_NUM, Cur_ARG_INFO, "配列であること", "", ZEND_ZVAL_TYPE_NAME (ARG), "TSRMLS_CC); を返します。
}
}
1 を返します;}
zend_verify_arg_type のプロセス全体を図 3.1 に示します。
図3.1 タイプ即時判定フローチャート
型ヒントがエラーを報告する場合、zend_verify_arg_type 関数は最終的に zend_verify_arg_class_kind を呼び出してエラー メッセージを生成し、zend_verify_arg_error を呼び出してエラーを報告します。コードは次のとおりです:
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC){
*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
*クラス名 = (*pce) ? (*pce)->名前: cur_arg_info->クラス名;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
return "インターフェースを実装";
} 他 {
return "のインスタンスになる;
}}
static inline int zend_verify_arg_error(const zend_function *zf, zend_uint arg_num, const zend_arg_info *cur_arg_info, const char *need_msg, const char *need_kind, const char *given_msg, char *given_kind TSRMLS_DC){
zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
char *fname = zf->common.function_name;
char *fsep;
char *fclass;
if (zf->common.scope) {
fsep = "::";
fclass = zf->common.scope->name;
} 他 {
fsep = "";
fclass = "";
}
if (ptr && ptr->op_array) {
zend_error(E_RECOVERABLE_ERROR, "%s%s%s() に渡される引数 %d は %s%s でなければなりません。%s%s が指定され、%d 行目の %s で呼び出され、定義されています", arg_num, fclass, fsep, fname 、need_msg、need_kind、given_msg、given_kind、ptr->op_array->ファイル名、ptr->opline->lineno);
} 他 {
zend_error(E_RECOVERABLE_ERROR, "%s%s%s() に渡される引数 %d は %s%s、%s%s が指定されている必要があります", arg_num, fclass, fsep, fname, need_msg, need_kind, give_msg, Given_kind);
}
0を返す;}
上のコードでは、前のブロックメッセージ内のいくつかの関連する引数、渡される、呼び出されるなどを見つけることができます。

http://www.bkjia.com/PHPjc/963684.htmlwww.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/963684.html技術記事タイプが提案する実装​​ PHP は弱いタイプの言葉であり、メソッドにパラメータを渡すときにも、データのタイプを検査する必要はなく、このために 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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Windows 11でネットワークの種類をプライベートまたはパブリックに変更する方法 Windows 11でネットワークの種類をプライベートまたはパブリックに変更する方法 Aug 24, 2023 pm 12:37 PM

ワイヤレス ネットワークのセットアップは一般的ですが、ネットワークの種類の選択または変更は、特に結果が分からない場合には混乱する可能性があります。 Windows 11 でネットワークの種類をパブリックからプライベートに、またはその逆に変更する方法についてのアドバイスをお探しの場合は、役立つ情報をお読みください。 Windows 11 のさまざまなネットワーク プロファイルとは何ですか? Windows 11 には、多数のネットワーク プロファイルが付属しています。これらのプロファイルは、基本的に、さまざまなネットワーク接続を構成するために使用できる設定のセットです。これは、自宅やオフィスに複数の接続がある場合に便利で、新しいネットワークに接続するたびにすべてを設定する必要がありません。プライベート ネットワーク プロファイルとパブリック ネットワーク プロファイルは Windows 11 の 2 つの一般的なタイプですが、一般的には

ビデオ マトリックス アカウントを作成するにはどうすればよいですか?どのようなタイプのマトリックスアカウントがありますか? ビデオ マトリックス アカウントを作成するにはどうすればよいですか?どのようなタイプのマトリックスアカウントがありますか? Mar 21, 2024 pm 04:57 PM

ショートビデオプラットフォームの人気に伴い、ビデオマトリックスアカウントマーケティングが新たなマーケティング手法となっています。企業や個人は、さまざまなプラットフォームで複数のアカウントを作成および管理することで、ブランドのプロモーション、ファンの増加、製品の販売などの目標を達成できます。この記事では、ビデオ マトリックス アカウントの効果的な使用方法について説明し、さまざまな種類のビデオ マトリックス アカウントを紹介します。 1. ビデオ マトリックス アカウントを作成するにはどうすればよいですか?優れたビデオ マトリックス アカウントを作成するには、次の手順に従う必要があります。 まず、ブランド コミュニケーション、ファンの増加、製品の販売など、ビデオ マトリックス アカウントの目標を明確にする必要があります。明確な目標を持つことは、それに応じた戦略を立てるのに役立ちます。 2. プラットフォームの選択: 対象視聴者に基づいて、適切なショートビデオ プラットフォームを選択します。現在主流のショートビデオプラットフォームには、Douyin、Kuaishou、Huoshan Videoなどが含まれます。

Python での動的配列の実装: 初心者から熟練者まで Python での動的配列の実装: 初心者から熟練者まで Apr 21, 2023 pm 12:04 PM

パート 1 Python シーケンス型の性質について話しましょう。このブログでは、Python のさまざまな「シーケンス」クラスと、一般的に使用される 3 つの組み込みデータ構造 (リスト、タプル、文字) について話します。文字列クラス (str) の性質)。お気づきかどうかはわかりませんが、これらのクラスには明らかな共通点があります。複数のデータ要素を保存するために使用できます。最も重要な機能は、各クラスがシーケンスの要素への添え字 (インデックス) アクセスをサポートしていることです。 SyntaxSeq[i] の使用など。実際、上記の各クラスは配列などの単純なデータ構造で表されます。ただし、Python に詳しい読者は、これら 3 つのデータ構造にいくつかの違いがあることをご存じかもしれません。たとえば、タプルと文字列は変更できませんが、リストは変更できます。

Golang関数の戻り値の型は何ですか? Golang関数の戻り値の型は何ですか? Apr 13, 2024 pm 05:42 PM

Go 関数は、異なる型の複数の値を返すことができます。戻り値の型は関数シグネチャで指定され、return ステートメントを通じて返されます。たとえば、関数は funcgetDetails()(int,string) のように整数と文字列を返すことができます。実際には、円の面積を計算する関数は、面積とオプションのエラーを返すことができます: funccircleArea(radiusfloat64)(float64,error)。注: 関数シグネチャで型が指定されていない場合は、null 値が返されます。読みやすさを向上させるために、明示的な型宣言を含む return ステートメントを使用することをお勧めします。

Python の型ヒントのベスト プラクティス Python の型ヒントのベスト プラクティス Apr 23, 2023 am 09:28 AM

しばらくの間動的言語を使用するのは素晴らしいことです。コードは火葬場で再構築されます。単体テストと同様に、コードを書くのに少し時間はかかりますが、長い目で見ると非常に価値のある作業です。この記事では、Python の型ヒントをよりよく理解し、使用する方法を説明します。 1. 型ヒントは構文レベルでのみ有効です。型ヒント (PEP3107 以降導入) は、変数、パラメーター、関数パラメーター、およびその戻り値、クラス プロパティ、メソッドに型を追加するために使用されます。 Python の変数型は動的であり、実行時に変更してコードに型ヒントを追加できます。変数型は構文レベルでのみサポートされ、コードの実行には影響しません。Python インタープリタは、コードの実行時に型ヒントを無視します。したがってタイプは

C++ 関数の種類と特性 C++ 関数の種類と特性 Apr 11, 2024 pm 03:30 PM

C++ 関数には、単純関数、const 関数、静的関数、および仮想関数というタイプがあり、インライン関数、デフォルト パラメーター、参照戻り値、およびオーバーロードされた関数などの機能が含まれます。たとえば、calculateArea 関数は π を使用して、指定された半径の円の面積を計算し、それを出力として返します。

主なセルフメディア プラットフォームは何ですか?セルフメディアプラットフォームにはどのような種類がありますか? 主なセルフメディア プラットフォームは何ですか?セルフメディアプラットフォームにはどのような種類がありますか? Mar 21, 2024 pm 06:36 PM

インターネットの急速な発展に伴い、セルフメディアは情報伝達の重要なチャネルとなっています。 Weメディアプラットフォームは、個人や企業が自らをアピールし、情報を広める舞台を提供します。現在、市場に出ている主なセルフメディアプラットフォームには、WeChat公式アカウント、Toutiao、Yidian News、Penguin Media Platformなどが含まれます。これらのプラットフォームにはそれぞれ独自の特徴があり、大多数のセルフメディア実践者に豊富な創造的なスペースを提供します。次に、これらのプラットフォームを詳しく紹介し、セルフメディア プラットフォームの種類を検討します。 1. 主要なセルフメディア プラットフォームは何ですか? WeChat公式アカウントは、テンセントが個人および法人ユーザー向けに情報公開・普及サービスを提供するために立ち上げたセルフメディアプラットフォームです。サービスアカウントとサブスクリプションアカウントの2種類に分かれており、サービスアカウントは主に企業向けのサービスを提供し、サブスクリプションアカウントは情報発信を中心としています。による

PHP8 の新機能の分析: より強力なタイプの属性をどのように活用するか? PHP8 の新機能の分析: より強力なタイプの属性をどのように活用するか? Sep 12, 2023 am 11:26 AM

PHP8 の新機能の分析: より強力なタイプの属性をどのように活用するか?近年、Web 開発の世界で PHP の人気が高まっています。 PHP は、その柔軟性と学習の容易さにより、さまざまなプロジェクトに適した人気のプログラミング言語となっています。言語を継続的に改善および最適化する取り組みの一環として、PHP8 には、プロパティの型付け強化など、多くの新機能が導入されています。この記事では、PHP8 のプロパティ タイプの新機能と、それらを活用してコードの信頼性とパフォーマンスを向上させる方法について詳しく説明します。 PHP8 より前では、プロパティの型宣言は次のようになります。

See all articles