【发布时间】:2012-01-17 14:05:18
【问题描述】:
我在 PHP 中遇到了一种情况,我需要在不知道类是什么的情况下访问类的构造函数。我可能从错误的设计角度来处理这个问题,所以情况就是这样——我在 Drupal 工作,围绕他们的无类数据处理编写一个轻微的 OO 层,以允许一些非 Drupal 开发人员加入我的项目。
在 Drupal 中,所有内容都被视为一个节点。所以,我做了一个抽象类——Node。任何内容都必须具有特定的内容类型。使用 OO,这很容易——我创建了一个扩展 Node 的 Person 类,或者一个扩展 Node 的 Event 类等。现在是棘手的部分——我的项目的一部分允许这些节点“包含”在其他节点中。也就是说,如果节点 A 包括节点 B,那么无论何时显示 A,都会显示来自 B 的数据。这意味着每当实例化节点 A 时,它也需要实例化节点 B。但是...Node 是一个抽象类。所以,我不能实例化一个原始节点。我必须实例化它的一个实现类。所以,据我所知,我要么需要编写一个抽象的静态函数,所有扩展类都必须实现它返回构造函数......要么,我需要以某种方式使用反射来确定类型,并以某种方式调用合适的类构造函数?
不考虑 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();
}
?>
【问题讨论】:
标签: php oop object inheritance