Nota: La solución a continuación es para PHP 5.3 y por debajo. A partir de PHP 5.4, también puede do it via Reflection as shown elsewhere on this page.
Esto es realmente posible.
Modificado de PHPUnit_Framework_MockObject_Generator
1 $myClass = unserialize(
2 sprintf(
3 'O:%d:"%s":0:{}',
4 strlen('MyClass'), 'MyClass'
5 )
6 );
Por favor, tenga en cuenta, que un código como todo esto es bueno y justificado en un marco como PHPUnit. Pero si debe tener un código como este en su código de producción, es probable que esté haciendo algo muy extraño.
Has solicitado que una explicación:
Cuando serialize an Object se obtiene una representación de cadena del objeto. Por ejemplo
echo serialize(new StdClass) // gives O:8:"stdClass":0:{}
El objeto O
significa. 8
es la longitud de cadena del nombre de clase. "stdClass"
es obviamente el nombre de clase. El objeto serializado tiene 0
conjunto de propiedades (más que el posterior), indicado por las llaves vacías. :
son solo delimitadores.
Cada cadena serializada se puede recrear en su valor "directo" original con la función unserialize. Al hacerlo, sorteará al constructor. Como Charles señaló correctamente, se llamará al magic method __wakeup()
si está definido (al igual que se llamará __sleep()
al serializar).
En la línea 3 verá una cuerda preparada para ser utilizada con sprintf (línea 2). Como puede ver, la longitud de la cadena del nombre de la clase se da como %d
y el nombre de la clase se da como %s
. Esto es para indicarle a sprintf que debe usar el primer argumento que se le pasa en la línea 4 como un dígito y el segundo como una cadena. Por lo tanto, el resultado de la llamada sprintf es
'O:7:"MyClass":0:{}'
debería reemplazar ambas ocurrencias de "MyClass" en la línea 4 con su nombre de la clase deseada para crear una cadena en serie de la clase en la que desea crear una instancia sin necesidad de invocar el controlador.
Esta cadena se deserializa en una instancia de MyClass en la línea 1, sin pasar por el constructor. La instancia no serializada tendrá todos los métodos de su clase y también cualquier propiedad. Si hay propiedades en MyClass, éstas tendrán sus valores predeterminados, a menos que agregue valores diferentes a la cadena ficticia serializada.
Y eso ya es todo. Nada demasiado mágico al respecto.
O, como han señalado otros, un método estático puede adaptarse mejor a sus necesidades dependiendo de lo que esté tratando de hacer. –
+1 para extender la clase. Tal vez es una clase de una biblioteca de terceros que no debe cambiarse ... –
+1 para las buenas soluciones alternativas. – Yacoby