web-dev-qa-db-ja.com

変数に格納された文字列からPHP関数を呼び出す方法

関数を呼び出せるようにする必要がありますが、関数名は変数に格納されていますが、可能ですか。例えば:

 function foo()
 {
 //ここにコード
} 
 
ファンクションバー() 
 //ここにコード
] 
 
 $ functionName = "foo"; 
 functionName 

誰でも素晴らしいでしょう。

ありがとうございます。

260
Lizard
431
knittl

私のお気に入りのバージョンはインラインバージョンです。

${"variableName"} = 12;

$className->{"propertyName"};
$className->{"methodName"}();

StaticClass::${"propertyName"};
StaticClass::{"methodName"}();

括弧の中に変数や式を入れることもできます。

96
Lajos Meszaros

はい、可能です。

function foo($msg) {
    echo $msg."<br />";
}
$var1 = "foo";
$var1("testing 1,2,3");

出典: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2

17
Sev

すでに述べたように、おそらく最も安全な方法がcall_user_func()であるか、あるいは必要ならば$function_name()のルートをたどることでこれを達成する方法がいくつかあります。このように両方の方法を使用して引数を渡すことは可能です。

$function_name = 'foobar';

$function_name(arg1, arg2);

call_user_func_array($function_name, array(arg1, arg2));

あなたが呼んでいる関数がオブジェクトに属しているなら、あなたはまだこれらのどちらかを使うことができます

$object->$function_name(arg1, arg2);

call_user_func_array(array($object, $function_name), array(arg1, arg2));

しかし、もしあなたが$function_name()メソッドを使用しようとしているなら、名前が何らかの形で動的であるならば、関数の存在をテストするのは良い考えかもしれません。

if(method_exists($object, $function_name))
{
    $object->$function_name(arg1, arg2);
}
16
olliefinn

数年遅れていますが、これが今の最善の方法です。

$x = (new ReflectionFunction("foo"))->getClosure();
$x();
12

他の誰かがクラス内のメソッドに変数を使用しようとしたためにここに来た場合、以下は実際に動作するコードサンプルです。上記のどれも私の状況ではうまくいきませんでした。主な違いは、&の宣言の$c = & new...&$ccall_user_funcに渡されることです。

私の特定のケースは、色とcsscolor.phpクラスからの2つのメンバーメソッドlighten()darken()に関係している誰かのコードを実装するときです。どんな理由であれ、私は同じコードでロジックでそれを選択するのではなく、lightenまたはdarkenを呼び出せるようにしたかったのです。これは、if-elseを使用したり、このメソッドを呼び出すコードを変更したりしないという、私の頑固さの結果かもしれません。

$lightdark="lighten"; // or optionally can be darken
$color="fcc";   // a hex color
$percent=0.15;  
include_once("csscolor.php");
$c = & new CSS_Color($color);
$rtn=call_user_func( array(&$c,$lightdark),$color,$percent);

$c->{...}で何でも試してもうまくいかなかったことに注意してください。 call_user_funcのphp.netのページの一番下にある読者寄稿の内容を熟読すると、私は上記をまとめることができました。また、配列としての$paramsうまくいきませんでした私には:=

// This doesn't work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);

上記の試みは、2番目の引数(パーセント)が必要なメソッドについて警告を出します。

12
Chris K

完全を期すために、 eval() を使うこともできます。

$functionName = "foo()";
eval($functionName);

ただし、 call_user_func() が適切な方法です。

10
karim79

動的関数名とネームスペース

名前空間を使用するときに動的関数名に関するポイントを追加するためだけに。

名前空間を使用している場合、関数がグローバル名前空間にある場合を除き、以下は機能しません

namespace greetings;

function hello()
{
    // do something
}

$myvar = "hello";
$myvar(); // interpreted as "\hello();"

何をすべきか?

代わりにcall_user_func()を使用する必要があります。

// if hello() is in the current namespace
call_user_func(__NAMESPACE__.'\\'.$myvar);

// if hello() is in another namespace
call_user_func('mynamespace\\'.$myvar);
6
Jivan

PHP 7では、いくつかの素晴らしい可能性があります。最初に、他の人が言ったように、PHP 5(そしてさらにPHP 5より古い)で私達はすることができました:

function something() {
    echo 256;
}

$foo = "something";
$foo(); // 256

これは良いことですが、PHP 7では良くなりました。括弧内の(a)文字列に対して任意の操作を行い、それを関数名として一度に使用できます(something()関数を宣言したとします)。

$bar = "some_thing";

// We use in this form: (expressions)(arguments);
(str_replace("_", "", $bar))(); // 256

さらに、以下のすべての形式を使用できます。

(expressions)['bar']
(expressions)->bar
(expressions)->bar()
(expressions)->$bar()
(expressions)::$bar
(expressions)::bar()
(expressions)()

たとえば、 無名クラス と上記の機能の組み合わせを使用できます。

echo (new class {
    public $something = 512;
})->something; // 512

また、次の形式でクラスインスタンスのメソッドを呼び出すこともできます。

[objectInstance, methodName]();

例として、我々はすることができます:

class X {
    public function object_call() {
        echo "Object Call";
    }
    public static function static_call() {
        echo "Static Call";
    }
}

[new X(), "object_call"](); // Object Call
[new X(), "static_call"](); // Static Call

this PHP talk から取り出しました。

5
MAChitgarha

オブジェクトのメソッドを呼び出したい場合は@Chris Kの答えを補完するために、クロージャの助けを借りて単一の変数を使用してそれを呼び出すことができます。

function get_method($object, $method){
    return function() use($object, $method){
        $args = func_get_args();
        return call_user_func_array(array($object, $method), $args);           
    };
}

class test{        

    function echo_this($text){
        echo $text;
    }
}

$test = new test();
$echo = get_method($test, 'echo_this');
$echo('Hello');  //Output is "Hello"

私は別の例を投稿しました ここ

3
David

Call_user_func関数を使用してください。

2
PaulJWilliams

この質問とその答えから私が学んだこと。皆さんありがとう!

これらの変数と関数があるとしましょう。

$functionName1 = "sayHello";
$functionName2 = "sayHelloTo";
$functionName3 = "saySomethingTo";

$friend = "John";
$datas = array(
    "something"=>"how are you?",
    "to"=>"Sarah"
);

function sayHello()
{
echo "Hello!";
}

function sayHelloTo($to)
{
echo "Dear $to, hello!";
}

function saySomethingTo($something, $to)
{
echo "Dear $to, $something";
}
  1. 関数を呼び出すには引数なしで

    // Calling sayHello()
    call_user_func($functionName1); 
    

    こんにちは!

  2. 関数を呼び出すには1引数付き

    // Calling sayHelloTo("John")
    call_user_func($functionName2, $friend);
    

    ジョン様、こんにちは。

  3. Functionを呼び出すには1つ以上の引数でこれはあなたが動的にあなたの関数を呼び出していて、それぞれの関数が異なる数の引数を持っている場合に役に立ちます。これが私が探していた(そして解決した)ケースです。 call_user_func_arrayがキーです

    // You can add your arguments
    // 1. statically by hard-code, 
    $arguments[0] = "how are you?"; // my $something
    $arguments[1] = "Sarah"; // my $to
    
    // 2. OR dynamically using foreach
    $arguments = NULL;
    foreach($datas as $data) 
    {
        $arguments[] = $data;
    }
    
    // Calling saySomethingTo("how are you?", "Sarah")
    call_user_func_array($functionName3, $arguments);
    

    サラ様、お元気ですか?

さようなら!

2
asmasyakirah

以下のコードはPHPで動的関数を書くのに役立ちます。関数名は変数 '$ current_page'によって動的に変更できるようになりました。

$current_page = 'home_page';
$function = @${$current_page . '_page_versions'};
$function = function() {
    echo 'current page';
};
$function();
1
rakesh.falke