secuencia resueltos hacer ejemplos diagrama como php constructor new-operator method-chaining

php - resueltos - ¿Cómo encadenar el método en un objeto recién creado?



diagrama de secuencia ejemplos resueltos (7)

Me gustaría saber si hay una forma de encadenar métodos en un objeto recién creado en PHP.

Algo como:

class Foo { public function xyz() { ... return $this; } } $my_foo = new Foo()->xyz();

Alguien sabe de una manera de lograr esto?


Bueno, esta puede ser una vieja pregunta, pero como ocurre con muchas cosas en programación, eventualmente la respuesta cambia.

En cuanto a PHP 5.3, no, no se puede encadenar directamente desde el constructor. Sin embargo, para ampliar la respuesta aceptada, a fin de acomodar adecuadamente la herencia, puede hacer:

abstract class Foo { public static function create() { return new static; } } class Bar extends Foo { public function chain1() { return $this; } public function chain2() { return $this; } } $bar = Bar::create()->chain1()->chain2();

Eso funcionará perfectamente y le devolverá una nueva instancia de Bar ().

En PHP 5.4, sin embargo, puedes simplemente hacer:

$bar = (new Bar)->chain1()->chain2();

¡Espero que esto ayude a alguien a encontrar la pregunta como yo!


Defina una función global como esta:

function with($object){ return $object; }

Luego podrá llamar:

with(new Foo)->xyz();



En PHP 5.4+, el analizador ha sido modificado para que pueda hacer algo como esto

(new Foo())->xyz();

Ajustar la instanciación entre paréntesis y encadenar.

Antes de PHP 5.4, cuando estás usando

new Classname();

sintaxis, no puede encadenar una llamada a un método fuera de la creación de instancias. Es una limitación de la sintaxis de PHP 5.3. Una vez que se crea una instancia de un objeto, puede encadenarse.

Un método que he visto para evitar esto es un método de instanciación estática de algún tipo.

class Foo { public function xyz() { echo "Called","/n"; return $this; } static public function instantiate() { return new self(); } } $a = Foo::instantiate()->xyz();

Envolviendo la llamada a lo nuevo en un método estático, puede crear una instancia de una clase con una llamada a un método, y entonces usted es libre de encadenar eso.


Esta respuesta está desactualizada, por lo tanto, quiero corregirla.

En PHP 5.4.x puede encadenar un método a una nueva llamada. Tomemos esta clase como ejemplo:

<?php class a { public function __construct() { echo "Constructed/n"; } public function foo() { echo "Foobar''d!/n"; } }

Ahora, podemos usar esto: $b = (new a())->foo();

Y la salida es:

Constructed Foobar''d!

Se puede encontrar más información en el manual: http://www.php.net/manual/en/migration54.new-features.php


Sería realmente útil si ''arreglan esto'' en una versión futura. Realmente aprecio la capacidad de encadenar (especialmente al poblar colecciones):

Agregué un método a la clase base de mi framework llamado create () que puede ser encadenado. Debería funcionar con todas las clases descendientes automáticamente.

class baseClass { ... public final static function create() { $class = new /ReflectionClass(get_called_class()); return $class->newInstance(func_get_args()); } ... public function __call($method, $args) { $matches = array(); if (preg_match(''/^(?:Add|Set)(?<prop>.+)/'', $method, $matches) > 0) { // Magic chaining method if (property_exists($this, $matches[''prop'']) && count($args) > 0) { $this->$matches[''prop''] = $args[0]; return $this; } } } ... }

Class :: create () -> SetName (''Kris'') -> SetAge (36);


Solo por el bien de la compleción (y por el gusto de hacerlo ...), ya que nadie parece haber mencionado la solución con el código más corto (y menos sofisticado).

Para objetos de corta vida frecuentemente utilizados, especialmente cuando se escriben casos de prueba, donde normalmente se crea mucho objeto, es posible que se desee optimizar la comodidad de tipeo (en lugar de pureza) y, a continuación, combinar Foo::instantiate() Alan Storm método y Kenaniah with() técnica de función global.

¡Simplemente haga que el método de fábrica sea una función global con el mismo nombre que la clase! . ; -o (O agregarlo como envoltorio de conveniencia alrededor de la Foo::instantiate() estática adecuada de Foo::instantiate() justo Foo::instantiate() o simplemente moverlo hacia afuera mientras nadie está mirando).

class Foo { public function xyz() { echo "Called","/n"; return $this; } } function Foo() { return new Foo(); } $a = Foo()->xyz();

NOTA:

  • NO HARÍA ESTO en el código de producción. Aunque es un poco ''sexy, esto es un abuso en los principios básicos de codificación (como "principio de la menor sorpresa" (aunque en realidad es una sintaxis bastante intuitiva), o "no te repites", especialmente si envuelve un método de fábrica real con algunos parámetros, que a su vez, por cierto, ya es un abuso de DRY ...), además de PHP puede cambiar en el futuro para romper el código de esta manera divertida.