Estoy usando un sistema de almacenamiento de terceros que solo me devuelve objetos stdClass sin importar lo que ingrese por alguna extraña razón. Así que tengo curiosidad por saber si hay una manera de convertir un objeto stdClass en un objeto completo de un tipo determinado.
Por ejemplo, algo como:
//$stdClass is an stdClass instance
$converted = (BusinessClass) $stdClass;
Solo estoy lanzando stdClass en una matriz y la envío al constructor BusinessClass, pero tal vez haya una forma de restaurar la clase inicial que no conozco.
Nota: No estoy interesado en el tipo de respuestas 'Cambie su sistema de almacenamiento' ya que no es el punto de interés. Considérelo más una cuestión académica sobre las capacidades lingüísticas.
Salud
PDOStatement::fetchObject
logra esta tarea?Respuestas:
Consulta el manual de Malabarismo de tipos sobre posibles lanzamientos.
Los yesos permitidos son:
Tendría que escribir un asignador que realice la conversión de stdClass a otra clase concreta. No debería ser demasiado difícil de hacer.
O, si estás de humor hack, puedes adaptar el siguiente código:
que pseudocasts una matriz a un objeto de cierta clase. Esto funciona primero serializando la matriz y luego cambiando los datos serializados para que representen una determinada clase. Entonces, el resultado no se serializa en una instancia de esta clase. Pero como dije, es hackish, así que espere efectos secundarios.
Para objeto a objeto, el código sería
fuente
__PHP_Incomplete_Class
objeto usando este método (al menos a partir de PHP 5.6).fooBar
s (el privado deexample\Foo
y el público de stdClass). En cambio, reemplaza el valor.Puede usar la función anterior para convertir objetos de clase no similares (PHP> = 5.3)
EJEMPLO:
fuente
@Given the user :username has the id :id
en mi función y manejarlo con reflejos en la clase de contexto$destination = new $destination();
se puede intercambiar$destination = ( new ReflectionClass( $destination ) )->newInstanceWithoutConstructor();
si necesita evitar llamar al constructor.Para mover todas las propiedades existentes de a
stdClass
a un nuevo objeto de un nombre de clase especificado:Uso:
Salida:
Esto es limitado debido al
new
operador, ya que se desconocen qué parámetros necesitaría. Para su caso probablemente encaja.fuente
Tengo un problema muy similar. La solución de reflexión simplificada funcionó bien para mí:
fuente
Espero que alguien encuentre esto útil
fuente
Función modificada para fundición profunda (usando recursividad)
fuente
Y otro enfoque más usando el patrón decorador y los getter & setters mágicos de PHP:
fuente
Por cierto: la conversión es muy importante si está serializado, principalmente porque la deserialización rompe el tipo de objetos y se convierte en stdclass, incluidos los objetos DateTime.
Actualicé el ejemplo de @Jadrovski, ahora permite objetos y matrices.
ejemplo
matriz de ejemplo
código: (es recursivo). Sin embargo, no sé si es recursivo con matrices. Puede que le falte un is_array adicional
fuente
considere agregar un nuevo método a BusinessClass:
entonces puedes crear una nueva clase de negocio desde $ stdClass:
fuente
Otro enfoque más.
Lo siguiente ahora es posible gracias a la reciente versión de PHP 7.
En este ejemplo, $ foo se inicializa como una clase anónima que toma una matriz o stdClass como único parámetro para el constructor.
Finalmente, recorremos cada elemento contenido en el objeto pasado y lo asignamos dinámicamente a la propiedad de un objeto.
Para hacer que este evento de aproximación sea más genérico, puede escribir una interfaz o un Trait que implementará en cualquier clase en la que desee poder emitir una stdClass.
fuente
Conviértalo en una matriz, devuelva el primer elemento de esa matriz y establezca el parámetro de retorno para esa clase. Ahora debería obtener el autocompletado para esa clase, ya que la regconizará como esa clase en lugar de stdclass.
fuente