9

mmmh Leute, ich hoffe wirklich mein Englisch ist gut erugt zu erklären, was ich brauche.Gibt es eine Möglichkeit, einen anderen Parameter in der Callback-Funktion preg_replace_callback zu übergeben?

Lets nehmen dieses Beispiel (das ist nur ein Beispiel!) Code:

class Something(){ 
    public function Lower($string){ 
     return strtolower($string); 
    } 
} 
class Foo{ 
    public $something; 
    public $reg; 
    public $string; 
    public function __construct($reg, $string, $something){ 
     $this->something = $something; 
     $this->reg = $reg; 
     $this->string = $string; 
    } 
    public function Replace(){ 
     return preg_replace_callback($this->reg, 'Foo::Bar', $this->string); 
    } 
    public static function Bar($matches){ 
     /* 
     * [...] 
     * do something with $matches and create the $output variable 
     * [...] 
     */ 

     /* 
     * I know is really useless in this example, but i need to have an istance to an object here 
     * (in this example, the Something object, but can be something else!) 
     */ 
     return $this->something->Lower($output); 
    } 
} 
$s = new Something(); 
$foo = new Foo($myregexp, $mystring, $s); 
$content = $foo->Replace(); 

Also, das PHP-Handbuch sagt, dass eine Klassenmethode als Callback zu verwenden, in preg_replace_callback(), muss die Methode abstrakt sein .

Ich muss eine Instanz eines zuvor initialisierten Objekts (im Beispiel eine Instanz der Klasse Something) an die Callback-Funktion übergeben.

Ich habe versucht, call_user_func() zu verwenden, aber funktioniert nicht (auf diese Weise vermisse ich den matches Parameter).

Gibt es eine Möglichkeit, dies zu tun, oder muss ich den Prozess trennen (tun, bevor preg_match_all, für jedes Spiel den Ersetzungswert abrufen, und dann eine einfache preg_replace)?

edit: als Nebennote, vor der tom Haigh Antwort, habe ich diese Behelfslösung (im Beispiel, das die Methode ersetzen ist):

$has_dynamic = preg_match_all($this->reg, $this->string, $dynamic); 
if($has_dynamic){ 
    /* 
    * The 'usefull' subset of my regexp is the third, so $dynamic[2] 
    */ 
    foreach($dynamic[2] AS $key => $value){ 
     $dynamic['replaces'][$key] = $this->Bar($value); 
    } 
    /* 
    * ..but i need to replace the complete subset, so $dynamic[0] 
    */ 
    return str_replace($dynamic[0], $dynamic['replaces'], $this->string); 
}else{ 
    return $this->string; 
} 

Hoffnung jemand helfen kann.

Antwort

13

Es ist schwer, Argumente zu Rückrufe passieren, aber statt dessen:

return preg_replace_callback($this->reg, 'Foo::Bar', $this->string); 

Sie Bar() nicht statisch machen könnte, und verwenden Sie diese:

return preg_replace_callback($this->reg, array($this, 'Bar'), $this->string); 

Dann wird die Callback-Funktion der Lage sein, siehe zu $this

See 'Rückruf' in Pseudo-types and variables

Auch in PHP> = 5.3 können Sie anonymous functions/closures verwenden, um andere Daten an Callback-Funktionen zu übergeben.

+0

Das funktioniert! Ich dachte, dass die Klassenmethode statisch sein muss, erinnere dich nicht, wo ich es gelesen habe.vielleicht habe ich überhaupt nicht und ich bin mit einigen sätzen unordentlich. Danke – Strae

12

Ich steckte beim Versuch, ein Argument (Extra-Parameter) an einen Rückruf mit den Methoden create_function() und call_user_function() übergeben.

Dies ist als Referenz:

<?php 
$pattern = "/([MmT][a-z]*)/"; 
$string = "Mary is a naughty girl because she took all my animals."; 
$kill = "Mary"; 

echo preg_replace_callback($pattern, function($ma) use ($kill) { 

    foreach ($ma as $m){ 
     if ($m == $kill){ 
      return "Jenny"; 
     } 
     return "($m)"; 
    } 
}, $string); 

echo "\n"; 
?> 

$ php preg_replace_callback.php 
Jenny is a naughty girl because she took all (my) ani(mals). 
+0

sollte beachten Sie das 'use' Schlüsselwort wurde in PHP 5.4 hinzugefügt. die meisten Server laufen noch 5.3 :( – mpen

+1

@Mark die 'verwenden' Schlüsselwörter wird in PHP5.3 hinzugefügt –

+0

@WouterJ: Richtig. Aber sie haben' $ this' Unterstützung in 5.4 hinzugefügt? – mpen

0

ja ich so etwas wie diese verwenden, um eine Veränderung Variable und entschärft, so dass es an die Callback-Funktion verfügbar ist und Sie nicht brauchen die neuere php, es zu tun:

foreach ($array as $key) { 
    $this->_current_key = $key; 
    preg_replace_callback($regex, array($this, '_callback'), $content); 
    unset($this->_current_key); 
} 

dann in der Callback-Funktion $ this -> _ current_key verfügbar ist:

function _callback ($match) {  
    //use the key to do something 
    new_array[$key] = $match[0]; 

    //and still remove found string 
    return ''; 
} 
Verwandte Themen