PHP の型変換に関するインタビューの質問
原文はブログに掲載しています http://starlight36.com/post/php-type-convert
最近、会社の新人面接をしているのですが、よく聞かれる質問が価値観です。例:
var_dump((int)true);var_dump((string)true);var_dump((string)false);var_dump((bool)"1");var_dump((bool)"0");var_dump((bool)"");var_dump((bool)"false");
私がこの質問を初めて目にしたのは、Yingji の PHP シニア開発エンジニアの職の筆記試験でした。これは非常に基本的なことですが、それでも多くの PHP 使用者を困惑させる可能性があります。まず実行結果を見てみましょう:
int(1)string(1) "1"string(0) ""bool(true)bool(false)bool(false)bool(true)
ほとんどの人にとって、1、2、4 行目は通常問題ありません。しかし、なぜ false が空の文字列に変換されるのでしょうか?リクエスト値を処理するとき、通常は文字列型 false が渡されますが、「false」(文字列)は false(ブール値)ではないため、少し混乱します。
なぜこれが起こっているのですか?
この問題に関して、PHP カーネルから始めて、型変換中にシステム内で何が起こるかを見てみましょう。
まず、PHP の弱い型の実装に関する背景知識を追加しましょう。もちろん、PHP インタプリタは C 言語で記述され、変数の最終処理も C 言語を使用して実装され、データ構造が構築されます。 Zend エンジンでは、対応する PHP 変数の型は zval です。
Zend/zend_types.h ファイルを開くと、zval 型の定義が表示されます。php-5.5.23 バージョンは 55 行目あたりにあります:
typedef struct _zval_struct zval;
このようにして、zval が実際には _zval_struct Type という名前の構造体であることがわかります。 Zend/zend.h ファイルの 320 行目あたりから始まるこの構造体の定義を見つけました。
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj;} zvalue_value;struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc;};
ご覧のとおり、_zval_struct には 2 つの重要なメンバーが含まれています。1 つは zvalue_value 型の値で、もう 1 つはzend_uchar 型の型。 zvalue_value 型は共用体であり、PHP 変数の値に関する情報を格納するために使用されることに注意してください。 (ユニオンが何であるかを忘れた場合は、説明しましょう。ユニオンは構造体に似ていますが、ユニオンにはメンバーが 1 つしか存在できず、ユニオンが占有するスペースはユニオン内で最も長くなります。メンバーが長いほど、ユニオンにはメンバーが 1 つしか存在できません。これはメモリ使用量を節約するために行われます。) zvalue_value には、long、double、struct、HashTable、zend_object_value の 5 種類のメンバーがあります。これらは、PHP 変数のさまざまなタイプの値を保存するために使用されます:
C タイプ | PHP タイプ |
long | bool |
int | |
リソース | |
ダブル | float |
struct | string |
HashTable | 配列 |
オブジェクト |
PHP の変数の型変換、つまり弱い型の実装は、基本的に異なる型間の zval 型の変換を実装していることがわかります。 zvalue_value の数値変換を完了することに加えて、_zval_struct の型を現在の変数の型に設定する必要もあります。この変換を完了するために、一連の関数 Convert_to_* が Zend エンジンに実装されています。これらの変換関数は、Zend/zend_operators.c の 511 行目あたりにあります。
ZEND_API void convert_to_boolean(zval *op) /* {{{ */{ int tmp; switch (Z_TYPE_P(op)) { case IS_BOOL: break; case IS_NULL: Z_LVAL_P(op) = 0; break; case IS_RESOURCE: { TSRMLS_FETCH(); zend_list_delete(Z_LVAL_P(op)); } /* break missing intentionally */ case IS_LONG: Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0); break; case IS_DOUBLE: Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0); break; case IS_STRING: { char *strval = Z_STRVAL_P(op); if (Z_STRLEN_P(op) == 0 || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { Z_LVAL_P(op) = 0; } else { Z_LVAL_P(op) = 1; } STR_FREE(strval); } break; case IS_ARRAY: tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); zval_dtor(op); Z_LVAL_P(op) = tmp; break; case IS_OBJECT: { zend_bool retval = 1; TSRMLS_FETCH(); convert_object_to_type(op, IS_BOOL, convert_to_boolean); if (Z_TYPE_P(op) == IS_BOOL) { return; } zval_dtor(op); ZVAL_BOOL(op, retval); break; } default: zval_dtor(op); Z_LVAL_P(op) = 0; break; } Z_TYPE_P(op) = IS_BOOL;}/* }}} */
case。 IS_STRING このコードは文字列型変数をブール型に変換する演算です。文字列が空であるか、文字列の長さが 1 で文字が 0 の場合にのみ、文字列のブール値が 1 (true)、その他の値が 0 (false) であることがわかります。 。
同様に、ブール値がどのように文字列に変換されるかについても理解しています。これは、_convert_to_string 関数の実装から理解できます。
一見単純かつ基本的な PHP の問題の根本原因は、PHP 実装メカニズムの把握にあります。個人的には、この質問は PHPer の知識の境界を特定するのにも適した質問であると感じています。

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

ホットトピック









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

セッションハイジャックは、次の手順で達成できます。1。セッションIDを取得します。2。セッションIDを使用します。3。セッションをアクティブに保ちます。 PHPでのセッションハイジャックを防ぐための方法には次のものが含まれます。1。セッション_regenerate_id()関数を使用して、セッションIDを再生します。2。データベースを介してストアセッションデータを3。

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

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

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。
