una parametros otra metodos llamar instanciar funciones funcion ejercicios ejemplos dentro crear clases clase php code-generation proxy-classes dynamic-compilation

parametros - Generar dinámicamente clases en tiempo de ejecución en php?



instanciar una clase dentro de otra php (8)

Esto es lo que quiero hacer:

$clsName = substr(md5(rand()),0,10); //generate a random name $cls = new $clsName(); //create a new instance function __autoload($class_name) { //define that instance dynamically }

Obviamente, esto no es lo que realmente estoy haciendo, pero básicamente tengo nombres desconocidos para una clase y, según el nombre, quiero generar la clase con ciertas propiedades, etc.

He intentado usar eval () pero me está dando ajustes en privado y $ this-> references ...

//editar

Ok, obviamente, mi breve y dulce "esto es lo que quiero hacer" causó grandes conflictos y consternación entre aquellos que pueden proporcionar respuestas. Con la esperanza de obtener una respuesta real seré más detallado.

Tengo un marco de validación que utiliza sugerencias de código en el sitio que mantengo. Cada función tiene dos definiciones.

function DoSomething($param, $param2){ //code } function DoSomething_Validate(vInteger $param, vFloat $param2){ //return what to do if validation fails }

Estoy buscando agregar un validador para las claves primarias en mi base de datos. No quiero crear una clase separada para CADA tabla (203). Así que mi plan era hacer algo como

function DoSomething_Validate(vPrimaryKey_Products $id){ }

Donde __autoload generaría una subclase de vPrimaryKey y establecería el parámetro de la tabla en Productos.

¿Feliz ahora?


Creo que usar eval() no es una solución confiable, especialmente si su script o software se distribuirá a diferentes clientes. Los proveedores de alojamiento compartido siempre deshabilitan la función eval() .

Estoy pensando en un mejor enfoque como este:

<?php function __autoload( $class ) { require ''classes/''.$class.''.php''; } $class = ''App''; $code = "<?php class $class { public function run() { echo ''$class<br>''; } ".'' public function __call($name,$args) { $args=implode(",",$args); echo "$name ($args)<br>"; } }''; file_put_contents(''classes/App.php'' ,$code); $a = new $class(); $a->run();

Después de terminar de ejecutar el código, puede eliminar el archivo si lo desea, lo probé y funciona perfectamente.


Esto es casi una mala idea.

Creo que sería mejor dedicar su tiempo a crear un script que cree sus definiciones de clase y no intentar hacerlo en tiempo de ejecución.

Algo con una firma de línea de comandos como:

./generate_classes_from_db <host> <database> [tables] [output dir]


He creado un paquete que crea clases / interfaces / rasgos dinámicamente ... y los almacena en un archivo, luego puede incluir el archivo creado para poder usar su clase.

paquete: https://packagist.org/packages/kanel/enuma


Por favor, lea las respuestas de todos los demás sobre cómo esta es realmente una muy mala idea.

Una vez que entiendas eso, aquí hay una pequeña demostración de cómo puedes, pero no debes, hacer esto.

<?php $clname = "TestClass"; eval("class $clname{}; /$cls = new $clname();"); var_dump($cls);


Sé que esta es una pregunta antigua y hay respuestas que funcionarán, pero quería ofrecer algunos fragmentos que responderían a la pregunta original y creo que ofrecer una solución más amplia en caso de que alguien termine aquí como lo hice cuando buscaba una respuesta a este problema

Crear una sola clase dinámica

<?php // Without properties $myclassname = "anewclassname"; eval("class {$myclassname} { }"; // With a property $myclassname = "anewclassname"; $myproperty = "newproperty"; eval("class {$myclassname} { protected /${$myproperty}; }"; ?>

Siempre que escape correctamente su texto, también puede agregar una función allí.

Pero, ¿qué sucede si desea crear clases dinámicamente basadas en algo que podría ser dinámico, como crear una clase para cada tabla en su base de datos como se mencionó en la pregunta original?

Crear múltiples clases dinámicas

<?php // Assumes $dbh is a pdo connection handle to your MySQL database $stmt=$dbh->prepare("show tables"); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); $handle = null; $classcode = ''''; foreach ($result as $key => $value) { foreach ($value as $key => $value) { $classcode = "class {$value} { "; $stmt2=$dbh->prepare("DESC $value"); $stmt2->execute(); $result2 = $stmt2->fetchAll(PDO::FETCH_ASSOC); foreach ($result2 as $key => $value) { $classcode .= "public /${$value[''Field'']}; "; } $classcode .= "}"; eval($classcode); } } ?>

Esto generará dinámicamente una clase para cada tabla en una base de datos. Para cada clase, una propiedad que se nombra después de cada columna TAMBIÉN se creará.

Ahora se ha señalado que no debe hacer esto. Mientras controle lo que está pasando en la evaluación, el riesgo de seguridad no es un problema. PERO, es muy probable que haya una solución que tenga más sentido si piensas lo suficiente. Pensé que tenía el caso de uso perfecto para crear dinámicamente nuevas clases. El examen cuidadoso del problema demostró lo contrario.

Una posible solución: use stdClass para crear objetos que sean solo contenedores de datos y que no necesiten ningún método.

Además, como se mencionó, puede usar un script para generar manualmente muchas clases. En el caso de las clases que reflejan las tablas de su base de datos, puede usar la misma lógica que tengo arriba y, en lugar de hacer una evaluación, escriba esa información en un archivo.


Usar eval () es realmente una mala idea. Se abre un gran agujero de seguridad. Simplemente no lo uses!


es gracioso, en realidad esta es una de las pocas cosas en las que la evaluación no parece tan mala idea.

siempre que pueda asegurarse de que ninguna entrada del usuario ingresará en la evaluación.

usted todavía tiene inconvenientes, como cuando usa un caché de bytecode que el código no se almacenará en caché, etc., pero los problemas de seguridad de eval están más o menos relacionados con la entrada de usuarios en la evaluación, o para terminar en el ámbito incorrecto.

Si sabes lo que estás haciendo, eval te ayudará con esto.

Dicho esto, en mi opinión, usted está mucho mejor cuando no confía en las sugerencias de tipo para su validación, pero tiene una función

DoSomething_Validate($id) { // get_class($id) and other validation foo here }


function __autoload($class) { $code = "class $class {` public function run() { echo ''$class<br>''; } ".'' public function __call($name,$args) { $args=implode(",",$args); echo "$name ($args)<br>"; } }''; eval($code); } $app=new Klasse(); $app->run(); $app->HelloWorld();

Esto podría ayudar a crear una clase en tiempo de ejecución. También crea una ejecución de methor y un método catchall para métodos desconocidos, pero es mejor crear objetos en tiempo de ejecución, no clases.