preg_replace shim z obsługą eval
To jest bardzo niewskazane. Ale jeśli nie jesteś programistą lub naprawdę wolisz okropny kod, możesz użyć preg_replace
funkcji zastępczej, aby tymczasowo utrzymać /e
flagę w działaniu .
function preg_replace_eval($pattern, $replacement, $subject, $limit=-1) {
$pattern = preg_replace('/(\W[a-df-z]*)e([a-df-z]*)$/i', '$1$2', $pattern);
if (preg_match('/\(\.[+*]/', $pattern)) {
trigger_error("preg_replace_eval(): regex contains (.*) or (.+) placeholders, which easily causes security issues for unconstrained/user input in the replacement expression. Transform your code to use preg_replace_callback() with a sane replacement callback!");
}
return preg_replace_callback(
$pattern,
function ($matches) use ($replacement) {
$repl = preg_replace_callback(
'/(?<!\\\\)(?:[$]|\\\\)(\d+)/',
function ($m) use ($matches) {
if (!isset($matches[$m[1]])) { trigger_error("No capture group for '$m[0]' eval placeholder"); }
return addcslashes($matches[$m[1]], '\"\'\`\$\\\0');
},
$replacement
);
return eval("return $repl;");
},
$subject,
$limit
);
}
W istocie wystarczy dołączyć tę funkcję do swojej bazy kodu i edytować preg_replace
ją preg_replace_eval
tam, gdzie /e
została użyta flaga.
Plusy i minusy :
- Naprawdę właśnie przetestowano z kilkoma próbkami ze Stack Overflow.
- Obsługuje tylko proste przypadki (wywołania funkcji, a nie wyszukiwania zmiennych).
- Zawiera kilka dodatkowych informacji o ograniczeniach i poradach.
- Przy błędach ekspresji wystąpią przemieszczone i mniej zrozumiałe błędy.
- Jednak nadal jest użytecznym rozwiązaniem tymczasowym i nie komplikuje prawidłowego przejścia na
preg_replace_callback
.
- A komentarz do licencji ma po prostu zniechęcić ludzi do nadużywania lub rozpowszechniania tego zbyt daleko.
Generator kodów zastępczych
Teraz jest to trochę zbędne. Ale może pomóc tym użytkownikom, którzy wciąż są przytłoczeni ręczną restrukturyzacją kodu do preg_replace_callback
. Chociaż jest to bardziej czasochłonne, generator kodu ma mniej problemów z rozszerzeniem /e
zastępującego ciągu znaków na wyrażenie. To bardzo zwyczajne nawrócenie, ale prawdopodobnie wystarcza w przypadku większości rozpowszechnionych przykładów.
Aby użyć tej funkcji, edytuj każde przerwane preg_replace
wywołanie preg_replace_eval_replacement
i uruchom je raz . Spowoduje to wydrukowanie odpowiedniego preg_replace_callback
bloku, który ma zostać użyty w jego miejsce.
function preg_replace_eval_replacement($pattern, $replacement, $subjectvar="IGNORED") {
$pattern = preg_replace('/(\W[a-df-z]*)e([a-df-z]*)$/i', '$1$2', $pattern);
$replacement = preg_replace_callback('/[\'\"]?(?<!\\\\)(?:[$]|\\\\)(\d+)[\'\"]?/', function ($m) { return "\$m[{$m[1]}]"; }, $replacement);
$ve = "var_export";
$bt = debug_backtrace(0, 1)[0];
print "<pre><code>
#----------------------------------------------------
# replace preg_*() call in '$bt[file]' line $bt[line] with:
#----------------------------------------------------
\$OUTPUT_VAR = preg_replace_callback(
{$ve($pattern, TRUE)},
function (\$m) {
return {$replacement};
},
\$YOUR_INPUT_VARIABLE_GOES_HERE
)
#----------------------------------------------------
</code></pre>\n";
}
Pamiętaj, że samo kopiowanie i wklejanie nie jest programowaniem. Będziesz musiał dostosować wygenerowany kod z powrotem do rzeczywistych nazw zmiennych wejścia / wyjścia lub kontekstu użycia.
- W szczególności
$OUTPUT =
przypisanie musiałoby przejść, gdyby poprzednie preg_replace
wywołanie zostało użyte w pliku if
.
- Najlepiej jednak zachować zmienne tymczasowe lub strukturę wielowierszowego bloku kodu.
A wyrażenie zastępcze może wymagać większej poprawy czytelności lub przeróbek.
- Na przykład
stripslashes()
często staje się zbędne w wyrażeniach dosłownych.
- Wyszukiwanie w zakresie zmiennych wymaga odwołania
use
lub global
odniesienia do / w wywołaniu zwrotnym.
- Nierównomiernie ujęte w cudzysłowy
"-$1-$2"
odniesienia do przechwytywania zostaną podzielone składniowo przez zwykłą transformację do "-$m[1]-$m[2]
.
Kod wyjściowy jest jedynie punktem wyjścia. I tak, byłoby to bardziej przydatne jako narzędzie online. To podejście do przepisywania kodu (edycja, uruchamianie, edycja, edycja) jest nieco niepraktyczne. Jednak może być bardziej przystępny dla tych, którzy są przyzwyczajeni do kodowania skoncentrowanego na zadaniach (więcej kroków, więcej odkryć). Ta alternatywa może więc ograniczyć kilka dodatkowych pytań.