una otra objeto metodos metodo instanciar dentro crear compuesta como clases clase anidar anidados anidadas anidada php design-patterns fluent-interface

otra - ¿Cómo hacer una clase anidada PHP o métodos anidados?



crear una clase dentro de una clase java (3)

¿Cómo puedo hacer esto en PHP?

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

lo que quiero decir es métodos anidados o clase anidada (¡no sé!) así que cuando llamo al método de límite como hijo de usuarios, sabrá que lo estoy llamando desde el método de "usuarios" -o clase- y cuando llamo ¡Limite el método -o la clase! - de los comentarios. También lo sabe.

¿Cuál es la estructura posible para una clase PHP para hacer esto?

el motivo de esta pregunta porque estoy trabajando en mi propia clase para la base de datos, así que puedo usar algo como esto fácilmente

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

para generar el código sql "select * from comments where id> 3 limit 10" Gracias


Haga que los métodos devuelvan objetos con los métodos descritos, y obtendrá lo que busca.

Entonces, siempre que $DB sea ​​un objeto que tenga un método de comments() , esa parte es válida. Si ese comments() devuelve un objeto que tiene un id() -method, esa parte también es válida. Entonces, id() necesita devolver un objeto que tenga el método limit() .

En su caso particular, es posible que desee hacer algo como esto:

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

En mi ejemplo, cada método (también no representado aquí) devolvería el objeto en sí, de modo que los comandos se puedan encadenar juntos. Cuando finaliza la construcción de la consulta de la base de datos, realmente evalúa la consulta al invocar execute() que (en mi caso) devolvería un valor booleano que representaría el éxito de la ejecución de la base de datos.

El usuario nickohm sugirió que esto se llama una interfaz fluida . Debo admitir que este es un nuevo término para mí, pero eso dice probablemente más de mi conocimiento, que el uso del término. ( "Solo escribo código, ya sabes ..." )

Nota: $this es una variable ''mágica'' que apunta al objeto activo actualmente. Como su nombre indica, simplemente se devuelve como el valor de retorno para el método.


La convención estándar para esto es devolver la instancia de $ this al final de cada llamada al método. Entonces, cuando regresamos a la persona que llama, nos referimos a otra llamada a otro método.

class Foo { public function do_something() { return $this; } public function do_something_else() { return $this; } } $foo->do_something()->do_something_else();


Un método simple de implementar para comenzar podría ser:

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

Dependiendo de si quiere o no ser complicado, pero sólido o simple, pero menos flexible, puede implementar dos estrategias diferentes. La estrategia simple podría ser así:

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

Alternativamente, pero más poderoso:

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

Entiendes la idea. O bien sobrecargar el objeto db, o crear un objeto base db, y objetos de tabla, poniendo gran parte de la inteligencia en objetos de tabla, asegurando que cuando se crea, un objeto de tabla almacena una referencia al objeto db