9

mmmh les gars, j'espère vraiment que mon anglais est bien en train d'expliquer ce dont j'ai besoin.Existe-t-il un moyen de transmettre un autre paramètre dans la fonction de rappel preg_replace_callback?

permet de prendre ce exemple (qui est juste un exemple!) De 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(); 

Ainsi, le manuel php dire que d'utiliser une méthode de classe comme rappel dans preg_replace_callback(), la méthode doit être abstraite .

Je dois passer une instance d'un objet initialisé précédemment (dans l'exemple, une instance de la classe Something) à la fonction de rappel.

J'ai essayé d'utiliser call_user_func(), mais ne fonctionne pas (car de cette façon, le paramètre matches me manque).

Y at-il un moyen de le faire, ou dois-je séparer le processus (faire avant preg_match_all, pour chaque match récupérer la valeur de remplacement, puis un simple preg_replace)?

modifier: comme un côté note, avant la tom Haigh réponse, je l'ai utilisé ce travail autour (dans l'exemple, c'est la méthode Remplacer):

$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; 
} 

L'espoir peut aider quelqu'un.

Répondre

13

Il est difficile de passer des arguments à callbacks, mais au lieu de cela:

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

Vous pouvez faire Bar() pas statique, et utiliser ceci:

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

Ensuite, la fonction de rappel sera en mesure pour voir $this

'rappel' voir à Pseudo-types and variables

En outre, dans PHP> = 5.3, vous pouvez utiliser anonymous functions/closures pour transmettre d'autres données aux fonctions de rappel.

+0

Cela fonctionne! Je pensais que la méthode de classe devait être statique, ne me souviens pas où je l'ai lu ..Peut-être que je n'ai pas du tout et je me salis avec quelques phrases. Merci – Strae

12

J'ai été bloqué en essayant de passer un argument (paramètre supplémentaire) à un rappel avec les méthodes create_function() et call_user_function().

Ceci est pour référence:

<?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

de noter que le mot-clé 'use' a été ajouté dans PHP 5.4. la plupart des serveurs fonctionnent toujours 5.3 :( – mpen

+1

@Mark les mots-clés 'use' sont ajoutés dans PHP5.3 –

+0

@WouterJ: right., mais ils ont ajouté le support' $ this' dans 5.4? – mpen

0

oui j'utiliser quelque chose comme ceci pour définir et unset une variable changeant de sorte qu'il est disponible à la fonction de rappel et vous n'avez pas besoin le plus récent php pour le faire:

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

alors cela dans la fonction de rappel $ -> _ current_key est disponible:

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

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