Php继承,动态属性和新的static()构造函数

时间:2014-02-28 23:35:07

标签: c# php .net yii

我来自.NET世界。现在进入这些寒冷的php水域。

我找到一个让我有点困惑的例子。当然,我正在尝试将OOP基础应用于这个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,在一个参数中是一个数组(上面数组的一个元素)。 / p>

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

但是,这个类在它的构造函数中,正在调用Yii :: configure($ this,$ config),在这个方法中,我看到它的方式,Yii正在添加$ this(我假设的Object实例,不是用户一)属于用户的参数。

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

在我看来,它正在向Object动态添加参数,User将通过匹配的参数访问它。

有道理吗?

从我的.net角度来看,对象中的 $ this 指的是Object实例本身,而不是继承自它的User实例(就像我的朋友所说)。我告诉他,这违反了基本的OOP原则,而且根本不可能。

任何可以让我理解这一点的人?

谢谢。

2 个答案:

答案 0 :(得分:1)

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角度来看,Object中的$ this指的是Object实例本身,而不是继承自它的User实例(就像我的朋友所说)。我告诉他,这违反了基本的OOP原则,而且根本不可能。

$ this引用实际对象,无论对象是从哪个类实例化的。您也可以在.NET中执行此操作,但您需要转换对象。但是为了没有强类型的PHP,对象呈现为原样,您可以按原样使用它。

答案 1 :(得分:1)

对于任何有兴趣的人,这是一个很好的答案,有一个冗长的解释。

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

享受!