2017-02-22 2 views
2

Ich habe eine Frage zum Wert, wenn ich eine Methode aus einer Zeichenfolge ausführen soll. Während ich in der Lage bin, einen einzelnen Methodenaufruf von einem String zu behandeln, bin ich neugierig, wie man eine Kette von Methoden aus einem String aufruft.Ausführen einer Methodenkette aus einem Zeichenfolgenwert

Zum Beispiel. $ Projekt ist ein Objekt.

$method1 = "name"; 
$project->$method1; // It shows the valid results 

$method2 = "get()->first()->name"; 
$project->get()->first()-name; // It shows the valid results 
$project->$method2; // get a null result 

Bitte helfen, einen Weg zu finden, die $ method2 Arbeit zu machen. Und was passiert, wenn ich in diesen Methoden Params habe?

Der Grund hier ist, ich habe eine Reihe von benutzerdefinierten Methoden gemacht. Es kann Zeile für Zeile ausgeführt werden, aber ich denke an eine Möglichkeit, sie in eine Schleife zu verwandeln, also ist es effizienter. Fügen Sie die Methoden in eine Datei ein und holen Sie sich die Werte, indem Sie sie durchlaufen.

Array = [ "getvalue1()", "getvalue2()", .... "getValuen() -> anotherMethod() -> Wert"]

Danke,

+1

Nicht wirklich eine gute Idee; Aber wenn Sie so etwas tun müssen, dann könnten Sie die Zeichenfolge in ein Array von einzelnen Methodenaufrufen aufteilen und über das Array iterieren. –

+0

Mögliches Duplikat von [Wie Kettenaufruffunktionen mithilfe einer Zeichenfolge, die diese Kette enthält in PHP] (http://stackoverflow.com/questions/30319950/how-to-chain-call-functions-by-using-a-string-containing-that-chain-in-php) –

Antwort

3

Wenn Sie verschachtelte try so etwas wie dies wollen:

private function callMethodChain($model, $methodChain) 
{ 
    return array_reduce(explode('->', $methodChain), function($model, $method) { 
     return $model->$method; 
    }, $model); 
} 

Diese durch eine Kette von Methodenaufrufe als beschrieben gehen. Wenn einige der Kette (das letzte Stück) ist eine Eigenschaft, ich glaube, ich einmal folgendes in Ordnung gebracht, um es zu behandeln:

protected function callMethodChain($model, $methodChain) 
{ 
    return array_reduce(explode('->', $methodChain), function($model, $method) { 
     try { 
      return $model->$method; 
     } catch (Exception $e) { 
      return $model->$method(); 
     } 
    }, $model); 
} 

Wenn Sie params versuchen hinzufügen möchten ersetzen $model->method mit:

call_user_func_array(
     array($project, 'your_method'), 
     $params 
    ); 
+0

Danke @chasenyc. Es scheint mit einem String wie "getMethod1() -> getMethod2()" zu funktionieren. Aber nicht "getMethod1() -> getMethod2() -> name". Es zeigt einen Fehler name() ist "Call to undefined Methode" –

+0

Ich habe eine Follow-up hinzugefügt, die für mich funktionierte, um beide Eigenschaften und Methoden zu behandeln. Ich würde auch sicherstellen, dass der Name eine Eigenschaft bei der Rückkehr von 'getMethod2()' –

+0

ist Es ist komisch, wenn ich das versuche. Es zeigt "Versuchen, Eigenschaft von Nicht-Objekt zu erhalten.". –

0

versuchen, diesen Ansatz :

$method1 = 'name'; 
$project->{$method1}(); 
+0

Dank @LBA. Es klappt. Mit dem $ method2 = "get() -> first() -> name". Auf diese Weise ist es nicht schwer. Irgendwelche Gedanken? –

0

Run-Methode aus einem String-Wert

Verwenden call_user_func() und call_user_func_array().

call_user_func_array() passt gut, wenn man vorbei Parameter

call_user_func_array(
     array($project, 'your_method'), 
     $params 
    ); 

Ketten Funktion

function chain_fun($chain,$object) 
{ 
    return array_reduce(explode('->', $chain), function ($obj, $method) { 
    if(preg_match('/[()]/',$method)){ 
     $method=trim($method,'()'); 
     return $obj->$method(); 
    }  
    return $obj->$method; 
    }, $object); 
} 

Hier Test

[email protected]:/tmp$ cat test.php 
<?php 
class Testclass 
{ 
    private $str; 
    function __construct() 
    { 
     $this->str = new StdClass; 
    } 
    function addA() 
    { 
     $this->str->a='A'; 
     return $this; 
    } 
    function addB() 
    { 
     $this->str->b='B'; 
     return $this; 
    } 
    function get() 
    { 
     return $this->str; 
    } 
} 

function chain_fun($chain,$object) 
{ 
    return array_reduce(explode('->', $chain), function ($obj, $method) { 
    if(preg_match('/[()]/',$method)){ 
    $method=trim($method,'()'); 
    return $obj->$method(); 
    }  
    return $obj->$method; 
}, $object); 
} 


$object = new Testclass(); 

// Output 1 
print_r(chain_fun("addA()->addB()->get()", $object)); 

// Output 2 
echo chain_fun("addA()->addB()->get()->a", $object); 


?> 

Ausgabe

[email protected]:/tmp$ php test.php 
stdClass Object 
(
    [a] => A 
    [b] => B 
) 
A 
+0

Danke @Akshay. Ich habe deine Methode noch nicht getestet. Der obere Vorschlag funktioniert für mich. Ich werde später nachsehen. –

Verwandte Themen