这是不好的面向对象的PHP?

时间:2009-07-29 20:09:56

标签: php oop

我创建了一个包含标题,侧边栏和页脚的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 */
    }
}

3 个答案:

答案 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;
}