php5勉強メモ(譲渡)

WBOY
リリース: 2016-06-21 09:15:51
オリジナル
827 人が閲覧しました

php5|メモ

作者: whhwq
phpv.net で見ると気持ちいい
/*
+---------------------------- -------------------------------------------------- -+
| = この記事は Haohappy<> によって読まれています
| = 翻訳 + 個人的な経験
|ありがとうございます
| = 批判や修正は歓迎です。私たちはすべての PHP 愛好家と一緒に進歩することを願っています
+---------------------- ---------------------------------------------------- --------+
*/

PHP5 学習ノート
セクション 1 - オブジェクト指向プログラミング
オブジェクト指向プログラミングは、大規模なソフトウェア プロジェクト、特に複数の人が関与するプロジェクトにソリューションを提供するように設計されています。ソース コードは 10,000 行、またはそれ以上に増加します。多くの場合、すべての変更が望ましくない副作用につながる可能性があります。これは、第一次世界大戦前のヨーロッパのように、モジュールが秘密同盟を形成した場合に起こります。
//haohappy 注: 比喩的にモジュールを指します。それらは高すぎて、相互依存性が強すぎます。1 つのモジュールを変更すると、他のモジュールも変更する必要があります。
ログインの処理に使用されるモジュールが、そのデータベース接続を共有できるようにする場合を想像してください。もちろん、出発点は適切です。これにより、別のデータベース接続のコストが節約されますが、場合によっては、ログイン処理モジュールが変数の 1 つの名前を変更するため、2 つの変数間の合意が切断される可能性があり、これによりクレジット カード モジュールでの処理エラーが発生する可能性があります。請求書を処理するモジュールが故障する可能性があります。したがって、大多数のプログラマーがカップリングとカプセル化に感謝するのは少し劇的だと思います。モジュール 相互依存性の尺度。既存のプロジェクトからモジュールを取得して、別の新しいプロジェクトで使用できるようにしたいと考えています。また、モジュール内で大規模な変更を行うこともできます。他のモジュールへの影響を心配する必要はありません。カプセル化の原理により、モジュールは比較的独立したものとして扱われ、モジュール間のデータ通信は相互の変数名を通じて行われず、関数を使用して行われます。丁寧にリクエストを送信してください。
カプセル化は、PHP や多くの手続き型言語で使用できる原則であり、モジュール WEB を使用して仮説を構築することを妨げるものはありません。
オブジェクト指向プログラミングでは、これらのオブジェクトはメソッドとプロパティを持ちます。これは、オブジェクトによって実行されるアクションです。 、属性はオブジェクトの特性です。理想的なオブジェクト指向システムでは、各部分はオブジェクトとメソッドを介したオブジェクト間の関係で構成されます。クラスはオブジェクトのプロパティを定義します。Cookie オブジェクトのセットを作成する場合、クラスのプロパティとメソッドは、データ メンバーまたはメソッド メンバーと呼ばれます。
各言語は、オブジェクトにアクセスするためのさまざまな方法を提供します。PHP は C++ から概念を借用し、関数と変数を含めるためのデータ型を提供します。 PHP が最初に設計されたとき、あるいは PHP3 が開発されたときでさえ、PHP はコード 100,000 行を超える大規模プロジェクトを開発する機能を提供することを意図していませんでした。 PHP と Zend Engine の開発により、大規模なプロジェクトを開発できるようになりましたが、プロジェクトがどれほど大きくても、クラス内にスクリプトを記述することでコードを再利用できます。これは、特に自分のコードを他の人と共有したい場合には良いアイデアです。
オブジェクトの考え方は、コンピューター サイエンスで最もエキサイティングな概念の 1 つです。最初はそれをマスターするのは難しいですが、一度マスターすれば、その心で考えることが非常に自然に感じられるようになるでしょう。
セクション 2 - PHP5 のオブジェクト モデル
PHP5 には、単一継承、制限されたアクセス、およびオーバーロード可能なオブジェクト モデルがあり、この章で後ほど詳しく説明しますが、これにはクラス間の親子関係も含まれます。 PHP は、プロパティとメソッドへの制限されたアクセスをサポートし、外部クラスからのアクセスを禁止するメンバーを宣言できます。 public.private は、カプセル化のより良い実装に適しています。
PHP5 のオブジェクト モデルは、オブジェクトを他のデータ型とは異なるものとして扱い、PHP では、ハンドルベースのオブジェクトの受け渡しを明示的に行う必要はありません。モデルについては、この章の最後で詳しく説明します。これは、PHP5 の最も重要な新機能です。
より直接的なオブジェクト モデルにより、ハンドルベースのシステムには、効率の向上、メモリの消費量の削減などの追加の利点があります。柔軟性の向上
以前のバージョンの PHP では、スクリプトはデフォルトでオブジェクトをコピーしていましたが、PHP 5 では、不要なコピーが回避されるため、スクリプトの実行効率が向上しました。同時に、コピーを減らすと、占有メモリが減り、他の操作に多くのメモリが残されるため、効率も向上します。
//haohappy 注: ハンドルに基づいて、2 つのオブジェクトが同じメモリをポイントできることを意味します。これにより、コピー操作が削減されるだけでなく、メモリ使用量も削減されます。
Zand エンジン 2 は、より優れた柔軟性を備えています。 - オブジェクトが破棄される前にクラスメソッドを実行します。これはメモリの利用にも適しており、PHP はオブジェクトへの参照がないことを明確に認識し、空きメモリを他の用途に割り当てることができます。クラスを宣言するときは、オブジェクトに必要なすべての変数と、プロパティとメソッドと呼ばれる関数をリストする必要があります。クラスの構成は、中括弧 ({}) で示されています。 3.1.2 では、クラス内で 3 つのプロパティと 2 つのメソッドを定義する方法を示します。 //ユーザーを追跡するクラスを定義します
class User
{
//Attributes
public $name;
private $password, $lastLogin

//Method
public function __construct($name , $password)
$ this->name = $name;
$this->password = $password;
$this->accesses++;

//前回の訪問
function getLastLogin()
{
return(date("M d Y", $this->lastLogin))
}
}

//オブジェクトのインスタンスを作成します
$user = new User ("Leon", "sdf123");

