この記事は主に、PHP オブジェクトに関する知識をまとめた関連情報を紹介していますので、必要な方は参考にしてください。これは、エイリアス (識別子) ) 転送です。つまり、それらはすべて、同じオブジェクトの実際のコンテンツを指す同じ識別子 (ID) のコピーを保存します。
<?php class A { public $foo = 1; } $a = new A; $b = $a; // $a ,$b都是同一个标识符的拷贝 // ($a) = ($b) = <id> $b->foo = 2; echo $a->foo."\n";//2 $c = new A; $d = &$c; // $c ,$d是引用 // ($c,$d) = <id> $d->foo = 2; echo $c->foo."\n";//2 $e = new A; function foo($obj) { // ($obj) = ($e) = <id> $obj->foo = 2; } foo($e); echo $e->foo."\n";//2
•オブジェクトのコピー: 元のオブジェクトが __clone() メソッドを定義している場合、コピー後に新しいオブジェクトの __clone() メソッドが呼び出されます。 ) メソッドを使用して、コピーされたオブジェクトのプロパティの値を変更できます。オブジェクトがコピーされると、オブジェクトのすべてのプロパティに対して浅いコピーが実行されますが、すべての参照プロパティは元の変数への参照のままです。
<?php class SubObject { static $instances = 0; public $instance; public function __construct() { $this->instance = ++self::$instances; } public function __clone() { $this->instance = ++self::$instances; } } class MyCloneable { public $object1; public $object2; function __clone() { // 强制复制一份this->object, 否则仍然指向同一个对象 $this->object1 = clone $this->object1; } function cloneTest() { echo 'cloneTest'; } } $obj = new MyCloneable(); $obj->object1 = new SubObject(); $obj->object2 = new SubObject(); $obj2 = clone $obj; print("Original Object:\n"); print_r($obj); print("Cloned Object:\n"); print_r($obj2); echo $obj2->cloneTest().":\n"; echo (new Reflectionclass($obj2));
上記の例の出力結果:
Original Object: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 1 ) [object2] => SubObject Object ( [instance] => 2 ) ) Cloned Object: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 3 ) [object2] => SubObject Object ( [instance] => 2 ) ) cloneTest: Class [ <user> class MyCloneable ] { @@ /public/t.php 18-33 - Constants [0] { } - Static properties [0] { } - Static methods [0] { } - Properties [2] { Property [ <default> public $object1 ] Property [ <default> public $object2 ] } - Methods [2] { Method [ <user> public method __clone ] { @@ /public/t.php 23 - 27 } Method [ <user> public method cloneTest ] { @@ /public/t.php 29 - 32 } } }
•オブジェクトの走査: foreach はオブジェクトの表示されているプロパティのみを走査できますが、そのメソッドを走査することはできません。これは実装が容易です。さらに、Iterator インターフェイスを実装することもできます。または、IteratorAggregate インターフェイスのメソッドがオブジェクトのプロパティを走査することもできます。
•型制約: PHP は弱い型指定言語であり、型制約によりプログラミングがより標準化され、エラーが軽減されます。型制約はオブジェクト定義だけでなく関数定義でも使用できます。型制約は、オブジェクト、インターフェイス、配列、および呼び出し可能オブジェクト (クロージャ コールバック) を指定できます。ただし、型制約は、実際のデータ型がプロトタイプ定義と一致していることを確認するために使用されます。デフォルト値は NULL です。その場合、実際のパラメータは NULL にすることができます。型制約は、int や string などのスカラー型には使用できません。また、特性も使用できません。
•オブジェクトのシリアル化と復元: 関数 Serialize() は、バイト ストリームを含む文字列をオブジェクトを簡単に保存できる文字列に変換でき、関数 unserialize() は文字列をオブジェクトに復元できます。ただし、シリアル化または逆シリアル化に関係なく、オブジェクトのクラス定義が完了している、つまりクラス (ファイル) を最初にインポートする必要があるという前提があります。
• オーバーロード: PHP のオーバーロードには、一般的なオーバーロード構文の仕様がサポートされておらず、より広範な影響を与えるクラス プロパティまたはメソッドが含まれます。現在の環境では未定義または非表示です。すべてのオーバーロードされたメソッドは public に宣言する必要があり (これは理解しやすいはずです。他のメソッドは目に見えないために必要になる可能性があるため、あなたは表示される必要があります)、パラメータを参照によって渡すことはできません (おそらくセキュリティ上の理由から、オーバーロードされたメソッドは予測できません)。変数が任意に参照されるのを防ぎます)。オーバーロードされたプロパティは、isset() 以外の他の言語構造では使用できません。つまり、オーバーロードされたプロパティで empty() が使用される場合、オーバーロードされたマジック メソッドは呼び出されず、この制限を回避するには、オーバーロードされた属性をローカル変数に割り当てる必要があります。そして empty() が使用されると、正当な属性と不正な属性の間にオーバーロードされた属性が存在することがわかります。
[プロパティのオーバーロード]: これらのメソッドは静的として宣言できません。静的メソッドでは、アクセスできないプロパティに値を割り当てる場合、これらのマジック メソッドは呼び出されません。 () が呼び出されます
publicmixed __get ( string $name )
アクセスできないプロパティの値を読み取るとき、__get() が呼び出されます
アクセスできないプロパティで呼び出されるときisset() または empty() の場合、__isset() が呼び出されます
アクセスできないプロパティに対して unset() が呼び出される場合、__unset() が呼び出されます
PHP代入操作が処理される方法では、__set() の戻り値は無視されます。同様に、次のチェーン代入では、__get() は呼び出されません:
$a = $obj->b = 8;
[メソッドのオーバーロード]:
publicmixed__call(string$name,array$arguments)
アクセスできないメソッドがオブジェクト内で呼び出される場合、__call() が呼び出されます
public staticmixed __callStatic ( string $name , array $arguments )
アクセスできないメソッドが静的コンテキスト内で呼び出される場合、__callStatic() が呼び出されます
•后期静态绑定:static:: 定义后期静态绑定工作原理是存储了上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类;static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的,可以用于静态属性和所有方法的调用。
<?php class A { private $proPrivate = "private of A"; protected $proProtected = "protected of A"; public $proPublic = "public of A"; private function foo() { echo $this->proPrivate."\n"; echo $this->proProtected."\n"; echo $this->proPublic."\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* foo() will be copied to B, hence its scope will still be A and * the call be successful */ } class C extends A { private $proPrivate = "private of C"; protected $proProtected = "protected of C"; public $proPublic = "public of C"; private function foo() { /* original method is replaced; the scope of the new one is C */ echo "I am C\n"; } public function myFoo() { //parent::foo(); $this->foo(); } } echo "Class B:\n"; $b = new B(); $b->test(); echo "\nClass C:\n"; $c = new C(); $c->myFoo(); $c->test(); //fails
上例输出结果:
Class B: private of A protected of A public of A private of A protected of A public of A Class C: I am C private of A protected of C public of C Fatal error: Uncaught Error: Call to private method C::foo() from context 'A' in /public/t.php:19 Stack trace: #0 /public/t.php(54): A->test() #1 {main} thrown in /public/t.php on line 19
•继承:官方文档对继承有这样一段描述“当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能”,言下之意似乎私有属性和方法不会被继承;然而上例又告诉我们子类拥有与父类一致的属性和方法,继承就是全盘复制,这才能满足我们对继承编程的需求,如果私有的不能继承,子类就必须自行重新定义,在大多数时候没有必要。另外就是可见性问题,父类的私有属性和方法在子类是不可见的。上例还告诉我们对象实际执行的域要考虑可见性、继承、后期静态绑定机制。
以上就是本文的全部内容,希望对大家的学习有所帮助。
相关推荐:
以上がPHP オブジェクトの知識の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。