Rozszerzone strip_tags()
12 listopada 2008
Ostatnio poprawiałem funkcjonalność get_meta_tags(), teraz przyszedł czas na strip_tags().
Najpierw kilka zdań o samej funkcji strip_tags() (dla tych, którzy jej nie znają chociaż każdy programista PHP znać ją powinien
).
Funkcja służy do łatwego, szybkiego i bezbolesnego pozbywania się tagów HTML z tekstu i przyjmuje dwa argumenty. Pierwszy to oczywiście tekst na którym ma pracować a drugi (opcjonalny) to lista tagów, które mają zostać pominięte podczas usuwania.
Przykład:
-
$tekst = 'To jest <b>test</b> działania <i>funkcji</i> strip_tags()';
-
echo "\r\n";
Powyższy kod PHP da nam taki wynik:
-
To jest test działania funkcji strip_tags()
-
To jest <b>test</b> działania funkcji strip_tags()
Pierwsze wywołanie funkcji spowodowało usunięcie wszystkich tagów z tekstu. W drugim nakazaliśmy pominąć tagi <b> i tak też się stało.
Niestety czasami funkcja strip_tags() nie wystarcza. Oto przykład problematycznej sytuacji:
-
$tekst = 'Jakiś tekst
-
<script type="text/javascript">
-
jakiś kod JavaScript
-
</script>
-
dalsza część strony';
Wynik:
-
Jakiś tekst
-
-
jakiś kod JavaScript
-
-
dalsza część strony
Funkcja oczywiście zadziałała poprawnie ale w tym konkretnym przypadku pewnie większość osób wolałaby aby razem z tagami zostało usunięte to co było między nimi czyli kod JavaScript. Z tym jednak musimy sobie poradzić sami i tu z pomocą przychodzi moja funkcja:
-
function strip_tags_content($text, $tags = '', $invert = FALSE) {
-
-
-
if($invert == FALSE) {
-
}
-
else {
-
}
-
}
-
elseif($invert == FALSE) {
-
}
-
return $text;
-
}
Funkcja przyjmuje trzy parametry. Pierwszy to tekst na którym pracujemy, drugi to lista tagów, które będą pominięte (o ile parametr trzeci jest ustawiony na FALSE, ustawienie domyślne) lub zostaną usunięte (gdy trzeci parametr ustawimy na TRUE).
Najlepiej zobrazuje to przykład. Tekst na którym będziemy pracować:
Efekt strip_tags():
-
przykładowy tekst
-
-
jakiś skrypt JavaScript
-
-
tekst abc
-
-
pogrubiony tekst
-
bla bla lala ble ble
-
i jeszcze jedna linijka
-
kolejny tekst
Wywołanie strip_tags_content() bez parametrów (usunie wszystkie tagi z zawartością umieszczoną między nimi):
Wywołanie strip_tags_content() z drugim parametrem o wartości '<script><span>' (ma usunąć wszystkie tagi oprócz <script> i <span>):
Wywołanie strip_tags_content() z drugim parametrem o wartości '<span><b>' i trzecim parametrem ustawionym na TRUE (ma usunąć tylko tagi <span> i <b>):
Mam nadzieję, że przykłady są jasne i nie trzeba nic wyjaśniać. Wyposażeni w obie funkcje (standardową strip_tags() i moją strip_tags_content() ) mamy pełną kontrolę nad tym co ma pozostać w tekście a co ma być z niego usunięte.
Blog przede wszystkim o Internecie i mojej pasji jaką jest tworzenie stron www. Ale nie ograniczam się do jednej tematyki, piszę o wszystkim o czym mam ochotę :-)
cymerus napisał: 14.11.08 o godzinie 13:45
jest tylko jedno ale
„inline javascript”
czyli javascript w tagach, chetnie zobaczylbym jaki masz pomysl na pozostawianie tagow, ale bezpiecznych tagow bez javascriptu
MariuszT napisał: 14.11.08 o godzinie 17:18
Jeżeli potrzebujesz usunąć wszystkie argumenty z tagów to sprawa jest prosta. Trochę więcej trzeba się narobić jeżeli chcesz usuwać tylko wybrane argumenty lub tylko wybrane zostawić.
W komentarzach na stronie http://pl.php.net/strip_tags masz kilka prób usuwania argumentów dla tagów. Nie wiem jak to działa bo nie testowałem
Firenze_Alessio napisał: 22.12.09 o godzinie 3:32
Hi guys. You made a great job with the strip_tags_content function..I have a question: i need to use regular expressions to replace a string that is not inside a tag < a > or inside a tag . This string can be inside other tags but not inside < a >. I’m not as good as you guys are with regular expressions, but i guess it’s the fastest way to do something like this.
As strip_tags_content() shows, the regular expression should be something like this:
@.*?@si
but for example if i want to replace the word Hello with Bye, how should i edit the regex?
Thanks in advance.
MariuszT napisał: 22.12.09 o godzinie 13:32
Hi, I got an email from you.
What you want exactly to do:
1) Replace all strings Hello (inside and outside all tags) except those in A tags?
2) Replace all strings Hello in all tags except A tags but not outside the tags?
3) Replace all strings Hello only in H1 tags (not inside and outside other tags).
4) Replace all strings Hello only in H1 tags and outside other tags.
5) …. ?
Explain exactly what you want.
Firenze_Alessio napisał: 22.12.09 o godzinie 16:15
Sorry, i can tell that my explanation was really bad. I want to replace all strings Hello inside and outside all tags except those in A tags and except when the string Hello is an attribute of a tag, for example img alt=”Hello” shouldn’t be replaced. The regular expression above looks for tags a and h1, but i don’t really care to avoid strings between h1 tags. That regular expression is the one that your function strip_tags_content uses in the first case when it returns preg_replace(…)
I don’t know if you can help me! Thanks!
MariuszT napisał: 22.12.09 o godzinie 18:55
Check this:
$word1 = 'abc';$word2 = 'xyz';
$text = 'abc def <a abc="abc">abc</a> <h1>abc</h1> <abc abc="abc">def abc def</abc> abc';
echo htmlspecialchars($text), '<br />';
$return = preg_replace('@(?:'. preg_quote($word1) .'(?!(?:[^<]+)?>))(?!</a[ >])@si', $word2, $text);
echo htmlspecialchars($return);
Result:
abc def <a abc="abc">abc</a> <h1>abc</h1> <abc abc="abc">def abc def</abc> abcxyz def <a abc="abc">abc</a> <h1>xyz</h1> <abc abc="abc">def xyz def</abc> xyz
Firenze_Alessio napisał: 22.12.09 o godzinie 23:56
I think you are a genius! Thanks a lot! I hope this helps also someone else…It was pretty hard as regular expression or maybe i’m just an ignorant in that!
MariuszT napisał: 23.12.09 o godzinie 0:21
Regular expressions are very cool and powerful tool but it requires a lot of practice. I also did not immediately write each regexp.
I am glad that I helped you. Greetings from Poland and Merry Christmas
Firenze_Alessio napisał: 23.12.09 o godzinie 3:40
Yes you are right! Thanks again. Greetings from Italy and Merry Christmas!
anonim napisał: 23.12.09 o godzinie 13:55
Próbuje sprawić by funkcja dla wartości <b>znaki</b> nie usuwała wszystkie – a to robi..to zamierzone? Chyba powinna zostawić słowo ‘znaki’ ?
echo strip_tags_content(‘<b>znaki</b>’);
MariuszT napisał: 23.12.09 o godzinie 22:06
Po to właśnie powstała ta funkcja aby w łatwy sposób móc usuwać tagi z całą ich zawartością. Jeżeli chcesz usunąć tylko taki B i zostawić to co między nimi to użyj zwykłej funkcji strip_tags().
ebooki napisał: 13.04.10 o godzinie 10:37
Świetny skrypt do użycia w każdym formularzu ładującym dane do bazy.
mxf napisał: 20.04.10 o godzinie 7:44
A co w przypadku bardziej złożonego kodu do ataku na strony?
Zrobiłem test, powyższy skrypt przepuszcza taki kod.
A co w przypadku bardziej złożonego kodu do ataku na strony?
Np. „><script>JavaScript:alert(„Test XSS”);</script>
MariuszT napisał: 20.04.10 o godzinie 12:45
@mxf
Przetestowałem Twój przykład, usunęło mi prawidłowo tag script z całą jego zawartością. Może coś przeoczyłeś?
Flashstar napisał: 11.05.10 o godzinie 15:08
Świetna funkcja zamierzam ją wykorzystać na moich stronach. Pozdrawiam i stawiam piwko…
Konrad napisał: 13.08.10 o godzinie 7:34
Dobra funkcja.