我已经深入了解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();
}
?>
答案 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"