el alfa
¿Es posible agregar un método/función de esta manera, como
$arr = array(
"nid"=> 20,
"title" => "Something",
"value" => "Something else",
"my_method" => function($arg){....}
);
o tal vez así
$node = (object) $arr;
$node->my_method=function($arg){...};
y si es posible, ¿cómo puedo usar esa función/método?
Esto ahora es posible de lograr en PHP 7.1 con clases anónimas
$node = new class {
public $property;
public function myMethod($arg) {
...
}
};
// and access them,
$node->property;
$node->myMethod('arg');
-
Buena, me estaba burlando de algunos datos y esto resultó bastante útil.
– Nick M.
28 de septiembre de 2017 a las 0:08
-
pero ¿agrega esto una nueva función a un objeto ya definido?
– Geomorillo
11 de octubre de 2018 a las 2:53
-
@Geomorillo, No, no se agrega al objeto, puede “agregar función a la clase” con
extends
en (anónimo) clase. Es php, no es JavaScript. Pero en otras respuestas también puede ver soluciones ilegibles con__call
.– usuario1742529
23 de febrero a las 2:23
keelerm
No puede agregar dinámicamente un método a stdClass y ejecutarlo de la manera normal. Sin embargo, hay algunas cosas que puedes hacer.
En su primer ejemplo, está creando un cierre. Puede ejecutar ese cierre emitiendo el comando:
$arr['my_method']('Argument')
Puede crear un objeto stdClass y asignar un cierre a una de sus propiedades, pero debido a un conflicto de sintaxis, no puede ejecutarlo directamente. En su lugar, tendrías que hacer algo como:
$node = new stdClass();
$node->method = function($arg) { ... }
$func = $node->method;
$func('Argument');
Tratando
$node->method('Argument')
generaría un error, porque no existe ningún método “método” en una stdClass.
Vea esta respuesta SO para algunos hackers hábiles usando el método mágico __llamada.
-
+1, se hizo de otras maneras hace mucho tiempo, alguien editó la respuesta, vea la fecha, pero gracias por su esfuerzo.
– El alfa
9 de julio de 2013 a las 2:12
-
¡Vaya! Pasé por alto eso por completo. Gracias de cualquier forma.
– keelerm
9 de julio de 2013 a las 2:16
Desde PHP 7 también es posible invocar directamente una propiedad de función anónima:
$obj = new stdClass;
$obj->printMessage = function($message) { echo $message . "\n"; };
echo ($obj->printMessage)('Hello World'); // Hello World
Aquí la expresión $obj->printMessage
da como resultado la función anónima que luego se ejecuta directamente con el argumento 'Hello World'
. Sin embargo, es necesario poner la expresión de la función entre paréntesis antes de invocarla para que lo siguiente siga fallando:
echo $obj->printMessage('Hello World');
// Fatal error: Uncaught Error: Call to undefined method stdClass::printMessage()
g13013
Otra solución sería crear una clase anónima y representar la llamada a través de la función mágica. __call
con funciones de flecha incluso puede mantener la referencia a las variables de contexto:
new Class ((new ReflectionClass("MyClass"))->getProperty("myProperty")) {
public function __construct(ReflectionProperty $ref)
{
$this->setAccessible = fn($o) => $ref->setAccessible($o);
$this->isInitialized = fn($o) => $ref->isInitialized($o);
$this->getValue = fn($o) => $ref->getValue($o);
}
public function __call($name, $arguments)
{
$fn = $this->$name;
return $fn(...$arguments);
}
}
Abolfazl
class myclass {
function __call($method, $args) {
if (isset($this->$method)) {
$func = $this->$method;
return call_user_func_array($func, $args);
}
}
}
$obj = new myclass();
$obj->method = function($var) { echo $var; };
$obj->method('a');
O puede crear una clase predeterminada y usar …