zamanında bir yöntem / işlevini değiştirmek

5 Cevap php

Ben php yansıma yöntemleri bakarak oldum, ben ne yapmak istediğinizi yöntem açtı ve herhangi bir dönüş değeri önce, örneğin i değiştirmek istiyorum sonra bazı kod enjekte olduğunu:

function foo($bar)
{
    $foo = $bar ;
    return $foo ;
}

Ve gibi içine bazı kod enjekte:

function foo($bar)
{
    //some code here
    $foo = $bar ;
    //some code here
    return $foo ;
}

mümkün?

5 Cevap

anonymous functions içine bak. PHP yapmanız çalışıyoruz ne çizgisinde daha fazla olabileceğini 5,3 çalıştırabilirsiniz.

Bu, en azından sonra olan bir şekilde, mümkün değildir. Yorum önerildiği gibi, yansıma sınıfları / işlevleri değil, onları değiştirme hakkında bilgi almak içindir.

http://www.php.net/manual/en/book.runkit.php, ancak bu orada konak büyük çoğunluğu üzerinde varsayılan olarak yüklü olacak değil - Ben bu tür bir işlev sağlar inanıyoruz runkit adında bir PHP uzantısı vardır.

Bu olsa yapmanın farklı bir yolu olabilir. Yapmanız çalıştığınız ne hakkında biraz daha bilgi verebilir, ve neden söz işlevini değiştirmek değil, belki biz bazı öneriler sunmak mümkün olabilir. Örneğin Düzenlemek istemediğiniz bir üçüncü taraf kitaplığında bir çekirdek PHP işlevi veya kodunu değiştirmek istediğiniz işlevi nedir?

Peki, tek yönlü, tüm yöntem "sanal" çağrıları yapmak olacaktır:

class Foo {
    protected $overrides = array();

    public function __call($func, $args) {
        $func = strtolower($func);
        if (isset($this->overrides[$func])) {
            // We have a override for this method, call it instead!
            array_unshift($args, $this); //Add the object to the argument list as the first
            return call_user_func_array($this->overrides[$func], $args);
        } elseif (is_callable(array($this, '_' . $func))) {
            // Call an "internal" version
            return call_user_func_array(array($this, '_' . $func), $args);
        } else {
            throw new BadMethodCallException('Method '.$func.' Does Not Exist');
        }
    }

    public function addOverride($name, $callback) { 
        $this->overrides[strtolower($name)] = $callback;
    }

    public function _doSomething($foo) {
        echo "Foo: ". $foo;
    }
}

$foo = new Foo();

$foo->doSomething('test'); // Foo: test

PHP 5.2:

$f = create_function('$obj, $str', 'echo "Bar: " . $obj->_doSomething($str) . " Baz";');

PHP 5.3:

$f = function($obj, $str) {
    echo "Bar: " . $obj->_doSomething($str) . " Baz";
}

Tüm PHP:

$foo->addOverride('doSomething', $f);

$foo->doSomething('test'); // Bar: Foo: test Baz

Bu "geçersiz kılma" için ilk yöntem olarak nesnenin örneği geçer. Not: Bu "overriden" yöntemi sınıfın herhangi korumalı üyelerine erişemez. Böylece alıcılar kullanmak (__get, __set). Bu gerçek çağrı __call() geliyor bu yana, korunan yöntemlerine erişimi var OLACAKTIR ...

Note: Tüm varsayılan yöntemleri ... bu iş için bir '_' ile öneki için değiştirmeniz gerekir (veya başka bir önek seçeneği seçtim, ya da yapabilirsiniz sadece kapsamı hepsini korumalı) ...

Sadece bir fikir:

function foo($bar, $preprocess, $postprocess){

    //IF CONDITION($preprocess)
    include('/mylogic/'.$preprocess.".php"); //do some preprocessing here?
    $foo = $bar ;
    //IF CONDITION($postprocess)
    include('/mylogic/'.$postprocess.".php"); //process $foo here?
    //FINALLY return
    return $foo;

}

Belki de ben bir şey eksik, ama sen gerçekten dediğin gibi kodu "eklemesine" istiyorsun? Ne elde etmek için çalışıyoruz? Sadece B olduğunda tek bir olur kod bloğu, ve başka yürütmek istiyorsanız, o zaman ihtiyacınız olan tüm if () deyimi gibi, basit bir programlama mantığıdır.

Eğer gerçekten zamanında bir işlevi değiştirmek için çalışıyorsunuz? Ya da bu sadece bir mantık sorundur?

Yapmanız gerekenler hakkında daha spesifik olun.