2014-12-21 22 views
5

, ben başka fonksiyona this bağlamak ve .call veya PHP

.apply ile çağırabilirsiniz JavaScript çağrısı gibi thisArg bağlamak call_user_func işlev?

JavaScript:

function greet() { 
    alert('Hello ' + this.name); 
} 

function SomeClass() {} 
SomeClass.prototype = { 
    name: 'John', 
    test: function() { 
    greet.call(this); 
    } 
} 

var me = new SomeClass(); 
me.test(); // Hello John 

PHP:

GÜNCELLEME
function greet() { 
    echo 'Hello ' . $this->name; 
} 

class SomeClass { 
    public $name = 'John'; 

    function test() { 
    call_user_func('greet'); 
    } 
} 

$me = new SomeClass; 
$me->test(); // Fatal error: Using $this when not in object context 

:

Teşekkür Reflection fikir için @deceze, ben bu çözümleri bulduk ama sanmıyorum bu iyidir performans için (doğrudan çağrıdan x10 daha yavaş), fakat okumada çok net.

// See also Javascript: Function.prototype.apply() 
function function_apply($fn, $thisArg, $argsArray = array()) { 
    static $registry; 
    if (is_string($fn)) { 
    if (!isset($registry[$fn])) { 
     $ref = new \ReflectionFunction($fn); 
     $registry[$fn] = $ref->getClosure(); 
    } 
    $fn = $registry[$fn]; 
    } 
    return call_user_func_array($fn->bindTo($thisArg), $argsArray); 
} 

// See also Javascript: Function.prototype.call() 
function function_call($fn, $thisArg /*, arg1, arg2 ... */) { 
    return function_apply($fn, $thisArg, array_slice(func_get_args(), 2)); 
} 

ve call_user_funcfunction_call için değiştirin:

function greet() { 
    echo 'Hello ' . $this->name; 
} 

class SomeClass { 
    public $name = 'John'; 

    function test() { 
    function_call('greet', $this); 
    } 
} 

$me = new SomeClass; 
$me->test(); // Hello John 
+0

neden Neden o işlevine argüman katmayan ve bağımsız değişken olarak değişken geçirebilirsiniz ? Aksi takdirde 'use' anahtar kelimesi size yardımcı olabilir. (http://php.net/functions.anonymous) Ama emin değilim. –

+0

http://stackoverflow.com/questions/27014664/php-equivalent-of-javascript-bind – haim770

+0

'un olası kopyasının, bu argümanı "$ $" olarak değiştiren bir çözüm olduğunu bildiğim gibi, sadece merak ettiğim gibi çalışan Javascript – user1542316

cevap

3

PHP JavaScript değildir:

Ben iki işlevi yazdım serbestçe içeri tanımlanmış fonksiyonlar ve dış sınıflar karştramazsnz, onların bağlamı anahtarlama onları çağırdıkça. $this'u anlattığınız şekilde kullanma girişimleri önemli bir hataya neden olacaktır: Using $this when not in object context. Daha sonra, aynı etki, klasısız fonksiyonlar için basit bir sözleşme ile gerçekleştirilebilir: ilk param olarak çalışacakları bağlamı aktarırlar. Görünüşe göre, yalnızca içerik nesnesinin genel arayüzünü kullanabileceksiniz - ama yine de, JavaScript ile aynıdır. Ayrıca, bir bonus olarak, sınıf ipucu ile bir tip kontrolüne sahip olacaksınız. Örneğin:

function greet(SomeClass $_this) { 
    echo 'Hello ' . $_this->name; 
} 

class SomeClass { 
    public $name = 'John'; 

    function test() { 
    call_user_func('greet', $this); 
    } 
} 

$me = new SomeClass; 
$me->test(); // Hello John 
+0

Siz * Reflection API'sını kullanarak $ this rebel edebilirsiniz ... ama dediğiniz gibi PHP'de Javascript olmadığı için üretimde yapmamızı tavsiye ederim. +1 – deceze

1

Eğer Kapatma :: bağlama fonksiyonunu

<?php 

class AAA { 

    public function ccc() 
    { 
     $bbb = new BBB; 
     $r = $bbb->abc()[0]; 
     var_dump($r, Closure::bind($r, $this)); 
    } 

} 

class BBB { 

    public function abc() 
    { 
     return [function() { 

     }]; 
    } 

} 

$aaa = new AAA; 
$aaa->ccc(); 

kullanabilir ve

object(Closure)#3 (1) { 
    ["this"]=> 
    object(BBB)#2 (0) { 
    } 
} 
object(Closure)#4 (1) { 
    ["this"]=> 
    object(AAA)#1 (0) { 
    } 
} 
İlgili konular