PHP call_user_func ile sadece çağıran işlev


92

Eminim bunun çok kolay bir açıklaması vardır. Bunun arasındaki fark nedir:

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

... ve bu (ve faydaları nelerdir?):

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

Yanıtlar:


88

Bildiğiniz zaman her zaman gerçek işlev adını kullanın.

call_user_func ismini önceden bilmediğiniz ancak programın çalışma zamanında işlevi araması gerektiğinden çok daha az verimli olan işlevleri çağırmak içindir.


44
call_user_funcgerekli değildir. Her zaman değişken fonksiyonları kullanarak bir işlevini çağırabilirsiniz: $some_func(). call_user_func_arraygerçekten kullanışlı olandır.
Ionuț G. Stan

23
php'nin her zaman "işlevi çalışma zamanında araması" gerekir
VolkerK,

2
@Pacerier Yanlış. Anonim işlevler hala değişkenlerdedir, yani $func = function(){};. Call_user_func için olası herhangi bir parametrenin çağrılabilir olması gerekir, bu da ister bu ister $func()ya $obj->{$func}()da her neyse , doğrudan ona erişmek için yeterli veri içerdiği anlamına gelir .
Benubird

2
"Daha az verimli" aslında çok az, özellikle php7'den beri, yaklaşık birkaç ms / milyon çağrı: github.com/fab2s/call_user_func
fab2s

1
Bir kaynağa göre , "var olmayan bir işlevi bir değişken aracılığıyla çağırmak ölümcül bir hataya neden olurken, call_user_func () bir uyarı döndürür." Yani bu bir fark.
mbomb007

32

Değişken işlev adlarını şu şekilde çağırabilmenize rağmen:

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

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

Kaç argüman geçtiğinizi bilmediğiniz durumlar vardır. Aşağıdakileri göz önünde bulundur:

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

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

Sırasıyla statik ve nesne yöntemlerini çağırmak için de kullanışlıdır:

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

8
Bunun çok eski olduğunu biliyorum, ancak başka bir yerde makale bulamadım. $ VariableFunction () 'a uygulandığı gibi call_user_func (' customFunction ') kullanmak daha mı avantajlı? Farklılıklar nedir? Teşekkürler!
David Hobs

14

call_user_funcEğer gibi şeyler yapabilirsiniz böylece seçeneği vardır:

$dynamicFunctionName = "barber";

call_user_func($dynamicFunctionName, 'mushroom');

nerede dynamicFunctionNamedize daha heyecan verici ve çalışma sırasında üretilen olabilir. Gerekmedikçe call_user_func'ı kullanmamalısınız çünkü daha yavaştır.


2
Bu senaryoda değişken bir işlev kullanabileceğiniz görülüyor.
Anthony Rutledge

5

Önceden adını bilmediğiniz bir işlevi çağırmanın yararlı olduğunu düşünüyorum ... Şunun gibi bir şey:

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

call_user_func($func, 'stuff');

6
Hayır! Hala yapabiliriz$func('stuff');
ankush981

1
Evet, ancak aradaki fark bir değişken kullanmak, call_user_func kullanılırsa PHP uyarısına karşı bir PHP Ölümcül hatası üretecektir.
Robert Brisita

Bu, call_user_func()bu senaryoda değişken fonksiyonların değerini olumsuzlamadı .
Anthony Rutledge


3

Bu işlevi çağırmanın hiçbir faydası yok çünkü temelde "kullanıcı" işlevini çağırmak için kullanıldığını düşünüyorum (eklenti gibi) çünkü çekirdek dosyayı düzenlemek iyi bir seçenek değil. İşte Wordpress tarafından kullanılan kirli örnek

<?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
?>

çıktı

hello world my name is Tasikmalaya

0

İlk örneğinizde bir dizge olan işlev adını kullanıyorsunuz. dışarıdan gelebilir veya anında belirlenebilir. yani, kod oluşturma anında hangi fonksiyonun çalıştırılması gerektiğini bilmiyorsunuz.


-1

İsim alanlarını kullanırken, call_user_func () ismini önceden bilmediğiniz bir işlevi çalıştırmanın tek yoludur, örneğin:

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

Tüm işlevleriniz aynı ad alanında olsaydı, böyle bir şey kullanabileceğiniz için bu bir sorun olmazdı:

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

Düzenleme: @Jannis'in yanıldığımı söyledikten sonra biraz daha test yaptım ve pek şansım olmadı:

<?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()'
}

Çıktı sonuçlarını burada görebilirsiniz: https://3v4l.org/iBERh İkinci yöntem PHP 7'den itibaren işe yarıyor gibi görünüyor, ancak PHP 5.6 için geçerli değil.


1
. doğru olmadığı için. $ fn = '\ Foo \ Bar \ getCurrency'; $ fn ();
Jan Sverre

Merhaba @Jannis, bunu doğru bulmuyorum, belki nerede yanlış yaptığımı görebilirsiniz, cevabıma daha detaylı bir örnek ekledim.
ThomasRedstone

@ThomasRedstone bu işlevleri önceden mi istediniz? php, işlevleri diğer dosyalardan otomatik olarak yüklemez. Ayrıca ad alanlarındaki bu küçük ve büyük harflerin ne olduğu. Bar bir sınıf mı? o zaman bu başka bir kullanım durumu.
przemo_li

merhaba @przemo_li, bu tek bir dosya (tümü ad alanı içinde), ad alanı adına ne olduğundan emin değilim, savunmam için cevabı 4 yıl önce yazdım, ad alanını güncelledim ve hakkında bir not ekledim Gerçek çıktıyı görmek için bir bağlantı ile PHP 7. Hala jansverre'nin nasıl çalışmasını sağladığını bilmiyorum, PHP 7, 11 Haz 2015'e kadar alfa
girmedi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.