PHP zamanında bir işlev Çıkarma

8 Cevap php

Bu soru hacky ve garip görünüyor biliyorum, ama PHP zamanında bir işlev kaldırmak için bir yol var?

Ben bir "eğer" bloğunda ilan tekrarlamalı bir fonksiyon var ve bu fonksiyon sadece bu "eğer" bloğunda "geçerli" olmak istiyorum. Bu fonksiyon bu bloğun dışında callled olmak istemiyorum.

Ben öğrendim runkit_function_remove ama runkit Benim Web ana etkin değil. Bunu yapmak için başka bir yolu var mı?

MEZUNLARI Ben sadece PHP 5.1.0 destekler.

Edit: Ben soru hacky olduğunu biliyordum ama burada yapmak istediğim tam olarak bir şey:

if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
    function stripslashes_deep($value)
    {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }

    $_POST = array_map('stripslashes_deep', $_POST);
    $_GET = array_map('stripslashes_deep', $_GET);
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    $_REQUEST = array_map('stripslashes_deep', $_REQUEST);

    //runkit_function_remove('stripslashes_deep');
}

Sihirli Tırnaklar AÇIK olduğunda "stripslashes_deep" sadece live, ben onunla işim bittiğinde ondan kurtulmak istiyordu çünkü. Ben insanlar her zaman there olmayan bir fonksiyonu güvenmek istemiyorum. Ben şimdi daha net umuyoruz. Sigara hacky çözüm önerileri de bekliyoruz!

8 Cevap

No. But removing a function definition is silly.
Either you're defining the function differently in an else block and need the definition to change based on program state, effectively making your project closer and closer to impossible to debug, or code that calls that function will crash and burn if it didn't happen to get defined at runtime.

Bir sınıfta bu işlevi koymak gerekir:

class foo {

    public function bar() {

        if( /* some condition */ ) {
            $this->baz();
        } else {
            $this->bazzer();
        }

    }

    private function baz() {

        /* if the if condition was met */

    }

    private function bazzer() {

        /* if the if condition failed */

    }

}

ya da, sadece durum bir kez test istiyorsanız,

class foo {

    private $bar_function = NULL;

    public function __construct() {

        if( /* some condition */ ) {
            $this->bar_function = baz;
        } else {
            $this->bar_function = bazzer;
        }

    }

    public function bar() {

        $this->$bar_function();

    }
        ...

Ne yapmaya çalışıyorsun bilmiyorum ya da neden bir işlev tanımını kaldırmak istiyorum ama umarım bu temiz bir şekilde bunu yapmak yardımcı olabilir.

İlk fonksiyon tanımı gibi görünüyor:

// includes/std_functions.php
if (! function_exists('the_function')) {
  function the_function() {
    global $thefunction;
    return call_user_func_array($thefunction, func_get_args());
  }
  $GLOBALS['thefunction'] = function() {
    echo 'foo';
  };
}

Eğer kodu yeniden yazmak için izin veren bir test koşulu varsa:

// somewhere in your code
if (<replacethefunctioncondition>) {
  $GLOBALS['thefunction'] = function() {
    echo 'bar';
  };
}

Eğer başka bir yüklenme vardır eğer orijinal dosya önce veya sonra yüklenecektir şunlardır:

// includes/custom_functions.php
if (! function_exists('the_function')) {
  function the_function() {
    global $thefunction;
    return call_user_func_array($thefunction, func_get_args());
  }
}
$GLOBALS['thefunction'] = function() {
  echo 'bar';
};

Simple answer: no.

Ancak, you can try placing the function inside a namespace, a class ya da within another function - ama ben sizin için ne arıyorsanız olmadığını düşünüyorum.

Ben biliyorum hackish, ama yani runkit_function_remove() - sen var Bir diğer seçenek .. çağırarak hangi dosya / satır / vb kontrol dedi işlev içinde debug_backtrace() kullanmaktır.


Düzenle - PHP 5.3 + tüketmemek çok kötü, aksi takdirde sadece yapabileceği:

if (get_magic_quotes_gpc())
{
    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
}

PHP'nin eski sürümleri için you still have this option:

if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}

Hiçbir işlevleri ve kod uzun değil. =)

Bu runkit_function_remove olmadan imkansız. Runkit bu gibi şeyler yapmak için tasarlanmıştır uzantısıdır.

Eğer fonksiyon eğer blok tamamlandıktan sonra yaşadığı emin misiniz? Ben sanırdım ki o daha sonra ulaşılmaz olacağını, eğer blok içinde tanımlı olsaydı.

Ben de izin için çok az sebep göremiyorum bir işlev "canlı" veya bir koşula bağlı "canlı değil", ama soruyu cevaplamak için, bu anonim fonksiyonları kullanarak çeşit mümkündür. @ Gordon zaten nasıl yapıldığını anlattı. Aşağıdaki gibi PHP 5.3.0 ile başlayarak, ayrıca anonim işlevlerini kullanabilirsiniz. (create_function() yaklaşımın fonksiyonel fark yoktur.)

if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
    $stripslashes_deep = function($value)
    {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }

    $_POST = array_map($stripslashes_deep, $_POST);
    $_GET = array_map($stripslashes_deep, $_GET);
    $_COOKIE = array_map($stripslashes_deep, $_COOKIE);
    $_REQUEST = array_map($stripslashes_deep, $_REQUEST);

    unset ($stripslashes_deep);
}

Ben Alix katılıyorum. Ancak, fonksiyonun kurtularak başka bir yerden çağrıldığını işlevini önleyebilirsiniz. Iteratif döngü olarak özyinelemeli işlevini yeniden. Sen yararı bellek kullanımını azaltmak gerekir.

UPDATE: kod örneği ile, seni tekrar çağrıldığını bu işlevini engellemek için ihtiyacı hissediyorum neden emin değilim. Bu sadece bir dizi bazı dizeleri ardışık ... tekrar, yinelenen bu yapmak ve ilk etapta bir işleve sahip önlemek olabilir biçimlendirir. Aksi takdirde, sadece orada bırakın ve tekrar demiyorlar.

Bu gibi bunlardan kullanımını değiştirerek işlevlerini yerine başka bir çözüm olabilir;

function function1(){
 echo "1";
}

function function2(){
 echo "2";
}

if(FUNCTION_CHOOSER_CONDITION) $the_function = "function2";
else $the_function="function1";
$the_function(); //  displays 2 if condition is TRUE;

Belki bu değil sizin için işlevini yok etmek istedim ama bu durumda bu işlevleri yerine hakkında konuşmak için doğru yerdir i bile.