Как сделать PHP вложенный класс или вложенные методы?

Как я могу это сделать в PHP

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

Я имел в виду вложенные методы или вложенный класс (я не знаю!) поэтому, когда я вызываю метод limit как дочерний метод пользователей, он будет знать, что я вызываю его из метода "users"- или класса - и когда я вызываю метод limit-или класс!- из комментариев он тоже это знает.

какова возможная структура для класса PHP, чтобы сделать это?


причина этого вопроса, потому что я работаю над своим собственным классом для базы данных, поэтому я могу легко использовать что-то вроде этого

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

для создания кода sql " выберите * из комментариев, где id > 3 ограничивает 10" Спасибо

3 ответов


есть методы возвращают объекты с описанными методами, и вы получаете то, что вам нужно.

пока $DB - это объект, который имеет comments() - метод, эта часть действительна. Если это comments() возвращает объект, который имеет id()-метод, эта часть действительна тоже. Затем:id() необходимо вернуть объект, который имеет limit()-метод.

в вашем конкретном случае вы можете сделать что-то вроде этого:

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();

в моем примере, каждый метод (также не изображенный здесь) вернет сам объект, так что команды могут быть скованы вместе. Когда построение запроса базы данных выполняется, вы фактически оцениваете запрос, вызывая execute() это (в моем случае) вернет логическое значение, которое будет представлять успех выполнения базы данных.

пользователь nickohm предположил, что это называется свободно интерфейс. Я должен признать, что это новый термин для меня, но это говорит, скорее всего знание, чем использование термина. (


стандартным соглашением для этого является возврат экземпляра $this в конце каждого вызова метода. Поэтому при возврате вызывающему объекту мы просто ссылаемся на другой вызов метода.

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

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

$foo->do_something()->do_something_else();

простой в реализации метод, чтобы вы начали может пойти, как:

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