15

我怎样才能在 PHP 中做到这一点

$myDBClass->users()->limit(5);//output you limited users to 5
$myDBClass->comments()->limit(3);//output you limited comments to 3

我的意思是嵌套方法或嵌套类(我不知道!)所以当我作为用户的孩子调用限制方法时,它会知道我是从“用户”方法或类调用它并且当我调用限制方法 - 或类!- 来自评论 它也知道这一点。

PHP 类做这件事的可能结构是什么?


这个问题的原因是因为我正在为我自己的数据库类工作,所以我可以轻松地使用这样的东西

     $DB->comments()->id(" > 3")->limit(10);

生成 sql 代码 "select * from comments where id > 3 limit 10" 谢谢

4

3 回答 3

20

让这些方法返回具有所描述方法的对象,然后您就会得到您想要的。

因此,只要$DB是具有 - 方法的对象comments(),该部分就有效。如果comments()返回一个具有id()-method 的对象,那么该部分也是有效的。然后,id()需要返回一个具有limit()-method 的对象。

在您的特定情况下,您可能想要执行以下操作:

class DB {
  public function comments() {
    // do preparations that make the object select the "comments"-table...
    return $this;
  }

  public function id($string) {
    // handle this too...
    return $this;
  }

  public function limit($int) {
    // also this
    return $this;
  }

  public function execute() {
    $success = try_to_execute_accumulated_db_commands();
    return $success;
  }
}

$DB = new DB();
$DB->comments()->id(" > 3")->limit(10);

在我的示例中,每个方法(也未在此处描述)都会返回对象本身,因此可以将命令链接在一起。当数据库查询的构建完成时,您实际上通过调用execute()(在我的情况下)将返回一个表示数据库执行成功的布尔值来评估查询。

用户 nickohm 建议这称为fluent interface。我必须承认,这对我来说是一个新术语,但这可能比该术语的用法更能说明我的知识。(“我只是写代码,你知道……”

注意: $this是一个指向当前活动对象的“魔术”变量。顾名思义,它只是将自身作为方法的返回值返回。

于 2009-02-10T18:06:30.960 回答
10

this 的标准约定是在每个方法调用结束时返回 $this 的实例。所以当返回给调用者时,我们只是引用另一个方法调用。

class Foo
{
  public function do_something()
  { 
    return $this; 
  }

 public function do_something_else() 
 {
   return $this; 
  }
}

$foo = new Foo();
$foo->do_something()->do_something_else();
于 2009-02-10T18:04:45.083 回答
0

一个简单的实现方法可以帮助您入门,如下所示:

class db
{
  public function __call($function, $arguments)
  {
    switch($function) {
      // implement table handling here
      case 'user':
        //do something
        return $something;
        break;
    }
  }
}

根据您是否想变得复杂,但坚实或简单,但不太灵活,您可能会实施两种不同的策略。简单的策略可能是这样的:

class db
{

  protected $operatingTable;

  public function limit($limitNumber)
  {
    return $this->executeQuery("SELECT * FROM ".$this->operatingTable." LIMIT ".$limitNumber); // where executeQuery is a function that runs a query
  }

  public function __call($function, $arguments)
  {
    switch($function) {
      // implement table handling here
      case 'user':
        $this->operatingTable='user'; // alternately, but less secure: $this->operatingTable=$function;
        return $this;
        break;
    }
  }
}

或者,但更强大:

class db
{
  protected $operatingTable;

  public function limit($limitNumber)
  {
    return $this->executeQuery("SELECT * FROM ".$this->operatingTable." LIMIT ".$limitNumber); // where executeQuery is a function that runs a query
  }

  public function __call($function, $arguments)
  {
    switch($function) {
      // implement table handling here
      case 'user':
        $user = new user($this); // pass in the database to the object, so the table object can have a reference to the db
        return $user;
        break;
    }
  }
}

class baseTableClass
{
  protected $db; // an instance of class db

  function limit($limitNumber)
  {
    $db->execute($aStatementDerivedFromThisClassesInformation); // execute a sql command, based on information about the table in the class
  }

}

class user extends baseTableClass
{
  public function __construct($db) {
    $this->db = $db;
  }
}

你明白了。要么重载 db 对象,要么创建基本 db 对象和表对象,将大部分智能放在表对象中,确保创建时,表对象存储对 db 对象的引用

于 2009-02-10T18:33:15.577 回答