2016-05-23 7 views
1

Ich verwende preg_replace_callback, um Parameter an bestimmte URLs in ausgehenden E-Mails anzuhängen.pcre.trackback limit php preg_replace_callback()

Der Prozess funktioniert, indem eine E-Mail-Vorlage aus einer Datenbank geladen auf, eine Liste der Benutzer aus der gleichen Datenbank ziehen, und dann Führen des E-Mail-Körper durch diese Funktion:

function add_user_login($body, $user_id, $user_hash) { 
    ini_set('pcre.backtrack_limit',1000000000); 
    $return_string = preg_replace_callback('@(https?://([-\w\.]+)+mydomain.com([^"]*))@', function ($matches) use ($user_id, $user_hash) { 

     if (strpos($matches[0], "?") === false) { 
     return $matches[0] . "?user_id=" . $user_id . "&user_hash=" . $user_hash; 
     } else { 
     return $matches[0] . "&user_id=" . $user_id . "&user_hash=" . $user_hash; 
     } 
    }, $body); 

    return $return_string; 
} 

Das Ziel ist, dass alles, was mit "www.mydomain.com" oder "mydomain.com" erhalten die GET-Parameter "user_id" und "user_hash", die an sie angehängt werden. Leider gibt es vielleicht bereits existierende GET-Parameter und andere Dinge, die mit diesen nicht-einheitlichen URLs passieren, daher war dies die beste Methode, die ich bisher gefunden habe, um dies zu tun.

Mein Problem ist, dass ich aus irgendeinem Grund zurücktrack_limit Fehler beim Testen bekam und meine backtrack_limit erhöhen musste. Das hat beim Testen funktioniert, aber es ist unglaublich langsam.

Hat jemand anderes etwas ähnliches getan? Ich habe versucht, meine Regex zu ändern, und ich denke, dass das Backtrack-Problem von meiner Wildcard-Verwendung herrührt, aber alle Änderungen, die ich vorgenommen habe, haben dazu geführt, dass es nicht funktioniert hat.

+1

ersetzen Sie einfach '([- \ w \.] +) +' mit '- +' und versuchen Sie es erneut [\ w.]. –

Antwort

1

Die Regex, die Sie haben, enthält einen verschachtelten Quantifikator innerhalb - ([-\w\.]+)+. Dieses Untermuster, wenn es mit Untermustern verbunden ist, die mit denselben Zeichen übereinstimmen können, verursacht eine große Anzahl von Backtracking-Schritten.

Siehe die regex demo: 26.664 Schritte, um das Spiel zu vervollständigen. Mit https://see.my-cool-site.here.mydomain.c (eine nicht übereinstimmende Zeichenfolge) erhalten wir eine katastrophale Backtracking-Problem.

Die Lösung ist einfach zu bedienen [-\w.]+:

'@(https?://[-\w\.]+mydomain.com([^"]*))@' 

Sie können eine Erfassungsgruppe über das Muster halten, wenn Sie den Wert vor mydomain.com müssen (aber von Ihrem Code zu urteilen, müssen Sie nur das ganze Spiel benötigen) :

'@(https?://([-\w\.]+)mydomain.com([^"]*))@' 

Siehe regex demo

+0

Warum sollte jemand diese Antwort ablehnen? Es erklärt das Problem und bietet eine Lösung. –

+0

Ja, das ist seltsam. Es war nicht ich übrigens. Ich habe die Antwort aufgegriffen und akzeptiert. Ich frage mich, ob jemand aus Versehen es abgelehnt hat. Danke für deine Antwort, es war sehr hilfreich. –

+0

Gern geschehen. –