2012-04-03 15 views
2

sagen, string ist:In PHP, wie Funktion in Zeichenfolge aufrufen?

$str="abcdefg foo() hijklmopqrst"; 

Wie PHP-Aufruf foo() und legen Sie die Rückgabestring auf diese Zeichenfolge lassen?

+5

Sehr unangenehm. Haben Sie eine Liste von Funktionen, für die Sie dies zulassen möchten, oder eine Funktion im Allgemeinen? (Sie haben auch die Auswirkungen auf Sicherheit und Leistung berücksichtigt, ja?) – Corbin

+0

Sie können eval() verwenden, aber es wird nicht allgemein empfohlen. – Panagiotis

+0

Bitte geben Sie uns mehr Informationen über Ihren Code. Woher kommt diese Saite? Du hast eine API erwähnt? –

Antwort

5
$str="abcdefg foo() hijklmopqrst"; 
function foo() {return "bar";} 

$replaced = preg_replace_callback("~([a-z]+)\(\)~", 
    function ($m){ 
      return $m[1](); 
    }, $str); 

Ausgang:

$replaced == 'abcdefg bar hijklmopqrst'; 

Dadurch werden alle Kleinbuchstaben als Funktionsnamen erlauben. Wenn Sie andere Symbole benötigen, fügen Sie sie dem Muster hinzu, d. H. [a-zA-Z_].

Be SEHR vorsichtig, welche Funktionen Sie erlauben, aufgerufen zu werden. Sie sollten zumindest überprüfen, ob $ m [1] eine Whitelist-Funktion enthält, die Remote-Code-Injection-Angriffe nicht zulässt.

$allowedFunctions = array("foo", "bar" /*, ...*/); 

$replaced = preg_replace_callback("~([a-z]+)\(\)~", 
    function ($m) use ($allowedFunctions) { 
      if (!in_array($m[1], $allowedFunctions)) 
       return $m[0]; // Don't replace and maybe add some errors. 

      return $m[1](); 
    }, $str); 

Testrun auf "abcdefg foo() bat() hijklmopqrst" Ausgänge "abcdefg bar bat() hijklmopqrst". .

Optimierung für Whitelist-Ansatz (Gebäude Muster dynamisch aus erlaubt Funktionsnamen, dh (foo|bar)

$allowedFunctions = array("foo", "bar"); 

$replaced = preg_replace_callback("~(".implode("|",$allowedFunctions).")\(\)~", 
    function ($m) { 
      return $m[1](); 
    }, $str); 
+2

Sie sind ein guter Programmierer! – lovespring

+0

Was ist, wenn die Funktion Parameter hat? –

5
$foo = foo(); 
$str = "abcdefg {$foo} hijklmopqrst"; 
+0

Ich muss die foo() in der $ str Zeit aufrufen. – lovespring

+0

@lovesquing meinst du irgendwann später? Vielleicht suchen Sie nach 'eval ($ str)' –

11

Nur diese verwenden:

$str = "abcdefg".foo()."hijklmnopqrstuvwxyz"; 

Es wird Funktion während Zeichenfolge Schöpfung nennen.

+0

die API geben Sie mir nur eine Zeichenfolge, So kann dieses Format nicht machen. – lovespring

+0

Welche Funktion möchten Sie verwenden? –

+1

@lovespring Dies ist eine schreckliche Einrichtung. Welche API verwenden Sie, die dies tun würde? – Nilpo

16

Wenn Sie eine Methode einer Klasse aufrufen, können Sie normale variable Erweiterung verwenden. Zum Beispiel:

<?php 
class thingie { 

    public function sayHello() { 
    return "hello"; 
    } 

} 

$t = new thingie(); 
echo "thingie says: {$t->sayHello()}"; 

erhalten Sie folgende Ausgabe:

thingie sagt: hallo

Beachten Sie, dass die Klammern um den Anruf erforderlich sind.

+0

Aber es scheint eine globale Funktion auf diese Weise aufrufen, wird nicht funktionieren – Opux

3
function foo() 
{ 
    return 'Hi'; 
} 
$my_foo = 'foo'; 
echo "{$my_foo()}"; 
+0

Dies ist ein großer "Trick". Sie können sogar Parameter oder andere Variablen an sie übergeben, z. 'echo" {$ my_foo ('bar')} "'oder' echo "{$ my_foo ($ bar)}" '- besonders nützlich beim Erstellen von SQL-Abfragen mit vielen Escape-Werten. –

+0

Wow, toller Trick! – pineappleman

0

Um beliebige Ausdrücke aus einem doppelten Anführungszeichen Zeichenfolge ausgewertet erhalten werden Sie auf Variable-Funktionen spekulieren:

<?php 
// A user function 
function foo() { 
    return 'bar'; 
} 

/** 
* The hack 
* 
* @param $v mixed Value 
* return mixed Value (untouched) 
*/ 
$_ = function ($v) { 
    return $v; 
}; 

// Happy hacking 
echo "Foo is {$_(foo())} and the sum is {$_(41 + 1)}...{$_(str_repeat(' arrh', 3))}!"; 

Ergebnis:

Foo is bar and the sum is 42... arrrh arrrh arrrh! 

Referenzen:

Verwandte Themen