过度使用$ this作为PHP中的对象参数,如何避免?

时间:2009-10-07 18:22:06

标签: php oop

我已经在PHP5中工作了几年,并开发了一个轻量级MVC框架,用于加速网站开发。工作很棒,自动化formbuilder,autoSQL模块等。

然而,我开发的一个坏习惯是将$ this作为一个简单的对象参数。我还没有弄清楚如何真正封装数据,而不必从基类(定义所有站点变量)扩展,并使用setter方法用传递的$ this对象填充每个对象实例。一切正常,但每个对象必须知道整个应用程序状态是荒谬的。我希望每个对象执行它的指定任务,只需要对“外部”上下文的最小知识。

例如,假设我有一个生成客户帐户详细信息的类:

// pseudo account

Class account extends siteBase {

protected $formObj;
public $custID = 1;
public $name;
public $email;
// etc...

 function __construct() {

  $this->formObj = new FormBuild($this); // easy $this passing

  $this->formObj->getFormData();

  $this->formObj->build();

}
}

// pseudo form builder class

Class FormBuild extends siteBase {

 protected $data;

 function __construct($caller) {

  $this->set($caller); 

 }

 function set($arr) { 

  foreach($arr as $key => $val) {

   $this->$key = $val;

  }

 }

 function getFormData() {

  $this->data = new FormQuery($this); // more easy $this passing

 }

 function build() {
  foreach($this->data as $key => $val) {
   echo $key . " " . $val . "<br>";
  }
 }
}

Class FormQuery extends siteBase {

function __construct($caller) {

  $this->set($caller); 

 }

 function query() { 

  $sql = "SELECT email, phone FROM account WHERE custID = '$this->custID'";

  // query & return return result, etc.

 }

}

“专业人士”在这种情况下做了什么?我想稍微清理一下界面......

3 个答案:

答案 0 :(得分:2)

有很多方法可以解决这个问题。这里有几个

  1. 全局或类常量
  2. 由某种配置类读取的外部配置/静态数据(INI样式,xml,yaml,数据库等)
  3. registry pattern
  4. depdency injection/inversion-of-control pattern
  5. 他们都有起伏 - 没有“一个真正的解决方案。”

答案 1 :(得分:0)

尝试从客户端代码的角度出发:派生类应该与父类具有相同的接口,但是具有不同的实现。

一个混乱的接口,例如父类中未在派生类中使用的方法,应该永远不存在,并且是启动重构的良好提示。您最有可能注意到的另一个强烈提示是,这些方法不会采用相同的参数(将account::__construct()FormBuild::__construct($caller)进行比较,两者都来自siteBase::__construct())。

我会考虑配置重构,如果siteBase包含数据库但派生类需要不同/一组不同的数据库怎么办?尝试绘制你的公共类,看看哪些真正共享签名,一次配对几个。

答案 2 :(得分:0)

上述两个回答都是正确的。

我内置了一个注册表对象/属性容器,我将其传递给不再需要从应用程序基类继承的相应对象。与传递$ this相比有点麻烦,但是为了更好的规划并迫使我定义我的对象需要知道什么而不是知道一切。

重构建议还让我将一些经常使用的对象剥离下来,而不是一次性完成工作。

还有一些方法,我已经习惯了从应用程序的几乎任何地方了解应用程序的所有内容......