まず、前のセクションの質問に答えましょう。
コードをコピーします コードは次のとおりです:
$foo = 10;
$bar = 20;
function change() {
global $foo;
//echo '関数内 $ foo = '.$foo.' />';
br $bar はできません関数の本文内でアクセスできます
$bar = 0;
echo $foo, ' ', $bar;
?>
プログラム出力11 20。その理由は、メソッド内で $bar 変数にアクセスできないため、その値は 20 のままです。 global を使用すると、$foo の値が取得できます。自動インクリメント後の $foo の値は 11 です。
Global はグローバル変数の定義に使用されますが、このグローバル変数は Web サイト全体ではなく、include または require 内のすべてのファイルを含む現在のページに適用されます。
変数の 3 つの基本的な特性については、序文で説明しました。そのうちの 1 つは、変数には文字列、配列、オブジェクトなどの特定の型があります。プログラミング言語の型システムは、強い型と弱い型の 2 つのタイプに分類できます。 強い型付き言語とは、変数が特定の型の変数として宣言されると、プログラムの実行中に変更できないことを意味します。変数の型以外の値が割り当てられます (もちろん、これがすべて当てはまるわけではありません。これには、次のセクションで説明する型変換が含まれる場合があります)。 C/C++/Java がこのカテゴリに分類されます。
PHP、Ruby、JavaScript などのスクリプト言語は弱く型指定された言語です。変数は任意のデータ型を表すことができます。
PHP がシンプルでありながら強力な言語である理由の大部分は、変数の型指定が弱いためです。 しかし、これは諸刃の剣でもあり、不適切に使用すると問題が発生する可能性があります。機器と同じように、強力であればあるほど、エラーが発生する可能性が高くなります。
公式の PHP 実装では、すべての変数は同じデータ構造 (zval) を使用して保存され、この構造は PHP のさまざまなデータ型も表します。 これには、変数の値だけでなく、変数の型も含まれます。これは PHP の弱い型付けの中核です。
zval 構造体はどのようにして弱い型を実装しているのでしょうか?一緒にベールを明らかにしましょう。
変数ストレージ構造
PHP は、変数を宣言または使用するときに、そのデータ型を明示的に示す必要はありません。
PHP は弱い型指定言語ですが、PHP に型がないという意味ではありません。PHP には 8 つの変数型があり、3 つのカテゴリに分類できます
* スカラー型: ブール型、整数型、浮動小数点数 (double)、文字列型
* 複合型: 配列、オブジェクト
* 特殊型: リソース、NULL
公式 PHP は C で実装されており、C は厳密に型指定された言語です。では、これはどのようにして PHP で弱い型を実装するのでしょうか。
変数の値は、以下に示す zval 構造体に格納されます。 zval 構造は Zend/zend.h ファイルで定義されており、その構造は次のとおりです:
コードのコードは次のとおりです;
zend_uchar 型 ; /* アクティブ型 */
zend_uchar is_ref__gc;
};
PHP はこの構造を使用して変数のすべてのデータを保存します。他のコンパイル済み静的言語とは異なり、PHP は変数を格納するときに、PHP ユーザー空間変数の型も同じ構造内に保存します。このようにして、この情報から変数の型を取得できます。
zval 構造体には 4 つのフィールドがあり、その意味は次のとおりです:
属性名 |
含义 |
默认值 |
refcount__gc |
表示引用计数 |
1 |
is_ref__gc |
表示是否为引用 |
0 |
value |
存储变量的值 |
|
type |
变量具体的类型 |
PHP5.3以降、新しいガベージコレクション機構が導入され、参照カウントと参照フィールド名がrefcount__gcとis_ref__gcに変更されました。その前には refcount と is__ref がありました。
変数の値は別の構造体 zvalue_value に格納されます。値の保存については以下で説明します。
PHP ユーザー空間は PHP 言語のレベルを指し、本書の大部分は PHP の実装について説明しています。 これらの実装は、カーネル空間として理解できます。 PHP は C で実装されているため、このスペースの範囲は C 言語に限定されます。 PHP ユーザー空間は、提供される PHP 構文と関数の範囲に制限されます。 たとえば、一部の PHP 拡張機能は、メソッドまたはクラスを PHP ユーザー空間にエクスポートするいくつかの PHP 関数またはクラスを提供します。
変数の型
zval 構造体の type フィールドは、弱い型指定を実装するための最も重要なフィールドです。type の値は、IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT、IS_RESOURCE のいずれかになります。 文字通り理解するのは簡単ですが、これらは型の一意の識別子にすぎず、異なる型に応じて異なる値が値フィールドに格納されます。 さらに、それらで定義されるタイプには、IS_CONSTANT および IS_CONSTANT_ARRAY が含まれます。
これは、データベースを設計するときに行うことと似ています。同様のテーブルの設計の重複を避けるために、インジケーター フィールドを使用してさまざまな種類のデータを記録します。
変数の値が格納されます
前述したように、変数の値は zvalue_value 共用体に格納されます。構造体は次のように定義されます。
コードをコピーします コードは次のとおりです:
typedef Union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* ハッシュテーブル値 */
zend_object_value obj;
} zvalue_value;
这里使用联合体而不是用结构体是出于空间利用率的考虑,因为一个变量同时只能属于一种类型。 如果使用结构体的话将会不必要的浪费空间,而PHP中的所有逻辑都围绕变量来进行的,这样的话, 内存浪费将是十分大的。这种做法成本小但收益非常大。
各种类型的数据会使用不同的方法来进行变量值的存储,其对应赋值方式如下:
1. 一般类型
変数型 |
マクロ |
? |
ブール値 |
ZVAL_BOOL |
ブール/整数変数の値は (zval).value.lval に保存され、その型も対応する IS_* とともに保存されます。 Z_TYPE_P(z)=IS_BOOL/LONG; Z_LVAL_P(z)=((b)!=0); |
integer |
ZVAL_LONG |
float |
ZVAL_DOUBLE |
null |
ZVAL_NULL |
NULL值的变量值不需要存储,只需要把(zval).type标为IS_NULL。 Z_TYPE_P(z)=IS_NULL; |
resource |
ZVAL_RESOURCE |
资源类型的存储与其他一般变量无异,但其初始化及存取实现则不同。 Z_TYPE_P(z) = IS_RESOURCE; Z_LVAL_P(z) = l; |
2. String Sting
文字列の型表示は他のデータ型と同じですが、文字列を保存するときに文字列長を指定する追加フィールドがあります。
コードをコピーします コードは次のとおりです:
struct {
char *val;
int len;
} str;
C の文字列は次で始まります
3. 配列
配列は、PHP で最も一般的に使用され、最も強力な変数タイプであり、他のタイプのデータを格納でき、さまざまな組み込み操作関数を提供します。配列の格納は、他の変数よりも複雑です。配列の値は、HashTable タイプのデータである zvalue_value.ht フィールドに格納されます。 PHP の配列は、ハッシュ テーブルを使用して関連データを保存します。ハッシュ テーブルは、効率的なキーと値のペアの格納構造です。 PHP のハッシュ テーブルの実装では、HashTable と Bucket の 2 つのデータ構造が使用されます。 PHP のすべての作業はハッシュ テーブルによって実装されます。次のセクション HashTable では、ハッシュ テーブルの基本概念と PHP でのハッシュ テーブルの実装について説明します。
4. オブジェクト
オブジェクト指向言語では、クラス属性、メソッド、その他のデータなど、必要なデータ型を定義できます。オブジェクトはクラスの特定の実装です。 オブジェクトには独自の状態と完了できる操作があります。
PHP のオブジェクトは一種の複合データであり、zend_object_value 構造体を使用して保存されます。その定義は次のとおりです:
コードをコピーします コードは次のとおりです:
typedef struct _zend_object_value {
zend_object_handle handle; // unsigned int 型、EG(objects_store).object_buckets のインデックス
zend_object_handlers *handlers;
} zend_object_value;
PHP オブジェクトは実行時にのみ作成されます。前の章では、実行時にデータを保存するために使用されるグローバル構造である EG マクロを紹介しました。 これには、作成されたすべてのオブジェクトを保存するために使用されるオブジェクト プール、EG (objects_store)、およびオブジェクトの zend_object_handle フィールドが含まれます。オブジェクト値の内容は、オブジェクト プール内の現在のオブジェクトのインデックスであり、handlers フィールドは、オブジェクトが作成されたときのインデックスです。処理機能が保存されます。 この構造体とオブジェクト関連のクラス構造体 _zend_class_entry については後で紹介します。
PHP の弱い変数コンテナーは包括的な形式で実装されており、各タイプの変数には対応するタグとストレージ領域があります。 強力な型を使用する言語は、実行前に多くの情報を決定できるため、通常、弱い型よりも効率的であり、プログラム エラーの排除にも役立ちます。 これが引き起こす問題は、コードの記述が比較的制限されていることです。
PHP は主に Web 開発言語として使用されます。通常の Web アプリケーションでは、ボトルネックは通常ビジネス層とデータ アクセス層にあります。ただし、大規模なアプリケーションでは言語も重要な要素になります。したがって、Facebook は独自の PHP 実装を使用します。 PHP コードを C++ にコンパイルしてパフォーマンスを向上させます。ただし、Facebook の hiphop は完全な PHP 実装ではなく、PHP を C++ に直接コンパイルするため、eval 構造などの一部の PHP の動的機能は実装できません。もちろん、ヒップホップがそれを実装しない場合は、それを実装する方法があります。
http://www.bkjia.com/PHPjc/728099.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/728099.html技術記事まず、前のセクションの質問に答えましょう。 次のようにコードをコピーします: ?php $foo = 10; $bar = 20; function change() { //echo '内部関数 $foo = '.$foo.'br /'; ..