2013-03-16 4 views
2

J'utilise Active Record depuis un moment, et je voulais un petit changement de décor, certains amis développeurs ont suggéré de regarder dans ORM, tous les projets ORM que j'ai examinés nécessitent une classe séparée étendant l'ORM classe.Création dynamique de classes

Ma question est: est-il possible de créer dynamiquement une classe en utilisant PHP à partir d'une fonction sanseval?

C'est ce que j'ai:

<?php 
    class Constructor 
    { 
      function new_class($class) 
      { 
        $myself = get_called_class(); 
        eval("class {$class} extends {$myself} { }"); 
      } 
      function say_hi() 
      { 
        $class = get_called_class(); 
        echo "Hi, {$class}!"; 
      } 
    } 

    $constructor = new Constructor; 
    $constructor->new_class("Greeter"); 

    $greeter = new Greeter; 

    $greeter->say_hi(); // Hi, Greeter! 

Mais, mon client me informe que eval est bloqué sur son environnement en raison de l'être sur l'hébergement mutualisé.

+0

mais pourquoi? créer une classe, mettre les paramètres dans le tableau, ajouter une méthode '__set' et' __get' - définir les paramètres dans le tableau, vous pouvez ajouter le paramètre '$ name', qui va définir le' setName ($ name) 'et sera le nom de la classe, en essayant d'obtenir, get 'getName(). Héritier de la classe. – mkjasinski

+0

Il n'y a pas de "belle" façon de le faire en PHP. Vous pouvez utiliser eval(), ou créer un fichier avec une définition de classe à l'exécution, puis l'inclure() ... Mais pensez à changer la conception de votre programme. Voir http://stackoverflow.com/questions/3490474/how-to-create-or-define-class-in-php-at-runtime –

Répondre

2

Vous ne voulez probablement pas faire cela. Mais comme solution de contournement, vous pouvez utiliser la même approche que via eval(), mais une fois que vous avez construit la chaîne que vous auriez à alimenter, vous l'écrivez simplement en tant que fichier et l'incluez à nouveau.

Quelque chose comme ceci:

function my_eval($str) 
{ 
    $filename = uniqid().'.tmp'; 
    file_put_contents ($filename, $str); 
    include $filename; 
    unlink ($filename); 
} 

Je l'ai écrit de la mémoire et non testé, mais je pense qu'il devrait faire l'affaire. Seul bémol je verrais maintenant, c'est que vous auriez toujours faire la même chose que eval(), et cette variante ne vous permettrait pas de créer des variables dans la même portée que le contexte appelant (même si vous pouvez utiliser $ GLOBALS [] pour contourner cela pour les variables de portée globale).