J'utilise un système de stockage tiers qui ne me renvoie que des objets stdClass, peu importe ce que je nourris pour une raison obscure. Je suis donc curieux de savoir s'il existe un moyen de convertir / convertir un objet stdClass en un objet à part entière d'un type donné.
Par exemple, quelque chose du genre:
//$stdClass is an stdClass instance
$converted = (BusinessClass) $stdClass;
Je suis juste en train de convertir la classe stdClass dans un tableau et de la transmettre au constructeur BusinessClass, mais il existe peut-être un moyen de restaurer la classe initiale dont je ne suis pas au courant.
Remarque: je ne suis pas intéressé par le type de réponses «Changer votre système de stockage» car ce n'est pas le point d'intérêt. S'il vous plaît, considérez-le plus comme une question académique sur les capacités linguistiques.
À votre santé
PDOStatement::fetchObject
accomplir cette tâche?Réponses:
Voir le manuel sur la jonglerie de types sur les lancers possibles.
Les lancers autorisés sont:
Vous devrez écrire un mappeur qui effectue le transtypage de stdClass vers une autre classe concrète. Cela ne devrait pas être trop difficile à faire.
Ou, si vous êtes d'humeur hackish, vous pouvez adapter le code suivant:
qui pseudo-diffuse un tableau en un objet d'une certaine classe. Cela fonctionne en sérialisant d'abord le tableau, puis en modifiant les données sérialisées afin qu'elles représentent une certaine classe. Le résultat est alors désérialisé à une instance de cette classe. Mais comme je l'ai dit, c'est hackish, alors attendez-vous à des effets secondaires.
Pour objet à objet, le code serait
la source
__PHP_Incomplete_Class
objet en utilisant cette méthode (au moins à partir de PHP 5.6).fooBar
s (le privé deexample\Foo
et le public de stdClass). Au lieu de cela, il remplace la valeur.Vous pouvez utiliser la fonction ci-dessus pour convertir des objets de classe non similaires (PHP> = 5.3)
EXEMPLE:
la source
@Given the user :username has the id :id
dans ma fonctionnalité et la gérer avec des réflexions dans la classe de contexte$destination = new $destination();
peut être échangée$destination = ( new ReflectionClass( $destination ) )->newInstanceWithoutConstructor();
si vous devez éviter d'appeler le constructeur.Pour déplacer toutes les propriétés existantes de a
stdClass
vers un nouvel objet d'un nom de classe spécifié:Usage:
Production:
Ceci est limité en raison de l'
new
opérateur car on ne sait pas de quels paramètres il aurait besoin. Pour votre cas, probablement approprié.la source
J'ai un problème très similaire. La solution de réflexion simplifiée a très bien fonctionné pour moi:
la source
J'espère que quelqu'un trouvera cela utile
la source
Fonction modifiée pour le casting profond (en utilisant la récursivité)
la source
Et encore une autre approche utilisant le motif décorateur et les getter & setters magiques PHPs:
la source
BTW: La conversion est très importante si vous êtes sérialisé, principalement parce que la désérialisation rompt le type d'objets et se transforme en stdclass, y compris les objets DateTime.
J'ai mis à jour l'exemple de @Jadrovski, maintenant il autorise les objets et les tableaux.
exemple
exemple de tableau
code: (c'est récursif). Cependant, je ne sais pas si c'est récursif avec des tableaux. Peut-être qu'il manque un is_array supplémentaire
la source
envisagez d'ajouter une nouvelle méthode à BusinessClass:
alors vous pouvez créer une nouvelle BusinessClass à partir de $ stdClass:
la source
Encore une autre approche.
Ce qui suit est désormais possible grâce à la récente version de PHP 7.
Dans cet exemple, $ foo est en cours d'initialisation en tant que classe anonyme qui prend un tableau ou stdClass comme seul paramètre pour le constructeur.
Finalement, nous parcourons chacun des éléments contenus dans l'objet passé et attribuons ensuite dynamiquement la propriété d'un objet.
Pour rendre cet événement d'approche plus générique, vous pouvez écrire une interface ou un trait que vous implémenterez dans n'importe quelle classe où vous souhaitez pouvoir lancer un stdClass.
la source
Convertissez-le en tableau, retournez le premier élément de ce tableau et définissez le paramètre de retour sur cette classe. Vous devriez maintenant obtenir la saisie semi-automatique pour cette classe car elle la regconisera en tant que classe au lieu de stdclass.
la source