在PHP中,是否可以返回类的构造函数?

时间:2011-12-10 20:46:52

标签: php oop object inheritance

我已经深入了解PHP的情况,我需要在不知道类是什么的情况下访问类的构造函数。我可能从错误的设计角度来看待这个问题,所以情况就是这样 - 我在Drupal工作,围绕他们的无类数据处理编写了一个小OO层,允许一些非Drupal开发人员加入我的项目。

在Drupal中,所有内容都被视为节点。所以,我做了一个抽象类 - 节点。任何内容都必须具有特定的内容类型。使用OO,这很容易 - 我创建一个扩展Node的Person类,或者一个扩展Node等的Event类。现在是棘手的部分 - 我的项目的一部分允许这些节点“包含”在其他节点中。也就是说,如果节点A包括节点B,则每当显示A时,显示来自B的数据。这意味着每当节点A被实例化时,它也需要实例化节点B.但是......节点是一个抽象类。所以,我无法实例化原始节点。我必须实例化其中一个实现类。所以,据我所知,我要么编写一个抽象的静态函数,所有扩展类都必须实现,返回构造函数...或者,我需要以某种方式使用反射来确定类型,并以某种方式调用适当的类构造函数?

不考虑Drupal,从PHP / OO编程的角度来看,处理这个问题的最合适的方法是什么?

这是我的代码:

<?php

abstract class Node {

    public $title, $short_summary, $full_summary, $body, $uri, $machine_type_name, $included_content;

    public function __construct($node) {

        ##
        ## Set simple values
        $this->title = $node->title;
        $this->body = $node->body['und'][0]['safe_value'];

        ##
        ## Set clean uri if aliased
        if (drupal_lookup_path('alias', 'node/'.$node->nid)) {
            $this->uri = '/'.drupal_lookup_path('alias', 'node/'.$node->nid);
        } else {
            $this->uri = '/node/'.$node->nid;
        }

        ##
        ## Set short summary if exists, else short form of body text
        if(strlen($node->body['und'][0]['safe_summary'])) {
            $this->short_summary = $node->body['und'][0]['safe_summary'];
        } else {
            $this->short_summary = text_summary($node->body['und'][0]['safe_value'], NULL, 100);
        }

        ##
        ## Set full summary to concatenation of body
        $this->full_summary = text_summary($node->body['und'][0]['safe_value'], NULL, 600);

        ##
        ## Add included content if module is enabled
        if (module_exists('content_inclusion')) {
            // is this possible? Is there a better design pattern available?
            $this->included_content = Node::get_constructor(node_load($node->content_inclusion['und'][0]['value']));
        }

    }

    public static abstract function get_all_published();
    public static abstract function get_by_nid($nid);
    public static abstract function get_constructor();
}

?>

1 个答案:

答案 0 :(得分:2)

你的意思是:?

class MySubClass extends Node
{
    public static function get_constructor()
    {
        return new self();
    }
}

// ...

$object = MySubClass::get_constructor();

或者,如果你有PHP 5.3,你可以使用late static binding来使用return new static();$class = get_called_class(); return new $class();。等

完整示例:

abstract class Node 
{
    public $test;

    public function __construct()
    {
        $this->test = 'Node';
    }

    public static function get_constructor()
    {
        return new static();
    }
}

class MySubClass extends Node
{
    public function __construct()
    {
        $this->test = __CLASS__ . PHP_EOL;
    }
}

// ...

$object = MySubClass::get_constructor();
echo $object->test; // echoes "MySubClass"