Ответ 1
Для всех, кого это интересует, вот хороший ответ с длинным объяснением.
Наслаждайтесь!
Я родом из мира .NET. Теперь войдите в эти фригидные воды php.
Я нашел пример, который немного озадачил меня. Конечно, я пытаюсь применить основы ООП к этому 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) все, что он делает, создает статический новый экземпляр пользователя. Это первое, что меня насторожило.
В .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;
}
Мне кажется, что он динамически добавляет параметры в Object, который будет доступен пользователю через соответствующие параметры.
Имеет смысл?
С моей точки зрения .net $this в Object ссылается на экземпляр объекта, а не на экземпляр пользователя, наследующий его (как говорит мой друг). Я сказал ему, что нарушение основных принципов ООП и это просто невозможно.
Кто-нибудь, кто мог бы мне понять об этом?
Спасибо.
Для всех, кого это интересует, вот хороший ответ с длинным объяснением.
Наслаждайтесь!
В 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
Теперь во вторую часть вашего вопроса
С точки зрения my.net, $this в Object ссылается на экземпляр объекта непосредственно, а не на экземпляр пользователя, наследующий его (как говорит мой друг). Я сказал ему, что нарушение основных принципов ООП и это просто невозможно.
$это относится к фактическому объекту, независимо от класса, из которого был создан объект. Вы можете сделать это и в .NET, хотя вам нужно будет отбросить ваш объект. Но для PHP, где нет сильной типизации, объект представляет себя как есть, и вы можете использовать его как есть.