3 votes

Créer dynamiquement des fonctions avec Eval() en PHP

J'essaie de créer des fonctions de façon dynamique avec eval() . Mais je reçois cet avertissement : Notice: Use of undefined constant Une suggestion ?

$funcs = array('func_a', 'func_b', 'func_c');
foreach($funcs as $func_name) {
    eval( 'function ' . $func_name . '() { 
            mainfunc(' . $func_name . '); 
        }' 
    );  
}

func_a();
func_b();
func_c();

function mainfunc($func_name) {
    echo $func_name . '<br />';
}

En supposant que le tableau $func est une valeur d'option stockée dans une base de données et j'ai besoin des noms de fonction pour une fonction de rappel dans une partie séparée du script. Ainsi, la création de fonctions anonymes avec create_function() n'est pas ce que je recherche.

Merci pour votre information.

4voto

Glavić Points 13021

Utilisez une meilleure approche que eval(), elle s'appelle surcharge .

Exemple :

class MainFunc {

    public function __call($name, $arguments)
    {
        echo "_call($name)<br>";
    }

    public static function __callStatic($name, $arguments)
    {
        echo "_callStatic($name)<br>";
    }

}

# php >= 5.4.x
(new MainFunc)->func_a();
(new MainFunc)->func_b("param", "param2");
# or php < 5.4
$mainFunc = new MainFunc;
$mainFunc->func_a();
$mainFunc->func_b("param", "param2");

MainFunc::func_a_static();
MainFunc::func_b_static("param", "param2");

La sortie est :

_call(func_a)
_call(func_b)
_callStatic(func_a_static)
_callStatic(func_b_static)

2voto

jimp Points 5784

Votre corps ovale a besoin de lire :

mainfunc(\'' . $func_name . '\'); 

Sans les guillemets simples, eval() fait du code qui a un littéral non cité - une constante non définie.

0voto

Teno Points 929

Pour ceux qui se demandaient de quoi je parlais, voici l'exemple de plugin WordPress qui démontre l'utilité de la création de fonctions dynamiques.

/* Plugin Name: Sample Action Hooks with Dynamic Functions */

// assuming this is an option retrieved from the database
$oActions = array(  'a' => array('interval' => 10, 'value' => 'hi'),
                    'b' => array('interval' => 30, 'value' => 'hello'),
                    'c' => array('interval' => 60, 'value' => 'bye')
            );  

add_action('init', LoadEvents);
function LoadEvents() {
    global $oActions;
    foreach($oActions as $strActionName => $array) {
        eval( 'function ' . $strActionName . '() { 
                    SampleEvents(\'' . $strActionName . '\'); 
                }' 
        );  
        add_action('sampletask_' . md5($strActionName), $strActionName);
        if (!wp_next_scheduled( 'sampletask_' . md5($strActionName)))
            wp_schedule_single_event(time() + $oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));                  
    }
}
function SampleEvents($strActionName) {
    global $oActions;
    // just log for a demo
    $file = __DIR__ . '/log.html';
    $current = date('l jS \of F Y h:i:s A') . ': ' . $strActionName . ', ' . $oActions[$strActionName]['value'] . '<br />' . PHP_EOL;
    file_put_contents($file, $current, FILE_APPEND);    
    wp_schedule_single_event(time() + $oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));
}

Et la même fonctionnalité pourrait être obtenue avec __call() .

/* Plugin Name: Sample Action Hooks */

add_action('init', create_function( '', '$oSampleEvents = new SampleEvents;' ));
class SampleEvents {
    public $oActions = array(   'a' => array('interval' => 10, 'value' => 'hi'),
                                'b' => array('interval' => 30, 'value' => 'hello'),
                                'c' => array('interval' => 60, 'value' => 'bye')
                        );
    function __construct() {                
        foreach($this->oActions as $strActionName => $arrAction) {
            add_action('sampletask_' . md5($strActionName), array(&$this, $strActionName));
            if (!wp_next_scheduled( 'sampletask_' . md5($strActionName)))
                wp_schedule_single_event(time() + $this->oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));
        }
    }
    function __call($strMethodName, $arguments) {
        // just log for a demo
        $file = __DIR__ . '/log.html';
        $current = date('l jS \of F Y h:i:s A') . ': ' . $strMethodName . ', ' . $this->oActions[$strMethodName]['value'] . '<br />' . PHP_EOL;
        file_put_contents($file, $current, FILE_APPEND);    
        wp_schedule_single_event(time() + $this->oActions[$strMethodName]['interval'], 'sampletask_' . md5($strMethodName));
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X