Наследование Php, динамические свойства и новый статический () конструктор

Я родом из мира .NET. Теперь войдите в эти фригидные воды.

Я нашел пример, который немного озадачил меня. Конечно, я пытаюсь применить основы ООП к этому php-коду, но это не имеет смысла.

Это класс, о котором я говорю.

<?php namespace app\models; class User extends \yii\base\Object implements \yii\web\IdentityInterface { public $id; public $username; public $password; public $authKey; private static $users = [ '100' => [ 'id' => '100', 'username' => 'admin', 'password' => 'admin', 'authKey' => 'test100key', ], '101' => [ 'id' => '101', 'username' => 'demo', 'password' => 'demo', 'authKey' => 'test101key', ], ]; public static function findIdentity($id) { return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; } public static function findByUsername($username) { foreach (self::$users as $user) { if (strcasecmp($user['username'], $username) === 0) { return new static($user); } } return null; } public function getId() { return $this->id; } public function getAuthKey() { return $this->authKey; } public function validateAuthKey($authKey) { return $this->authKey === $authKey; } public function validatePassword($password) { return $this->password === $password; } } 

Хорошо, для меня очевидно, что в методе findByIdentity ($ id) все, что он делает, это создание статического нового экземпляра User. Это первое, что меня насторожило.

В .net вы не можете создать экземпляр статического класса.

Теперь, двигаясь дальше. в этой строке

 return isset(self::$users[$id])? new static(self::$users[$id]) : null; 

второе, что меня интригует, следующее.

Поскольку все, что у вас есть в этом массиве, – это набор ключей / значений ….

 private static $users = [ '100' => [ 'id' => '100', 'username' => 'admin', 'password' => 'admin', 'authKey' => 'test100key', ], '101' => [ 'id' => '101', 'username' => 'demo', 'password' => 'demo', 'authKey' => 'test101key', ], ]; 

как php определяет, что он должен создать объект User? Отражение? Это приводит меня к следующему вопросу … глядя на класс, который он наследует от Object в конструкторе, есть один параметр, который является массивом (одним из элементов массива выше).

 public function __construct($config = []) { if (!empty($config)) { Yii::configure($this, $config); } $this->init(); } 

НО, этот класс в своем конструкторе вызывает Yii :: configure ($ this, $ config), и в этом методе, как я его вижу, Yii добавляет к $ this (экземпляр объекта, который я предполагаю, а не пользовательский ) параметры, которые принадлежат пользователю.

 public static function configure($object, $properties) { foreach ($properties as $name => $value) { $object->$name = $value; } return $object; } 

Мне кажется, что это динамически добавляет параметры к объекту, который будет доступен пользователю через соответствующие параметры.

Имеет смысл?

С точки зрения моего .net, $ this в Object ссылается на экземпляр Object, а не на экземпляр пользователя, наследующий его (как говорит мой друг). Я сказал ему, что это нарушение основных принципов ООП, и это просто невозможно.

Кто-нибудь, кто может заставить меня понять об этом?

Спасибо.

Related of "Наследование Php, динамические свойства и новый статический () конструктор"

Для всех, кого это интересует, вот хороший ответ с длинным объяснением.

http://forums.phpfreaks.com/topic/286702-php-inheritance-dynamic-properties-and-new-static-constructor/

Наслаждайтесь!

В PHP нет такого понятия, как статический класс, в нем могут быть статические методы и статические члены. Но каждый класс может быть создан. Однако вы можете использовать исключение в конструкторе.

Теперь … по ключевому слову static. В контексте, который вы используете, он вызывает конструктор позднего статически связанного класса. Вот код, который поможет вам.

 class Something { public static function getInstance() { return new static(); } } class Other extends Something { } 

Когда вы вызываете getInstance из контекста Other , то, что getInstance делает, вызывает конструктор для класса Other

 // this will print `Other` echo get_class(Other::getInstance()); 

Кроме того, поскольку вы наследуете из класса yii\base\Object и вы не определяете конструктор в User , вызывающий конструктор является тем, который вызывается в yii\base\Object


Теперь во вторую часть вашего вопроса

С точки зрения моего .net, $ this в Object ссылается на экземпляр Object, а не на экземпляр пользователя, наследующий его (как говорит мой друг). Я сказал ему, что это нарушение основных принципов ООП, и это просто невозможно.

$ this ссылается на фактический объект, независимо от класса, из которого был создан объект. Вы можете сделать это и в .NET, хотя вам нужно будет отбросить ваш объект. Но для PHP, где нет сильной типизации, объект представляет себя как есть, и вы можете использовать его как есть.