//最後の訪問時刻を取得する
print($user->getLastLogin() ."
n");

//ユーザー名を出力する
print ("$user->name
n");
?>
プロパティを宣言する場合、変数は整数、文字列、または別のオブジェクトである可能性があります。実際の状況によって異なります。プロパティを宣言するときに、プロパティの意味とデータ型をマークするアノテーションを追加することをお勧めします。メソッドを宣言するときは、クラスのメソッドの外で関数を定義するのと同じことを行います。これは、クラスの外部関数と同じ名前のメソッドを安全に作成でき、たとえば、クラスで date() という名前のメソッドを定義できることを意味します。 for や while などの PHP キーワードを使用してメソッドに名前を付けることはできません。

クラス メソッドには、スクリプトの場合、パラメータをメソッドに渡す別のクラスの名前が含まれる場合があります。メソッドを呼び出すと、PHP はクラスのインスタンスではない変数を渡すことによって「致命的エラー」を生成します。整数、文字列、ブール値などの他の型の型ヒントを指定していない可能性があります。ヒントに配列型を含めるべきかどうかはまだ議論されています。

型ヒントは、関数のパラメーターまたは演算子のインスタンスのデータ型をテストするためのショートカットです。このメソッドを必ず返すようにしてください。 , 整数型など。 3.2.1 コンパイルされたクラスが Widget.なし';
public $created=FALSE;
}

//Assembler
class Assembler
{
public function make(Widget $w)
{
print("Making $w->name
n") ;
$ w->created=TRUE;
}
}

//コンポーネント オブジェクトを作成します
$thing = new Widget;
$thing->name = 'ガジェット'//アセンブリ コンポーネント
アセンブラ::make ($thing);
?>
メソッドには、パラメーターに渡される変数に加えて、クラスの個々のインスタンスを表すためにこれを使用する必要があります。オブジェクト指向言語のいくつかの前提条件 修飾されていない変数はローカル プロパティに送信されますが、PHP では、メソッドの変数はメソッドの特定のスコープ内でのみ使用されることに注意してください。 class (3.1.2).

PHP では、メソッド宣言の前に public、private、protected などのアクセス修飾子を定義します。さらに、クラス内で定数を宣言することもできます。さまざまなアクセス方法については、この章の後半で説明します

3.1.2 では、User クラスに 2 つのプライベート プロパティ ($) があり、同じアクセス方法を 1 行にリストできます。パスワードと $lastLogin。

セクション 4- - コンストラクターとデストラクター

__construct という名前の関数をクラスで宣言すると、この関数はコンストラクターとして扱われ、オブジェクト インスタンスの作成時に実行されます。他の関数と同様に、コンストラクターには、オブジェクトを作成し、そのすべてのプロパティをステートメントに含めるクラスを定義できます。PHP では、__destruct という名前の関数を定義することもできます。オブジェクトが破棄される前にこの関数を呼び出します。これはデストラクターと呼ばれます。

継承はクラスの強力な機能です。あるクラス (サブクラス/派生クラス) は、別のクラス (親クラス/基本クラス) の機能を継承できます。派生クラスには、基本クラスのすべてのプロパティとメソッドが含まれており、次のクラスで使用できます。派生クラスに他のプロパティやメソッドを追加する 3.1.2 で示したように、extends キーワードを使用してクラスを継承することもできます。コンストラクターは継承されます。他のメソッドとともに継承されると、オブジェクトの作成時に実行されません。この機能が必要な場合は、第 2 章で説明した :: 演算子を使用する必要があります。ブロック Namespace。parent は親クラスの名前空間を指します。parent::__construct を使用して、クラスの後にコンストラクターを呼び出すことができます。つまり、クラスに Animal という名前を付け、その中に Animal という名前のメソッドを作成した場合、クラスに __construt コンストラクターとメソッドの両方がある場合、このメソッドはコンストラクターになります。 class 関数と同じ名前の場合、PHP は __construct をコンストラクターとして扱います。これにより、以前の PHP バージョンで作成されたクラスを引き続き使用できます。ただし、新しいスクリプト (PHP5) では、この新しく宣言された PHP メソッドのコンストラクターを使用できます。こうすることで、クラスの名前を変更するときにコンストラクターの名前を変更する必要がなくなります

コンストラクターに一意の名前を付けることができます。 PHP の名前 他のクラス メソッドと同様のアクセス メソッドは、

Destructor などの特定のスコープからオブジェクトをインスタンス化する機能に影響します。デフォルトでは、PHP はオブジェクトのプロパティによって占有されているメモリを解放するだけで、オブジェクトの使用後に任意のコードを実行してメモリをクリアできます。
いつ 関数の名前空間内で、スクリプトがオブジェクトに関連付けられていないと PHP が判断したときに、デストラクターが呼び出されます。グローバル変数の場合、これはスクリプトの最後に行われます。オブジェクトを破棄する場合は、そのオブジェクトを指す変数に他の値を割り当てることができます。通常は、変数を NULL に割り当てるか、unset を呼び出します。次の例では、クラスからインスタンス化されたオブジェクトの数をカウントします。

クラスを定義したら、new を使用してこのクラスのインスタンスを作成できます。このクラスの定義は、New が必要とするアセンブリ ラインに配置されます。クラスの名前を返し、クラスのインスタンスを返します。コンストラクターがパラメーターを必要とする場合は、 new の後にパラメーターを入力する必要があります。
class Counter
{
private static $count = 0;
関数 __construct()
{
self::$count++;
}

function __destruct()
{
self::$count--;

function getCount()
{
return self ::$count ;
}
}

//最初のインスタンスを作成します
$c = new Counter();

//出力 1
print($c->getCount() . "
n");
//2 番目のインスタンスを作成します
$c2 = new Counter();

//出力 2
print($c->getCount() . "
n");

//インスタンスを破棄します
$c2 = NULL;

//出力 1
print($c->getCount() . "
n");
?>
新しいインスタンスを作成すると、メモリは次のように準備されます。すべてのプロパティを保存します。各インスタンスには独自のプロパティのセットがありますが、メソッドはクラスのすべてのインスタンスで共有されます。

セクション 5 - オブジェクトを呼び出すために参照によってオブジェクト モデルを複製する場合もあります。オブジェクトのコピーを作成し、元のオブジェクトへの変更がコピーに影響しないことを望みます。この目的のために、PHP は __construct と _ _destruct と同様に、先頭に 2 つのアンダースコアを付けた特別なメソッドを定義します。デフォルトでは、__clone メソッドを使用すると、元のオブジェクトと同じプロパティとメソッドを持つオブジェクトが作成されます。クローン作成時にデフォルトのコンテンツを変更したい場合は、__clone Write (プロパティまたはメソッド) でそれをオーバーライドする必要があります。メソッドにはパラメータを含めることはできませんが、このポインタとあのポインタ (コピーされるオブジェクトを指す) の両方が含まれています。自分自身をクローンする場合は、オブジェクトに情報を含めたいものをすべてコピーするように注意する必要があります。 __clone を使用してコピーする場合、PHP は暗黙的なコピーを実行しません。

以下は、シリアル序数を使用してオブジェクトを自動化する例を示しています。 private static $nextSerial = 0;
private $name;

function __construct($name) //コンストラクター関数
{
$this->name = $name; ++self::$nextSerial
}

function __clone() //Clone
{
$this->name = "$that->name のクローン" ; self::$nextSerial;
}

function getId() //id 属性の値を取得します
{
return($this->id)
}
function getName() //name 属性の値を取得します
{
return($this->name);
}
}

$ot = new ObjectTracker("Zeev's Object"); ot- >__clone();

//出力: 1 Zeev のオブジェクト
print($ot->getId() . " " . $ot->getName() . "
");
/ /出力: Zeev のオブジェクトの 2 つのクローン
print($ot2->getId() . " " . $ot2->getName() . "
");
?>
セクション 6- - プロパティとメソッドへのアクセス

オブジェクト インスタンスのプロパティは、PHP の他の変数と同様に変数ですが、プロパティの前にドル記号 $ を使用する必要はありません。例: 6.1 の print ユーザー オブジェクトの name 属性の行は、-> と組み合わせて使用​​できます。オブジェクトの属性にオブジェクトが含まれている場合は、2 つの -> 演算子を使用できます。 6.5 の例を見ると、オブジェクト House のプロパティ room には Room オブジェクトのセットが含まれています。このアクセス方法は、プロパティへのアクセスと似ています。 > 演算子は、インスタンスのメソッドを指すために使用されます。例 6.1 では、メソッドの実行はクラス外の関数とほぼ同じです。親クラスのメソッドは、子クラスでも有効です。 クラス内に宣言はありません。 前述したように、継承されたプロパティにアクセスしたい場合は、それを参照するだけで済みます。 :: 演算子を使用して基本クラスの独自のプロパティにアクセスする場合と同様に、
PHP コード:
class Room
{
public $name;

function __construct($name="unnamed")
{
$this->name = $name;
}

class House
{
//部屋の配列
public $room;

// 空の家を作成
$home = 新しい家

/ /部屋を追加します
$home->room[] = 新しい Room(" 寝室");
$home->room[] = 新しい Room("キッチン"); new Room("bathroom");

//家の最初の部屋を表示
print($home->room[0]->name);
PHP には 2 つの特別な名前空間があります。名前空間は親クラスを指し、自己名前空間は現在のクラスを指します。 例 6.6 では、親クラスのコンストラクターを呼び出すために親名前空間を使用する方法を示します。
< ;?php
class Animal //Animal
{
public $blood; / /熱血属性または冷血属性
public $name;
public function __construct($blood, $name=NULL)
$this- >blood = $blood;
if($name)
{
$this-> name = $name;
}
}

クラス哺乳類は動物を拡張します //哺乳類
{
public $furColor;毛皮の色
public $legs;

function __construct($furColor, $legs, $name =NULL)
{
parent::__construct("warm", $name);
$this->furColor = $furColor;
$this->legs = $legs;
}
}

class 犬は哺乳類を拡張します
{
function __construct($furColor, $name)
{
parent::__construct($furColor, 4, $name);

self::bark();
}

function bark()
{
print("$this->名前は「ワンワン!」と言う)
}
}

$d = new Dog("ブラック アンド タン"、"アンガス");
?>
第 4 章で紹介されている関数の呼び出し方法。オブジェクトのメンバーの場合、次のように呼び出されます。 実行時に変数の名前を決定する必要がある場合メソッドを呼び出す場合は、$this->$Property のような式を使用できます。$ obj->$method() を使用することもできます。

値を返すには、-> 演算子を使用することもできます。たとえば、$obj->getObject()->callMethod() のような式を書くことができます。これにより、中間変数の使用が回避されます。ファクトリ パターンなどの特定のデザイン パターンの実装に役立ちます。
セクション 7 - クラスの静的メンバー

クラス 静的メンバーは一般的なクラス メンバーとは異なります。静的メンバーはオブジェクトのインスタンスとは何の関係も持た​​ず、クラス自体とのみ関係します。これらは、クラスによってカプセル化される関数とデータを実装するために使用されますが、特定のオブジェクトの関数とデータは含まれません。

静的プロパティには、クラスにカプセル化されるデータが含まれます。実際、クラスのすべてのインスタンスで共有できます。実際、固定クラスに属し、アクセス方法が制限されていることに加えて、クラスの静的プロパティは関数の静的プロパティと非常に似ています。グローバル変数

次の例の Counter::$count は、Counter クラスに属しており、Counter インスタンスには属していませんが、この例では、 self または他の有効な名前付け式を使用できます。 getCount メソッドは、Counter::$count ではなく、self::$count を返します。

静的メソッドは、クラスがカプセル化する必要がある関数を実装しており、特定のオブジェクトとは何の関係もありません。クラスの属性には、アクセス修飾子に関係なく、完全にアクセスすることも、オブジェクトのインスタンスによってアクセスすることもできます。6.3 の例では、getCount は -> で呼び出される通常のメソッドです。このメソッドは使用されませんが、場合によっては、getCount がどのオブジェクトにも属さないことを期待します。存在しない 有効なオブジェクトがあるときに呼び出す場合は、静的メソッドを使用する必要があります。PHP は、オブジェクトから呼び出した場合でも、この変数を静的メソッド内に作成しません。例 6.7 は、getCount を 6.3 に変更したものです。 static メソッド。static キーワード -> 演算子を使用してインスタンスが getCount を呼び出すのを防ぐことはできませんが、this-> を使用して呼び出すと、エラーが発生します。例 6.3 は、セクション 4 -- コンストラクターとデストラクターの例 (前の記事を参照) を参照しています。2 つの例を比較することで、
//static メソッドと通常のメソッドの違いをよく理解できます。このメソッドが静的に呼び出されたか非静的に呼び出されたかを示すために作成されました。もちろん、static キーワードを使用すると、このメソッドはどのように呼び出されても常に静的になります。

クラスで定数を定義することもできます。プロパティ、不要 public static を使用するには、const キーワードを使用するだけです。定数プロパティは常にクラスのプロパティであり、クラスをインスタンス化するオブジェクトのプロパティではありません。 < ?php
クラス カウンター
{
private static $count = 0;

function __construct()
{
self::$count++}

function __destruct()
self; :: $count--;
}

static function getCount()
{
return self::$count;
}
};

//インスタンスを作成すると、__construct() が実行されます
$c = new Counter ();

//出力 1
print(Counter::getCount() . "
n");

//クラスのバージョン属性を出力
print("Version used: " . Counter ::VERSION . "
n");
セクション 8 - アクセスメソッド

これは PHP5 の新しい機能ですが、多くの点で異なります。アクセス メソッドを使用することでのみ、信頼性の高いオブジェクト指向アプリケーションを開発し、再利用可能なオブジェクト指向クラス ライブラリを構築できます。

C++ や Java と同様、PHP には public、private、protected の 3 つのアクセス メソッドがあります。アクセス メソッドを指定しない場合、静的メンバーのアクセス メソッドを指定して、そのアクセス メソッドを static キーワードの前に置くこともできます。 public static).

パブリック メンバーには制限なくアクセスできます。クラス外のコードはパブリック プロパティを読み書きできます。以前のバージョンの PHP では、すべてのメソッドとプロパティがパブリックでした。

プライベート (プライベート) メンバーは、クラス メソッドの外部でのみ変更または変更できます。その値を読み取ることはできません。同じクラスはプライベート メソッドを呼び出すことができます。継承されたサブクラスは親クラスのプライベート メンバーにアクセスできません。例 6.8 を参照して、equals メソッドは 2 つのウィジェットを比較します。 == 演算子は同じクラスの 2 つのオブジェクトを比較しますが、この例では各オブジェクト インスタンスが一意の ID を持ちます。equals メソッドが別の Widget インスタンスのプライベート プロパティにどのようにアクセスするかに注意してください。そのような操作を許可します。

リスト 6.8 プライベートメンバー
class Widget
{
private $name;

public function __construct($name, $price; )
{
$this->name = $name;
$this->id = uniqid() ;
// 2 つのウィジェットがあるかどうかを確認します。同じ
public functionquals($widget)
{
return(($this-> name == $widget->name)AND
($this->price == $widget->price)) ;
}
}
$w1 = 新しいウィジェット('歯車', 5.00);
$w3 = 新しいウィジェット('歯車', 7.00); /TRUE
if($w1->equals($w2))
{
print( "w1 と w2 は同じです
n");

//FALSE
if($w1-> == 比較に ID が含まれます
if($w1 == $w2) / /ID が異なるため等しくありません
{
print("w1 と w2 は同じ
n");
}
?>
オブジェクト指向プログラミングに慣れていない人は、プライベート メンバーの目的が何なのか疑問に思うかもしれません。この章の冒頭で説明した、プライベート メンバーはデータのカプセル化に役立ちます。クラス内に隠されており、クラス外のコードからはアクセスできません。また、データ構造外のコードが内部プロパティに直接アクセスできない場合、ほとんどのプライベート プロパティには暗黙的な依存関係が存在しません。解決策は、パブリック メソッドのペアを使用することです。1 つは get (プロパティの値を取得)、もう 1 つは set (プロパティの値を設定) です。コンストラクターはプロパティの初期値も受け入れます。これにより、限定された適切なインターフェイスを介してメンバー間の通信が行われるようになり、メソッドに渡される値を変更する機会も提供されます。例 6.8 で、コンストラクターが強制的に価格を float Number(floadval()) にする方法にも注目してください。 .

保護された (保護された) メンバーは、同じクラス内のすべてのメソッドおよび継承されたクラス内のすべてのメソッドからアクセスできます。パブリック プロパティは、サブクラスの書き込みを許可するため、カプセル化の精神に違反します。この問題については、保護されたメソッドを使用するサブクラスはその親クラスの構造を知る必要があります。

Example 6.9 は Example 6.8 から改良されており、Widget には getName という名前の保護されたメソッドが含まれていることに注意してください。ウィジェットが保護されたメソッドを呼び出そうとすると、エラーが発生します。$w1->getName() はエラーを生成します。ただし、Thing の getName メソッドは、ウィジェットがこの保護されたメソッドを呼び出すことができることを証明するには単純すぎます。 ::getName メソッドは保護されています。実際の状況では、保護されたメソッドを使用するには、オブジェクトの内部構造を理解する必要があります。
プライベート $価格;

パブリック関数 __construct($name, $price)
$this->name = $name;
$this->price = floatval($price); $this->id = uniqid();
}

// 2 つのウィジェットが同じかどうかを確認します
public function等しい ($widget)
{
return(($this->name == $widget->) ;name)AND
($this->price == $widget->price));

保護された関数 getName()
{
return($this->name);
クラス Thing はウィジェットを拡張します
{
private $color;

public function setColor($color)
{
$this-> ;color = $color
}

public function getColor()
{
return($this; ->color);
}

public function getName()
{
return(parent::getName())
}
}

$w1 = 新しいウィジェット('Cog', 5.00); = new Thing('Cog', 5.00);
$w2->setColor('Yellow');

// TRUE (まだ!) 結果は true です
if($w1->equals($w2) ))
{
print("w1 と w2 は同じです
n")
}

//print Cog 出力 Cog
print($w2->getName());サブクラスは親クラスのメソッドをオーバーライドすることでメソッドにアクセスする方法を変更できますが、パブリック クラスのメンバーをオーバーライドする場合は、そのサブクラス内でパブリックなままにする必要があります。プライベート メンバーは、保護されたままにすることも、パブリックにすることもできます。同じ親クラスでプライベート メンバーを宣言することもできます。したがって、技術的には、同じ名前のメンバーを作成することはできません。

Final キーワードは、メンバー メソッドへのアクセスを制限するもう 1 つの方法です。親クラスで Final としてマークされたメソッドをオーバーライドすることはできません。

//haohappy 注: PHP5 のオブジェクト指向モデルはまだ完全ではありません。たとえば、Java のようにデータ、メソッド、さらにはクラスに使用することはできません。
セクション 9 - バインディング

アクセスを制限するだけでなく、アクセス方法も決定します。サブクラスがどのメソッドを呼び出すか、またはサブクラスがどの属性にアクセスするか、関数呼び出しと関数自体の関係、メンバーアクセスと変数のメモリアドレスの関係、この関係をバインディングと呼びます

。コンピュータ言語におけるバインディングの方法 - 静的バインディングと動的バインディング。 静的バインディングは、プログラムの実行前にデータ構造とデータ構造の間で発生します。 コンパイル時には、関数呼び出しと関数本体が対象になります。 PHP は動的言語であるため、静的バインディングを使用しません。 ただし、動的バインディングは実行時に生成されるアクセス要求に対して使用され、実行時に利用可能な情報のみを使用します。指向のコードでは、動的バインディングとは、アクセス スコープではなく、クラス自体に基づいて、動的バインディングを使用して、PHP の以前のバージョンの関数と同様に動作することを意味します。これは、メソッドが、サブクラスのクラス メンバーでオーバーライドされ、サブクラスのインスタンスであるメソッドにアクセスする場合、(親クラスのメンバーにアクセスする代わりに) サブクラスのメンバーにアクセスすることを意味します。
例 6.10 を見てください。このコードは「Hey! I am Son」を出力します。これは、PHP が getSalutation を呼び出すと、Father の挨拶が上書きされるため、PHP は同じ結果を生成します。オーバーライドされたメソッドの動作は、Son ではそのメソッドに非常によく似ています。 access メソッド使用の原則に従って、クラス メンバーのアクセス制限を強化することは不可能であるため、アクセス メソッドを public から protected に変更することはできません。

リスト 6.10 動的バインディング 動的バインディング
PHP コード:
<。 ;?php
class Father
{
protected $salutation = "こんにちは!"; //ご挨拶

public function getSalutation()
{
print("$this->salutationn");

保護された関数identify()
{
print("I am Father.
n")
}
};

class Son extends Father
{
protected $salutation = " Hey!"; / /親クラスの protected $salutation は上書きされます

protected functionidentify() //親クラスの protectedidentify() は上書きされます
{
print("I am Son.
n");
}
};

$obj = new Son();
$obj->getSalutation(); //出力 こんにちは! 私は息子です。
?>
// 注: getSalutation()はサブクラスでオーバーライドされませんが、実際には、このクラスにはまだ getSalutation() が存在します
// は Son サブクラスのインスタンスの getSalutation() メソッドに動的にバインドされているため、getSalutation( Son インスタンスのメソッドが呼び出されます。
//Son クラスのメンバー salutation とidentify() が、親クラスのメンバー salutation とidentify() の代わりに呼び出されます。

プライベート メンバーは、クラス内にのみ存在します。 public メンバーや protected メンバーとは異なり、PHP は静的バインディングをシミュレートします。例 6.11 を参照してください。サブクラスが this-> の値をバインドします。現在のクラス Father への挨拶。同様の原則がプライベート メソッドidentify() に適用されます。

リスト 6.11 バインディングとプライベート メンバー
PHP コード:
class Father
{
private $salutation = "こんにちは!";

public function getSalutation()
{
print("$this->salutationn");
$this->identify();
}

private functionidentify()
{
print("私は父です.
n");
}
}

class Son extends Father
{
private $salutation = "Hey!";
private functionidentify()
{
print("私は息子です。
;n");
}
}

$obj = new Son();
$obj->getSalutation(); //出力 こんにちは! 私は父です。
?>
動的バインディングの利点は次のとおりです。例 6.12 を参照してください。動的バインディングを使用しているため、deleteUser で呼び出される isAuthorized のバージョンは型によって決まります。通常のユーザーの場合、PHP は User::isAuthorized を呼び出します。これが AuthorizedUser のインスタンスである場合、PHP は AuthorizedUser::isAuthorized を呼び出します。これにより、deleteUser がスムーズに実行されます。 : 一言でわかりやすく言うと、オブジェクト タイプ、メソッド、および属性のバインディングです。メソッドが親クラスとサブクラスの両方に存在する場合、または属性にアクセスする場合、インスタンスがどのオブジェクト タイプであるかを最初に決定します。

リスト 6.12 動的バインディングの利点
class User //User
{
protected function isAuthorized() //Is it認証されたユーザーですか?
{
return(FALSE);
}

public function getName() // 名前を取得します
{
return ($this->name)
}

public function deleteUser($username); // ユーザーを削除
{
if(!$this->isAuthorized())
{
print("あなたには権限がありません。
n");
return(FALSE)

//ユーザーを削除
print("ユーザーが削除されました。
n");
}
}

classized AuthorUser extends User // 認証されたユーザー
{
protected function isAuthorized() // isAuthorized() をオーバーライドします
{
return (TRUE);
}
}

$user = 新しいユーザー;
$admin = 新しい AuthorizedUser
$user->deleteUser("Zeev"); ->deleteUser("Zeev");
?>
なぜプライベート クラス メンバーは静的バインディングをシミュレートするのでしょうか? この質問に答えるには、なぜプライベート メンバーを代わりに使用する必要があるのか​​を思い出す必要があります。保護されたメンバーの数は?

プライベート メンバーは、子クラスに親クラスの動作を継承させたくない場合にのみ使用されます。これは思ったよりもまれですが、適切なオブジェクト階層では、ほとんどの機能がサブクラスによって特殊化、改良、または変更されます。 - これはオブジェクト指向プログラミングの基本の 1 つであり、サブクラスに親クラスの特定の部分を変更させたくない場合など、特定の状況でプライベート メソッドまたは変数が必要になります。
セクション 10 - 抽象メソッドと抽象クラス

オブジェクト指向プログラムは、クラスの階層構造を通じて構築されます。PHP などの単一継承言語では、クラスの継承は 1 つ以上のサブクラスを持ちます。そして、各サブクラスから 1 つ以上の下位レベルのサブクラスを継承します。もちろん、適切に設計されたシステムでは、複数のルート クラスがアプリケーションで使用できる便利なインターフェイスを持つ必要があります。アプリケーション コードがルート クラスで動作するように設計されている場合は、ルート クラスを継承するサブクラスでも動作します。

抽象メソッドは、サブクラス内の通常のメソッドのプレースホルダーと同じです (必要になります)通常のメソッドとは異なり、クラス内に 1 つ以上の抽象メソッドが存在する場合、そのクラスは抽象クラスをインスタンス化する必要があります。それらを継承してからサブクラスをインスタンス化することもできます。すべての抽象メソッドをオーバーライドすると、サブクラスは通常のクラスになります。クラスに抽象メソッドが含まれる場合 (たとえ 1 つしかない場合でも)、クラス キー Add abstract でクラスを抽象として宣言する必要があります。

抽象メソッドを宣言する構文は、一般的なメソッドを宣言する構文とは異なります。抽象メソッドは、一般的なメソッドのように中括弧 {} で囲まれた本体を持たず、セミコロンで終わります。

例では、6.13 で getArea メソッドを含むクラス Shape を定義しました。形状が分からずに Figure の領域を決定することは不可能であるため、getArea メソッドを抽象メソッドとして宣言しました。Shape オブジェクトをインスタンス化することはできませんが、それを継承したり、例 6.13 のように式で使用したりすることはできます。

抽象メソッドのみを含むクラスを作成する場合は、インターフェイスを定義します。この状況を説明するために、PHP には、抽象クラスの代わりにインターフェイスを使用し、extends の代わりに実装を使用してクラス定義を指定することができます。たとえば、myClass を実装して myIterface を作成できます。

/*注:
2 つのメソッドは、次のものを参照します。
1.は aaa の抽象メソッドのみで、一般メソッドはありません)
class bbb extends aaa{} (bbb メソッドの aaa の抽象メソッドを上書きします)
2. インターフェース aaa{}
class bbb は aaa{} を実装します (aaa の抽象メソッドをオーバーライドします) bbb)
*/

リスト 6.13 抽象クラス
PHP コード:
//抽象ルートクラス抽象ルートクラス
抽象クラス Shape
{
abstract function getArea() //抽象メソッドを定義します
}

//抽象子クラス
抽象クラス Polygon extends Shape //Polygon
{
abstract function getNumberOfSides();
}

//concrete クラス エンティティクラス 三角形クラス
class Triangle extends Polygon
{
public $base; public $height;

public function getArea() //面積計算メソッドをオーバーライドする
{
return(($this->base * $this->height)/2)
}

public function getNumberOfSides( ) //サイドカウントメソッドをオーバーライドします
{
return(3);
}
}

//具象クラス エンティティクラス 四角形
クラス Rectangle extends Polygon
{
public $height; getArea()
{
return($this->width * $this-> height)
}

public function getNumberOfSides()
{
}
}

//具体的なクラスエンティティクラス Circle
class Circle は Shape を拡張します
{
public $radius;

public function getArea()
{
return(pi() * $this->radius * $this->radius
}
}

//具体的なルートクラスはカラークラスを定義します
class Color
{
public $ name;
}

$myCollection = array() //シェイプのコレクションを作成して配列に入れます

//make四角形
$r = 新しい四角形;
$r -> 高さ = 7;
$myCollection($r);三角形
$t = 新しい三角形;
$t ->高さ = 5;
$myCollection($t);円
$c = 新しい円;
$c->radius = 3;
$c = 新しい色を作成します。 $c->name = "blue";
$myCollection[] = $c;

foreach($myCollection as $s)
{
if($s instanceof Shape) $s は Shape クラスのインスタンスです
{
print("Area: " . $s-> getArea() .
"
n");}

if($s ポリゴンのインスタンス)
{
print("サイド: " .
$s->getNumberOfSides() .
"
n")
}

if($s インスタンスオブカラー); )
{
print("Color: $s->name
n");
}

?>

PHP4 には、Java や COM と同様に、外部オブジェクト モデルへのマッピングを確立するためのオーバーロード構文が備わっており、プログラマーがカスタム動作を作成してメソッドを呼び出すことができるようになります。特別なメソッド __get、__set、および __call。Zend エンジンがメンバーにアクセスしようとして見つからない場合、PHP はこれらのメソッドを呼び出します。 例 6.14 では、必要に応じて、 __get と __set が属性変数配列へのアクセスを置き換えます。たとえば、スクリプトで属性値の設定を無効にしたり、特定のプレフィックスで開始したり、特定の種類の値を含めたりすることができます。

__call メソッドは、未定義のメソッドを呼び出す方法を示しています。未定義メソッドの場合、メソッド名とメソッドによって受け取られたパラメータは __call メソッドに渡され、PHP は __call の値を未定義メソッドに返します。

リスト 6.14 ユーザーレベルのオーバーロード
PHP コード:
< ?php
クラス オーバーローダー
{
private $properties = array();

function __get($property_name)
{
if(isset($this- >properties[$property_name]))
{
return($this) ->プロパティ[$プロパティ名]);
}
else
return(NULL);
}

関数 __set($プロパティ名, $値)
{
$this->プロパティ[$プロパティ名] = $value;
}

function __call($function_name, $args)
{
print("$function_name()
n" ); );

return(TRUE);
}
}
$o = new Overloader();

// __set() を呼び出すと、属性変数に値を割り当てることができます。 o->dynaProp = "動的コンテンツ";

//invoke __get() activate __get()
print($o->dynaProp . "
//invoke __call() __call() をアクティブにする
$o->dynaMethod("Leon", "Zeev");
?>
セクション 12 -- クラスの自動ロード

未定義のクラスを使用しようとすると、PHP は致命的なエラーを報告します解決策は、ファイルに含めることができるクラスを追加することです。ただし、PHP には、プログラミング時間を節約できるクラスの自動ロード機能が用意されています。 PHP は体系化されていないため、グローバル関数 __autoload を探します。この関数が存在する場合、PHP はクラス

を使用してそれを呼び出します。例 6.15 は、現在のディレクトリ内の各ファイルがどのように使用されるかを示しています。スクリプトがクラス User のインスタンスを生成しようとすると、PHP は __autoload を実行します。スクリプトは class_User.php に User クラスが定義されていると想定します。呼び出しが大文字か小文字かに関係なく、PHP は戻り値を返します。小文字の名前

リスト 6.15 クラスの自動ロード
PHP コード:
//自動ロード関数を定義します
function __autoload($class)
{
include("class_" . ucfirst($class) . ".php ");
}

//自動ロードする必要があるクラスを使用します
$u = new User;
$u->name = " Leon";
$u->printName();
?>
セクション 13 - オブジェクトのシリアル化

シリアル化では、オブジェクトを含む変数を連続バイト データに変換できます。逆シリアル化された変数は、クラスの場合は逆シリアル化されて元のデータに復元されます。クラスのオブジェクトを逆シリアル化する前に定義すると、PHP はそのオブジェクトのプロパティとメソッドを正常に保存できます。そのような目的で、PHP は自動的に __sleep と __wakeup を検索します。オブジェクトがシリアル化されると、PHP は __sleep メソッドを呼び出します (存在する場合)。オブジェクトを逆シリアル化した後、PHP は __wakeup メソッドを呼び出します。どちらのメソッドも必要な属性を含む配列を返す必要はありません。 __sleep メソッドを使用しない場合、PHP は他の属性を破棄します。例 6.16 は、__sleep メソッドと __wakeup メソッドを使用してオブジェクトをシリアル化する方法を示しています。 __sleep メソッドは、シリアル化されたオブジェクトに id 属性が含まれないようにします。この例は、User オブジェクトを逆シリアル化するときに、id 属性の新しい値を確立するように設計されています。実際の開発では、リソースのオブジェクト (画像やデータ ストリームなど) がこれらのメソッドを必要とする場合があります。 $name;
public $id;

function __construct( )
{
//ユーザーに固有の ID を与える
$this->id = uniqid()
}

function __sleep()
{
//this->id をシリアル化しない
return(array("name"));
} function __wakeup()
{
//ユーザーに一意の ID を与える
$this- > ;id = uniqid();
}
}

//create object オブジェクトを作成します
$u = new User;
$u->name = "Leon"

//シリアル化に関する注意事項属性はシリアル化されておらず、id の値は破棄されます
$s = Serialize($u);

//シリアル化解除された ID は再割り当てされます
$u2 = unserialize($s)// $u と$u2 は異なる ID を持ちます $u と $u2 は異なる ID を持ちます
print_r($u);
print_r($u2);
セクション 14--名前空間

クラスでは非常に困難です。変数の名前は理解しやすいものである必要があることに加えて、その名前が他の場所で使用されていないかどうかも考慮する必要があります。2 番目の問題は、変数の再利用を考えるときの基本的な問題です。この後、プロジェクト コードでは、使用した名前の使用を避ける必要があります。一般的に、再利用可能なコードは常に関数またはクラスに含まれており、発生する可能性のある多くの名前の競合に対処する必要があります。すべてのクラスにプレフィックスを付けることでこれを回避することもできます。または、コード ブロックの外側で

Namespace キーワードを使用して、次の演算子を使用してこのコード ブロックを参照する必要があります。 : 名前空間の名前が続きます。同じメソッドが静的クラスのメンバーを参照するために使用されます。名前空間内のコードは名前空間を宣言する必要がなく、このメソッド自体がプレフィックスを追加するよりも優れています。階層型 (ネストされた) 名前空間を作成できるかどうか疑問に思われるかもしれませんが、スペース名の後にコロンを追加すると、コロンなしで変数、関数、クラスを再度呼び出すことができます。名前内のコロンは、最初と最後の文字でない限り、または別のコロンの後に続く限り、名前空間内で使用できます。 PHP ではコロンは意味を持ちませんが、論理ブロックを区別するために使用する場合は使用できます。コード内の親子関係をわかりやすく説明します


/* 注: つまり、次のように使用できます。
namespace Animal:dog {}
namespace animeig {}

親を示すにはコロンを使用します。子関係。
*/


名前空間ステートメントに関数、クラス、または定数の定義を含めることはできません。これにより、グローバル変数を使用する古いライブラリを改造するためにそれらを使用できなくなります。名前空間はオブジェクトに最適です。名前空間内の定数は、クラス内の定数と同じ構文を使用します。

例 6.17 は、名前空間の使用方法を示しています。

リスト 6.17 名前空間の使用
PHP code:
namespace core_php:utility
{
class textEngine
{
public function uppercase($text) //uppercase
{
return( strtoupper($text));
}
}

//非 OO インターフェースを作成する
function uppercase( $text)
{
$e = new textEngine;
return($e->uppercase($text));
}

}

//名前空間のクラスをテストします
$e = new core_php:utility::textEngine;
print($e->uppercase("from object") . "
");

//名前空間の関数をテストします
print(core_php) :utility::uppercase("from function") . "
");

//クラスをグローバル名前空間にインポートします
import class textEngine from core_php:utility
$e2 = new textEngine;
?>
Import ステートメントは、名前空間の特定の部分をグローバル名前空間にインポートします。
単一の名前空間のメンバーをインポートするには、型を定数、関数、またはクラスとして指定し、メンバーの名前を記述します。 //たとえば、クラス XXX をインポートします
特定の型のすべてのメンバーをインポートしたい場合は、名前を * で置き換えることができます;
//たとえば、import constant * はすべての定数をインポートします
すべてのメンバーをインポートしたい場合すべてのタイプの場合は、* を使用します。
//たとえば、import *

メンバーの後に、from キーワードを使用します。 名前空間の名前を追加します。
//たとえば、 import class textEngine from core_php:utility;

Inつまり、例 6.17 のように、 import * from myNamespace または import class textEngine from core_php:utility のようなステートメントを作成する必要があります。

セクション 15 - Zend エンジンの開発

この章の最後のセクションでは、Zeev が説明しています。 Zend Engine によってもたらされたオブジェクト モデルについて説明し、PHP の以前のバージョンのモデルとどのように異なるのかについて具体的に説明します。 1997 年の夏に、私たちは PHP をオブジェクト指向にする計画はありませんでした。当時、PHP3 は純粋な手続き型言語でした。しかし、1997 年 8 月 27 日の夜、PHP に新しい機能が追加されました。当時は PHP を研究する人が少なすぎたので、最小限の議論しかありませんでした。そこで 1997 年 8 月から、PHP はオブジェクト指向プログラミングへの一歩を踏み出しました。

。実際、これは最初のステップにすぎません。この設計には関連するアイデアがほとんどないため、このバージョンでのオブジェクトの使用は、配列にアクセスするための優れた方法に過ぎません。 bar"] を使用する場合は、より見栄えの良い $foo->bar を使用できます。オブジェクト指向アプローチの主な利点は、メンバー関数またはメソッドを通じて機能を保存できることです。典型的なコード ブロックを例 6.18 に示します。実際、例 6.19 のアプローチと大きな違いはありません。何らかの値";
function PrintValue()
{
print $this->value;
}
}
$obj = new Example();
$obj->PrintValue();
?>
リスト 6.19 PHP 3 構造プログラミング PHP3 PHP3 の構造プログラミング
PHP コード:
function PrintValue($arr)
{
print $arr["value"]
}

function CreateExample()
{
$ arr; ["value"] = "何らかの値";
$arr["PrintValue"] = "PrintValue";

$arr = CreateExample()//PHP の間接参照を使用します
$arr["PrintValue"]($arr);
?>
上記では、クラスに 2 行のコードを記述するか、明示的に配列を関数に渡していますが、PHP3 ではこれら 2 つのオプションに違いはありません。オブジェクト モデルは、配列にアクセスするための「構文上の光沢」としてのみ使用できます。

オブジェクト指向開発に PHP を使用したい人、特にデザイン パターンを使用したい人は、幸いにもすぐに壁にぶつかります。当時 (PHP3 時代)、オブジェクト指向開発に PHP を使用したいと考えている人は多くありませんでした。

PHP4 は、PHP のさまざまな側面を可能にする参照の概念を導入し、同じアドレスを指しました。これは、例 6.20 のように、同じ変数に複数の名前を使用できることを意味します。
//$b は $a と同じメモリ内の場所を指します $b と $a はメモリ内の同じアドレスを指します
$b = &$a;

/ /$a は次のとおりであるため、$b を変更しますChange $b を指すと、指すアドレスが変わります
//同じ場所が変わります $a が指すアドレスも変わります
$b = 7;

//prints 7 Output 7
print $a; ?>
相互に参照するオブジェクトのネットワークの構築はすべてのオブジェクト指向設計パターンの基礎であるため、参照によってより強力なオブジェクト指向アプリケーションを作成できる場合、オブジェクトを扱う PHP のアプローチは非常に重要です。他の種類のデータと同様に、PHP4 プログラマーなら誰でも言うように、アプリケーションは WTMA (アンパサンドが多すぎる) 症候群に悩まされることになります。実用的なアプリケーションを構築したい場合は、非常に苦痛を感じることになるでしょう。例 6.21 を見れば理解できると思います。

リスト 6.21 PHP 4 のオブジェクトの問題

1 class MyFoo {
2 function MyFoo( )
3 {
4 $this->me = &$this;
5 $this->value = 5;
6 }
7
8 関数 setValue($val)
9 {
10 $this->value = $val
11 }
12
13 関数 getValue()
14 {
15 $this->値を返す
16 }
17
18 関数 getValueFromMe()
19 {
20 $this->me->値を返す
21 }
22 }
23
24 function CreateObject($class_type)
25 {
26 switch ($class_type) {
27 case "foo":
28 $obj = new MyFoo( );
30 case "bar":
31 $obj; = new MyBar();
33 }
34 return $obj;
36
37 $global_obj = CreateObject ("foo ");
39
40 print "値は " . $global_obj->getValue() . "n";




まず、コンストラクターに MyFoo クラスがあり、$this->me に参照を与えて
us を設定します。1 つは this->value の値を設定します。 this->value; の値を返し、もう 1 つは this->value->me の値を返します。しかし、 --$this は同じではありません:: getValue() と MyFoo::getValueFromMe() は同じですか?

まず、MyFoo 型のオブジェクトを返す CreateObject("foo") を呼び出します。次に、MyFoo::setValue(7) を呼び出します。 MyFoo::getValue() と MyFoo::getValueFromMe() は、戻り値 7 を取得することを期待しています。
もちろん、いずれにしても 7 を取得した場合、上記の例は、この本の中で最も意味のない例です。ご想像のとおり、7 が 2 つもありません

しかし、どのような結果が得られるのでしょうか、そしてさらに重要なのは、その理由です。得られる結果はそれぞれ 7 と 5 です。理由としては 3 つあります。まず、コンストラクター内で this と this->me の間の参照を確立します。 、 this と this->me は同じものですが、コンストラクターが終了すると、PHP はオブジェクト (new MyFoo の 28 行目) を再作成し、それを $obj に割り当てる必要があります。オブジェクトは他のデータ型と同様に特別なものとして扱われません。X を Y に代入すると、Y は X のコピーになります。つまり、obj は新しい MyFoo のコピーになり、新しい MyFoo はオブジェクトになります。 >me? これは参照であるため、元のオブジェクトを指しています。これは、もう同じものではありません。一方を変更し、もう一方を変更しないでください。

上記は、 1 つ目の理由は、奇跡的にオブジェクトのインスタンス化の問題 (28 行目) を克服することになりますが、依然として同じ問題が発生します。戻り値のコピー、そして再び、global_object と global_object->me は同じではなくなります

しかし、実際には、まだそこまではできません。CreateObject が $obj を返したら、参照を破棄します (34 行目)。これが 3 番目の理由です。では、これを修正するには 2 つのオプションがあります (例 6.22 の 24、28、31 行目)。 2. 幸運にも PHP5 を使用できる場合は、上記のことをすべて忘れても構いません。PHP5 がこれらの問題をどのように考慮するかを知りたい場合は、リスト 6.22 を読んでください。 PHP 4 の WTMA シンドローム PHP4 の WTMA シンドローム

1 class MyFoo {
2 function MyFoo()
3 {
4 $this->me = &$this;
5 $this->value = 2; }
7
8 関数 setValue($val)
9 {
10 $this->value = $val;
11 }
12
13 function getValue()
14 {
15 return $this->value;
16 }
17
18 関数 getValueFromMe()
19 {
20 $this->me->value;
21 }
22 };
23
24 関数 &CreateObject($class_type)
25 {
26 switch ($class_type) {
27 case "foo":
28 $obj =& new MyFoo();
30 case "bar":
31 $obj =& new MyBar();
33 }
34 return $obj;
35 }
36
37 $global_obj =& CreateObject ("foo");
38 $global_obj ->setValue(7);
39
40 print "値は " です。 global_obj->getValue() . "n";
41 print "Value is " . $global_obj->getValueFromMe() . "n ";



PHP バージョンは他のものとは異なりますユーザーの観点から見ると、これは非常に明らかです。PHP5 では、オブジェクトは常に参照によって渡されますが、他のタイプのデータ (整数、文字列、配列など) は値によって渡されます。オブジェクトを参照で渡すことを示すために & 記号を使用する必要はありません。

オブジェクト指向プログラミングでは、オブジェクト ネットワークとオブジェクト間の複雑な関係を幅広く使用しますが、以前のバージョンの PHP では参照を使用する必要がありました。したがって、オブジェクトの移動にはデフォルトで参照が使用され、明示的にコピーが要求された場合にのみオブジェクトがコピーされるようになりました。これは、以前よりも優れています。

すべての値はどのように実装されていますか?これらの値は、zval (Zend Value) と呼ばれる特別な構造体に格納され、値が渡される場合は、数値や文字列などの単純な値、または配列やオブジェクトなどの複雑な値に格納できます。関数に送られるか、関数から返されると、これらの値はコピーされ、メモリ内の別のアドレスに同じ内容の構造体が作成されます。PHP5 では、オブジェクトを除き、値は引き続き zval 構造体に格納されます。オブジェクトはオブジェクトストアと呼ばれる構造体で存在しており、それぞれのオブジェクトは異なるIDを持ちます。Zvalではオブジェクトそのものは格納されませんが、永続的なオブジェクトをコピーする際にオブジェクトのポインタが格納されます。たとえば、オブジェクトをパラメータとして関数に渡す場合、同じオブジェクト ポインタを保持し、オブジェクト自体が配置されているため、この特定のオブジェクトが現在ポイントしていることをオブジェクト ストアに通知します。この追加の間接化により、PHP オブジェクトは、透明性と効率的な方法を使用して、常に参照によって渡されているかのように見えます。例 6.21 に戻って、すべてのアンパサンドを削除しても、コンストラクター (4 行目) でアンパサンドを保持してもすべて正常に動作します。








関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート