PHP call_user_funcと関数の呼び出しのみ


90

これについては非常に簡単な説明があると思います。これの違いは何ですか:

function barber($type){
    echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");

...そしてこれ(そして利点は何ですか?):

function barber($type){
    echo "You wanted a $type haircut, no problem\n";
}
barber('mushroom');
barber('shave');

回答:


87

知っている場合は、常に実際の関数名を使用してください。

call_user_func 名前が事前にわからない関数を呼び出すためのものですが、プログラムは実行時に関数を検索する必要があるため、効率が大幅に低下します。


ありがとう甲斐。call_user_funcは、まさに私が必要としているものであることがわかりました。
ジェイ

44
call_user_func必ずしも必要ではありません。変数関数を使用して、いつでも関数を呼び出すことができます$some_func()call_user_func_array本当に便利なものです。
Ionuț G. Stan

23
PHP

2
@Pacerierは不正解です。無名関数はまだ変数にあります$func = function(){};。call_user_funcへの可能なパラメータはすべて呼び出し可能である必要があります。つまり、、、、$func()またはその他に関係なく$obj->{$func}()、直接アクセスするのに十分なデータが含まれています。
Benubird 2017年

2
「効率が悪い」のは実際には非常に少なく、特にphp7以降、数ミリ秒/ 100万回の呼び出しです:github.com/fab2s/call_user_func
fab2s

32

このようにして変数関数名を呼び出すことができますが、

function printIt($str) { print($str); }

$funcname = 'printIt';
$funcname('Hello world!');

渡す引数の数がわからない場合があります。以下を検討してください。

function someFunc() {
  $args = func_get_args();
  // do something
}

call_user_func_array('someFunc',array('one','two','three'));

また、静的メソッドとオブジェクトメソッドをそれぞれ呼び出す場合にも便利です。

call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);

8
これは古くからあることは知っていますが、他の場所で記事を見つけることができませんでした。$ variableFunction()の代わりにcall_user_func( 'customFunction')を使用する方が有利ですか?違いは何ですか?ありがとう!
David Hobs、2014年

15

call_user_funcあなたのようなことを行うことができますので、オプションがあります:

$dynamicFunctionName = "barber";

call_user_func($dynamicFunctionName, 'mushroom');

どこdynamicFunctionNameの文字列は、よりエキサイティングで、実行時に発生する可能性があります。遅いので、必要がない限りcall_user_funcを使用しないでください。


1
このシナリオでは変数関数を使用できるようです。
Anthony Rutledge

6

事前に名前がわからない関数を呼び出すのに役立つと思います...次のようなもの:

switch($value):
{
  case 7:
  $func = 'run';
  break;
  default:
  $func = 'stop';
  break;
}

call_user_func($func, 'stuff');

5
いいえ。まだできます$func('stuff');
ankush981 2015年

1
はい。ただし、call_user_funcを使用すると、変数を使用するとPHPの致命的なエラーとPHPの警告が生成されるという違いがあります。
Robert Brisita 2017

このcall_user_func()シナリオでは、これは変数関数の値を無効にしていません。
Anthony Rutledge


3

コアファイルの編集は適切なオプションではないため、主に「プラグイン」などの「ユーザー」関数を呼び出すために使用されていたと思うので、そのような関数を呼び出す利点はありません。ここにWordpressが使用する汚い例があります

<?php
/* 
* my_plugin.php
*/

function myLocation($content){
  return str_replace('@', 'world', $content);
}

function myName($content){
  return $content."Tasikmalaya";
}

add_filter('the_content', 'myLocation');
add_filter('the_content', 'myName');

?>

...

<?php
/*
* core.php
* read only
*/

$content = "hello @ my name is ";
$listFunc = array();

// store user function to array (in my_plugin.php)
function add_filter($fName, $funct)
{
  $listFunc[$fName]= $funct;
}

// execute list user defined function
function apply_filter($funct, $content)
{
  global $listFunc;

  if(isset($listFunc))
  {
    foreach($listFunc as $key => $value)
    {
      if($key == $funct)
      {
        $content = call_user_func($listFunc[$key], $content);
      }
    }
  }
  return $content;
}

function the_content()
{
  $content = apply_filter('the_content', $content);
  echo $content;
}

?>

....

<?php
require_once("core.php");
require_once("my_plugin.php");

the_content(); // hello world my name is Tasikmalaya
?>

出力

hello world my name is Tasikmalaya

0

最初の例では、文字列である関数名を使用しています。それは外部から来るか、その場で決定されるかもしれません。つまり、コードの作成時に実行する必要がある関数がわかりません。


-1

名前空間を使用する場合、call_user_func()は、事前に名前がわからない関数を実行する唯一の方法です。次に例を示します。

$function = '\Utilities\SearchTools::getCurrency';
call_user_func($function,'USA');

すべての関数が同じ名前空間にある場合は、次のようなものを使用できるため、それほど問題にはなりません。

$function = 'getCurrency';
$function('USA');

編集:私が間違っていると言って@Jannisをフォローした後、私はもう少しテストを行いましたが、あまり運がありませんでした:

<?php
namespace Foo {

    class Bar {
        public static function getBar() {
            return 'Bar';
        }
    }
    echo "<h1>Bar: ".\Foo\Bar::getBar()."</h1>";
    // outputs 'Bar: Bar'
    $function = '\Foo\Bar::getBar';
    echo "<h1>Bar: ".$function()."</h1>";
    // outputs 'Fatal error: Call to undefined function \Foo\Bar::getBar()'
    $function = '\Foo\Bar\getBar';
    echo "<h1>Bar: ".$function()."</h1>";
    // outputs 'Fatal error: Call to undefined function \foo\Bar\getBar()'
}

ここで出力結果を確認できます。https//3v4l.org/iBERh 2番目の方法はPHP 7以降では機能しますが、PHP 5.6では機能しません。


。真実ではないため。$ fn = '\ Foo \ Bar \ getCurrency'; $ fn();
Jan Sverre 14年

こんにちは@Jannis、私はそれが本当であるとはわかりません、多分あなたは私が間違っているところを見ることができます、私は私の答えにさらに詳細な例を追加しました。
ThomasRedstone 2014年

@ThomasRedstone事前にそれらの機能を必要としましたか?PHPは他のファイルから関数をオートロードしません。また、名前空間の小さい文字と大きい文字の違いは何ですか。バーはクラスですか?その後、それは別のユースケースです。
przemo_li 2017年

こんにちは@przemo_li、これは単一のファイル(すべてネームスペース内)です。ネームスペース名で何が起こったのかわかりません。私の弁護では、4年前に回答を書きました。ネームスペースを更新しました。 PHP 7、実際の出力を表示するリンク付き。jansverreがどのように機能したかはまだわかりません。PHP7は2015
ThomasRedstone
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.