Note: La solution est ci-dessous pour PHP 5.3 et ci-dessous. Depuis PHP 5.4, vous pouvez aussi do it via Reflection as shown elsewhere on this page.
Ceci est en effet possible.
de Modified PHPUnit_Framework_MockObject_Generator
1 $myClass = unserialize(
2 sprintf(
3 'O:%d:"%s":0:{}',
4 strlen('MyClass'), 'MyClass'
5 )
6 );
S'il vous plaît garder à l'esprit, ce code comme cela est bon et justifié dans un cadre comme PHPUnit. Mais si vous avez un code comme celui-ci dans votre code de production, vous risquez de faire quelque chose de très étrange.
Puisque vous demande une explication:
Lorsque vous serialize an Object vous obtenez une représentation de chaîne de l'objet. Par exemple
echo serialize(new StdClass) // gives O:8:"stdClass":0:{}
L'objet O
signifie. 8
est la longueur de la chaîne du nom de la classe. "stdClass"
est évidemment le nom de la classe. L'objet sérialisé a 0
propriétés définies (plus à cela plus tard), indiqué par les accolades vides. Les :
ne sont que des délimiteurs.
Chaque chaîne sérialisée peut être recréée dans sa valeur d'origine "en direct" avec la fonction unserialize. Ce faisant, contournera le constructeur. Comme Charles a correctement souligné le magic method __wakeup()
sera appelé s'il est défini (tout comme __sleep()
sera appelé lors de la sérialisation).
Dans la ligne 3, vous voyez une chaîne préparée pour être utilisée avec sprintf (ligne 2). Comme vous pouvez le voir la longueur de chaîne du nom de classe est donnée comme %d
et le nom de classe est donné comme %s
. C'est dire à sprintf qu'il doit utiliser le premier argument passé à la ligne 4 comme un chiffre et le second comme une chaîne. Par conséquent, le résultat de l'appel sprintf est
'O:7:"MyClass":0:{}'
vous devez remplacer les deux occurences de « MyClass » dans la ligne 4 avec votre nom de classe désirée pour créer une chaîne sérialisée de la classe que vous voulez instancier sans invoquer le contrôleur.
Cette chaîne est ensuite désérialisée dans une instance MyClass de la ligne 1, en contournant le constructeur. L'instance non sérialisée aura toutes les méthodes de sa classe et aussi toutes les propriétés. S'il existe des propriétés dans MyClass, celles-ci auront leurs valeurs par défaut, à moins que vous n'ayez ajouté des valeurs différentes à la chaîne factice sérialisée.
Et c'est déjà ça. Rien de trop magique à ce sujet.
Ou, comme d'autres l'ont souligné, une méthode statique peut mieux répondre à vos besoins selon ce que vous essayez de faire. –
+1 pour étendre la classe. Peut-être que c'est une classe d'une bibliothèque tierce qui ne devrait pas être changée ... –
+1 pour les bonnes solutions alternatives. – Yacoby