Как я могу создать функцию динамически?

У меня есть переменная типа $string = "blah";

Как создать функцию, которая имеет значение переменной как имя? Возможно ли это в PHP?

Как function $string($args){ ... } или что-то еще, и иметь возможность называть его так:

blah($args);

Ответ 1

Это не похоже на отличный дизайн, возможно, стоит переосмыслить его, но...

Если вы используете PHP 5.3, вы можете использовать анонимную функцию.

<?php
$functionName = "doStuff";
$$functionName = function($args) {
    // Do stuff
};

$args = array();
$doStuff($args);
?>

Ответ 2

это может быть не очень хорошая идея, но вы можете сделать что-то вроде этого:

$string = "blah";
$args = "args"
$string = 'function ' . $string . "({$args}) { ... }";
eval($string);

Ответ 3

Хорошо, вызов принят!

Неважно, насколько странным является этот вопрос (это, между прочим, не так), давайте на минутку отнесемся к нему серьезно! Может быть полезно иметь класс, который может объявлять функции и делать их реальными:

<?php

customFunctions::add("hello",                 // prepare function "hello"

    function($what) {
        print "Hello $what, as Ritchie said";
        print "<br>";
    }

);

customFunctions::add("goodbye",               // prepare function "goodbye"

    function($what,$when) {
        print "Goodbye cruel $what, ";
        print "I'm leaving you $when";
        print "<br>";
    }

);

eval(customFunctions::make());                // inevitable - but it safe!

Это! Теперь они настоящие функции. Нет $ -prefixing, нет оценок времени выполнения, когда они вызваны - eval() был необходим только один раз для объявления. После этого они работают как любая функция.

Давайте попробуем их:

    hello('World');                 // "Hello World"
    goodbye('world','today');       // "Goodbye cruel world, I'm leaving you today" 

Волшебство позади

Вот класс, который может это сделать. На самом деле не сложный:

class customFunctions {

    private static $store = [];
    private static $maker = "";
    private static $declaration = '
        function %s() {
            return call_user_func_array(
                %s::get(__FUNCTION__),
                func_get_args()
            );
        }
    ';

    private static function safeName($name) {
        // extra safety against bad function names
        $name = preg_replace('/[^a-zA-Z0-9_]/',"",$name);
        $name = substr($name,0,64);
        return $name;
    }

    public static function add($name,$func) {
        // prepares a new function for make()
        $name = self::safeName($name);
        self::$store[$name] = $func;
        self::$maker.=sprintf(self::$declaration,$name,__CLASS__);
    }

    public static function get($name) {  
        // returns a stored callable
        return self::$store[$name];
    }

    public static function make() {  
        // returns a string with all declarations
        return self::$maker;
    }

}

Он обеспечивает внутреннее хранилище для ваших функций, а затем объявляет "настоящие" функции, которые их вызывают. Это что-то похожее на решение fardjad, но с реальным кодом (не строками) и, следовательно, намного удобнее и удобочитаемее.

Ответ 4

Вы можете вызвать функцию по имени, хранящемуся в переменной, и вы также можете назначить функцию переменным и вызвать ее с помощью переменной. Если это не то, что вы хотите, объясните подробнее.