【问题标题】:Instantiate a class with an unknown name in php?在php中实例化一个名称未知的类?
【发布时间】:2013-02-28 04:44:13
【问题描述】:

我正在使用抽象的Page 类在 PHP 中创建模板系统。我网站上的每个页面都是它自己的类,扩展了Page 类。由于无法实例化像$page = new Page(); 这样的抽象类,我无法弄清楚如何在不知道该页面的类名的情况下实例化扩展页面的类。

如果我在运行时只知道抽象类的名称,是否可以实例化扩展抽象类的类?如果是这样,我将如何去做?


Page类的伪代码:

<?php    
abstract class Page{
    private $request = null;
    private $usr;
    function __construct($request){
        echo 'in the abstract';
        $this->request = $request;
        $this->usr = $GLOBALS['USER'];
    }

    //Return string containing the page's title. 
    abstract function getTitle();

    //Page specific content for the <head> section.
    abstract function customHead();

    //Return nothing; print out the page. 
    abstract function getContent();
}?>

加载所有内容的索引页面的代码如下:

require_once('awebpage.php');
$page = new Page($request);
/* Call getTitle, customHead, getContent, etc */

各个页面如下所示:

class SomeArbitraryPage extends Page{
    function __construct($request){
        echo 'in the page';
    }

    function getTitle(){
        echo 'A page title!';
    }

    function customHead(){
        ?>
            <!-- include styles and scripts -->
        <?php 
    }
    function getContent(){
        echo '<h1>Hello world!</h1>';
    }
}

【问题讨论】:

  • 这得到了父母。我知道父类——Page——但我不知道子类的名称。
  • 你能提供一些伪代码吗?由于某种原因没有完全遵循
  • 您可以查看Factory Method 模式。所以你最终会得到类似Page::create('page1') 的东西,它返回处理你网站的Page1 的类的有效实例。 en.wikipedia.org/wiki/Factory_method_pattern
  • 很难做到这一点。也许你可以改变你的架构。向我们提供更多信息:您为什么要这样做?

标签: php class abstract-class instantiation


【解决方案1】:

您可以为函数/类名使用变量:

class YourExtendedClass {
    public function example(){
        echo 1;
    }
}

$class = 'YourExtendedClass';
$t = new $class();
$t->example();

【讨论】:

    【解决方案2】:

    你不能在不知道它的名字的情况下实例化一个类。如上所述,您可以将变量用作类/函数名称。您可以列出所有 Page 子项的列表:

    abstract class Page {
            public static function me()
            {
                return get_called_class();
            }
        }
    
    class Anonym extends Page {
    
    }
    
    $classes = get_declared_classes();
    $children = array();
    $parent = new ReflectionClass('Page');
    
    foreach ($classes AS $class)
    {
        $current = new ReflectionClass($class);
        if ($current->isSubclassOf($parent))
        {
            $children[] = $current;
        }
    }
    
    print_r($children);
    

    并获得以下输出

    Array ( [0] => ReflectionClass Object ( [name] => Anonym ) )
    

    但话又说回来,如果您不知道名称,您也不会知道索引。

    【讨论】:

      猜你喜欢
      • 2020-01-26
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多