思考实现:基于常量而不反射实例化类

时间:2013-11-29 04:40:27

标签: php class inheritance

第二次更新

我想我一直在从硬币的错误方面接近这个问题。我是否应该正确地假设我应该将'First'作为一个抽象类,并且稍后找到一种方法来引用'Second'和'Third'?

更新

根据一些反馈,我添加了一些内容来尝试清理我想要做的事情。类似于这种效果的东西。

我只是看下面的代码就知道了,如果它确实有效并且因为没有,那就是浪费性能,知道我从错误的角度接近问题。最终目标不是所有在我使用的一些框架中都不常见。

我更倾向于在CodeIgniter方法上建立这一特定代码,你可以在配置文件中定义(下面是)STR_CLASS_NAME,然后在任何时候通过程序的操作,使用它,因为我有决定。

STR_CLASS_NAME = 'Second';

class First {
    protected $intTestOne = 100;

    public function __construct() {
         $strClassName = STR_CLASS_NAME;
         return new $strClassName();
    }

    public function TestOne() {
        echo $this->intTestOne;
    }

    protected function TestThreePart() {
        return '*Drum ';
    }
}

class Second extends First{
    /* Override value to know it's working */
    protected $intTestOne = 200;

    /* Overriding construct to avoid infinite loop */
    public function __construct() {}

    public function TestTwo() {
        echo 'Using method from extended class';
    }

    public function TestThree() {
        echo $this->TestThreePart().'roll*';
    }
}

$Test = new First();
$Test->TestOne(); <-- Should echo 200.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum roll*'

你可能会问,为什么这样做而不仅仅是实例化第二,好吧,有些情况会略有不同:

STR_CLASS_NAME = 'Third';

class Third extends First{
    /* Override value to know it's working */
    protected $intTestOne = 300;

    /* Overriding construct to avoid infinite loop */
    public function __construct() {}

    public function TestTwo() {
        echo 'Using method from extended class';
    }

    public function TestThree() {
        echo $this->TestThreePart().'snare*';
    }
}

$Test = new First();
$Test->TestOne(); <-- Should echo 300.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum snare*'

情况

我有一个抽象类,它使用实际的实现来扩展基类;在这种情况下是一个基本的DB包装器。

class DBConnector ()
class DBConnectorMySQLi extends DBConnector()

如您所见,MySQLi是实现。现在,依赖于配置过程中的值,常量变为我希望使用的类名,在这种情况下(如下所示构建DBConnectorMySQLi。

define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);

目的

  • 拥有可扩展的基类以包含实现
  • 代码本身不需要知道实现的名称是什么
  • To(在这种情况下)能够键入或使用项目接受的公共变量来创建DBConnectorMySQLi。 I.E. $ db或类似的东西。 w ^

问题

当涉及到实际调用此类时,我希望代码如下所示。我想知道这是否完全没有必要添加任何额外的语法。另外,这个常数100%保证定义。

$DBI = new DB_CLASS();

解决方案1 ​​

我知道可以使用反射类(如THIS QUESTION中所述),这可以通过:

$DBI = new ReflectionClass(DB_CLASS);

然而,这会产生比预期“更脏”的代码

解决方案2

在DBConnector的构造函数中启动DBConnectorMySQLi的特定实现。

define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);

class DBConnector() { public function __construct() { $this->objInterface = new DBConnectorMySQLi(); }
class DBConnectorMySQLi()

然而,这将导致需要继续将变量从一个“推送”到另一个

任何建议都非常感谢

1 个答案:

答案 0 :(得分:0)

您可以在实例化类时使用变量。

$classname = DB_CLASS;
$DBI = new $classname();

来源:instantiate a class from a variable in PHP?