开发者

Excessive use of $this as object param in PHP, How to avoid?

I've been working in PHP5 for a couple of years now and have developed a lightweight MVC framework that I use to speed up site development. Works great, automated formbuilder, autoSQL module, etc.

One bad habit that I have developed, however, is relying on $this as an easy object param. I have yet to figure out how to truly encapsulate data without having to extend from a base class (where all site variables are defined) and using a setter method to populate each object instance with the passed $this object. Everything works, but it's ridiculous that each object has to know about the entire application state. I would like each object to perform it's designated task only requiring a minimum knowledge of the "outside" context.

For example, let's say I have a class that generates a customer's开发者_如何学JAVA account details:

// 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.

 }

}

What do the "pros" do this in situation? I'd love to clean up the interface a bit...


There are many approaches to this problem. Here are a few

  1. Global or class constants
  2. External config/static data (INI style, xml, yaml, database, etc) read by a config class of some sort
  3. The registry pattern
  4. The depdency injection/inversion-of-control pattern

They all have their ups and downs - there is no "one true solution."


Try to take the perspective of the client code: a derived class should have the same interface as the parent class but a different implementation.

A messy interface such as methods in parent classes that aren't used in derived classes should never exist and would be a good hint to start refactor. Another strong hint that you most probably noticed is that the methods don't take the same arguments (comparing account::__construct() to FormBuild::__construct($caller), both deriving from siteBase::__construct()).

I would refactor with configuration in mind, what if siteBase includes a database but a deriving class needs a different/a set of different databases? Try to draw out your common classes and see which ones that really share signature, pair together a few at a time.


Both responses above are correct.

I have built-in a registry object/properties container that I pass to appropriate objects that no longer need to inherit from an application base class. Bit of a hassle compared to passing $this around, but makes for better planning and forces me to define what my objects need to know vs. knowing everything.

The refactoring advice also got me stripping down a few frequently used objects to only doing their job vs. several jobs at once.

Still a ways to go though, I've gotten used to knowing everything about the application from almost anywhere in the app...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