我创建了一个包含标题,侧边栏和页脚的Display对象:
class Display {
protected $framework;
public $mysql;
public function __construct() {
$this->mysql = new MySQL();
$this->framework .= $this->header();
$this->framework .= $this->body();
$this->framework .= $this->sidebar();
$this->framework .= $this->footer();
}
private function header (){ /* blah */ }
private function body (){ }
private function sidebar (){ /* blah */ }
private function footer (){ /* blah */ }
public function displayPage(){
print $this->framework;
}
}
在每个页面上,我创建了一个扩展Display对象的对象,其中包含body的代码:
class IndexPHP extends Display {
public function body(){
$this->user = new User();
return '<div class="body">Hello ' . $this->user->getName() . '</div>';
}
}
$page = new IndexPHP();
$page->displayPage();
我是否通过将对象嵌套太多来创建问题?例如,在User对象中,如何访问已启动的MySQL对象?
class User {
protected $name;
public function __construct() {
$this->id = /* MySQL object query here */
}
}
答案 0 :(得分:7)
你所采用的方法的问题是你没有遵循任何形式的“权力分立”原则。您的Display对象中包含一个数据库,以及如何连接它的逻辑;这可能不是最好的方法(“上帝的对象”)。遵循MVC(模型 - 视图 - 控制器)原则可能是一个更好的主意,其中您有一个类知道您的模型(数据库),另一个知道如何将模型转换为将呈现的对象(控制器) ,第三个实际显示数据的所有CSS优点(视图,通常只是一个PHP模板文件)。
我建议你看看现有的MVC框架 - 我使用的是QCubed(http://qcu.be),还有其他的 - Symfony,Zend,CakePHP。它们都为您提供了一种干净利落地分离代码的好方法,最终实现了可维护性。
答案 1 :(得分:1)
例如,在User对象中,如何访问已经启动的MySQL对象?
你在构造函数中传递它:
class User {
protected $name;
public function __construct($mysql) {
$this->id = $mysql->something();
}
}
答案 2 :(得分:0)
如果覆盖子类中的函数(例如,您的IndexPHP类重写body()
),则应该使它们protected
而不是private
。
此外,最好只在构造函数中执行简单的操作,例如赋值。您的Display
构造函数完成了类中的所有工作,将构造工作移动到displayPage可能更好:
public function __construct(MySQL $mysql) {
$this->mysql = $mysql;
}
public function displayPage($rebuild=false) {
if(empty($this->framework) || $rebuild) {
$this->framework = $this->header();
$this->framework .= $this->body();
$this->framework .= $this->sidebar();
$this->framework .= $this->footer();
}
print $this->framework;
}