在抽象类中声明的方法中从子级获取常量覆盖

发布于 2024-12-13 12:19:44 字数 603 浏览 2 评论 0原文

我有这个(缩短):

abstract class MyModel
{
    const DBID = "";
    const TOKEN = "";

    public function getDB()
    {
        if(!$this->_DB)
        {
            $c = get_called_class(); // doesn't work pre php 5.3
            echo $c::DBID; // doesn't work pre php 5.3
            echo $c::TOKEN // doesn't work pre php 5.3
        }

        return $this->_qb;
    } 

问题是 get_ Called_class() 并且 $c::DBID/TOKEN 在 php 中不起作用 < 5.3

有没有一种方法可以在与 5.2.9 兼容的抽象类中完成相同的任务?

I have this (shortened):

abstract class MyModel
{
    const DBID = "";
    const TOKEN = "";

    public function getDB()
    {
        if(!$this->_DB)
        {
            $c = get_called_class(); // doesn't work pre php 5.3
            echo $c::DBID; // doesn't work pre php 5.3
            echo $c::TOKEN // doesn't work pre php 5.3
        }

        return $this->_qb;
    } 

The problem is that get_called_class() and the $c::DBID/TOKEN doesn't work in php < 5.3

Is there a way I can accomplish the same task from within the abstract class that is compatible with 5.2.9?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

十级心震 2024-12-20 12:19:44

编辑:
常量实际上并不意味着在对象实例化过程中进行更改,您可能需要考虑成员变量。

抽象类不能直接实例化。您可以创建一个子类来扩展您的抽象类,然后调用 getDb()。

abstract class MyModel
{
    private $dbId;
    private $token;

    public function setDbId($dbId)
    {
        $this->dbId = $dbId;
    }

    public function setToken($token)
    {
        $this->token = $token;
    }

    public function getDbId()
    {
        return $this->dbId;
    }

    public function getToken()
    {
        return $this->token;
    }

    public function __construct()
    {
        // All child classes will have the same values
        $this->setDbId('myParentDbId');
        $this->setToken('myParentToken');
    }

    protected function getDb()
    {
        echo $this->getDbId();
        echo $this->getToken();
    }
}

class MyChildModel extends MyModel
{
    // Don't need any methods, just access to abstract parent
    // But if I wanted to override my parent I could do this
    public function __construct()
    {            
        parent::__construct();

        $this->setDbId('myChildDbId');
        $this->setToken('myChildToken');
    }
}

$myChildModel = new MyChildModel();
var_dump($myChildModel->getDb());

EDIT:
Constants aren't really meant to be changed throughout object instantiations, you may want to consider member variables instead.

Abstract classes cannot be instantiated directly. You could create a child class to extend your abstract class, then make the call to getDb().

abstract class MyModel
{
    private $dbId;
    private $token;

    public function setDbId($dbId)
    {
        $this->dbId = $dbId;
    }

    public function setToken($token)
    {
        $this->token = $token;
    }

    public function getDbId()
    {
        return $this->dbId;
    }

    public function getToken()
    {
        return $this->token;
    }

    public function __construct()
    {
        // All child classes will have the same values
        $this->setDbId('myParentDbId');
        $this->setToken('myParentToken');
    }

    protected function getDb()
    {
        echo $this->getDbId();
        echo $this->getToken();
    }
}

class MyChildModel extends MyModel
{
    // Don't need any methods, just access to abstract parent
    // But if I wanted to override my parent I could do this
    public function __construct()
    {            
        parent::__construct();

        $this->setDbId('myChildDbId');
        $this->setToken('myChildToken');
    }
}

$myChildModel = new MyChildModel();
var_dump($myChildModel->getDb());
梦中楼上月下 2024-12-20 12:19:44

我在 PHP 5.2 代码库中有一个解决方案,它使用反射从超类获取子类的常量,但我建议不要这样做,除非绝对必要,因为就性能而言,反射是 PHP 中相对昂贵的工具。

PHP 5.3 引入了 static 关键字,如 static::CONST 而不是 self::CONST 来访问类的静态成员。我从未真正尝试过,但我相信它应该能够满足您的需求。在 PHP 手册中查找最新的静态绑定。

作为记录,下面是使用反射获取子类常量的方法的代码。

class SomeClass
{
    /**
     * Get reflection class for item
     * 
     * Get a reflector for this item so that internal constants can be used for the permission checking
     * functions.  This is necessary because of how static binding works prior to PHP 5.3.  
     * 
     * @return ReflectionClass
     */
    protected function getRef ()
    {
        if (!$this -> ref)
        {
            $this -> ref    = new ReflectionClass ($this);
        }
        return ($this -> ref);
    }

    /**
     * Check that the user has permission to create an item of the type this object represents
     *
     * @todo Use late static binding instead of reflection once PHP 5.3 becomes available on the server
     * @return bool True if OK
     */
    public function canCreate ()
    {
        $ref    = $this -> getRef ();
        if ($flag = $ref -> getConstant ('USR_FLAG_CREATE'))
        {
            return (self::$user -> permissions [$flag]);
        }
    }
}

I had a solution in a PHP 5.2 codebase that used reflection to get at the constants of a subclass from a superclass, but I'd advise against doing that unless it's absolutely necessary because reflection is q relatively expensive tool in PHP in terms of performance.

PHP 5.3 introduced the static keyword as in static::CONST instead of self::CONST to access static members of a class. I've never actually tried it but I believe it should be able to do what you need. Look up late static binding in the PHP manual.

For the record, here's the code for a method that used reflection to get a subclass constant.

class SomeClass
{
    /**
     * Get reflection class for item
     * 
     * Get a reflector for this item so that internal constants can be used for the permission checking
     * functions.  This is necessary because of how static binding works prior to PHP 5.3.  
     * 
     * @return ReflectionClass
     */
    protected function getRef ()
    {
        if (!$this -> ref)
        {
            $this -> ref    = new ReflectionClass ($this);
        }
        return ($this -> ref);
    }

    /**
     * Check that the user has permission to create an item of the type this object represents
     *
     * @todo Use late static binding instead of reflection once PHP 5.3 becomes available on the server
     * @return bool True if OK
     */
    public function canCreate ()
    {
        $ref    = $this -> getRef ();
        if ($flag = $ref -> getConstant ('USR_FLAG_CREATE'))
        {
            return (self::$user -> permissions [$flag]);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文