Preg_match Anti Spam POST
Ik zit met een klein en vrij simpel beginnersprobleempje. Ik heb een simpele "wall" ontworpen met 1 enkele form waar je gewoon wat tekst kunt in voegen en bij de submit komt dat dan op de wall.
Maar nu worden bij het posten van die tekst eerst enkele controles gedaan. O.a. op lengte, leegte, enz. Maar ik zou graag ook iets maken tegen spam.
Zo zou ik bvb alle ongewone tekens dat je in een normale tekst niet nodig hebt zoals / < > $ * % enz (uitgezonder leestekens( . , ; : ( ) ) en @) willen uitsluiten. En ik zou ook willen tegen gaan dat er mensen een spam doen met veel de zelfde letters na elkaar, dus laat ons zeggen dat je maar maximum 2 dezelfde letters naast elkaar moogt voegen(bvb: haaaaaaaaaaaaaaaallooo)
Zoals ik al eerder zij ben ik een beginner maar ik denk dat ik dit kan oplossen met een preg_match maar ik ben helemaal niet bekend met strings. Kunnen jullie mij daar bij helpen en zeggen hoe je er aan komt?
Alvast bedankt,
Pello
Gewijzigd op 12/02/2011 17:32:37 door Pello Mugica-Gonzalez
Een goede tutorial daarvoor is Regular expressions.
Daarin wordt alles uitgelegd.
De regex om alle tekens op A-Z, a-z, 0-9 en .,;:()@ te willen blokkeren kan je bijv. Deze regex proberen:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$regex = '/[^A-Za-z0-9\.,;:\(\)]/';
$preg = preg_match($regex, $_POST['iets']);
if($preg === false) {
echo 'Dit is spam!';
}
else {
echo 'Je hebt normaal gereageerd!';
}
$regex = '/[^A-Za-z0-9\.,;:\(\)]/';
$preg = preg_match($regex, $_POST['iets']);
if($preg === false) {
echo 'Dit is spam!';
}
else {
echo 'Je hebt normaal gereageerd!';
}
De uitleg:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
[ Begin van een character class
^ Match alle tekens met uitzondering van tekens in deze character class
A-Z Match A-Z (door de eerdere ^ wordt het eigenlijk match niet)
a-z Match a-z
0-9 Match 0-9
\.,;:\(\) Match .,;:(). Doordat . () tekens zijn die je bij speciale regexen kan gebruiken moet je deze door middel van de backslash \ als gewone teken declareren.
] Einde character class
^ Match alle tekens met uitzondering van tekens in deze character class
A-Z Match A-Z (door de eerdere ^ wordt het eigenlijk match niet)
a-z Match a-z
0-9 Match 0-9
\.,;:\(\) Match .,;:(). Doordat . () tekens zijn die je bij speciale regexen kan gebruiken moet je deze door middel van de backslash \ als gewone teken declareren.
] Einde character class
Voor de meerdere letters achterelkaar kan je doen met grouping metacharacters. Dit zijn (). Alles wat hier tussen staat wordt onthouden. Dit kan je weer terug halen met \1 \2, enz.
Voorbeeld
Uitleg:
Code (php)
1
2
3
4
5
2
3
4
5
( Dit is het begin van een metacharacters
. In een regex matched de . alles behalve spaties
{1} Door middel van {1} geven we aan dat het precies 1 keer mag matchen.
) Einde metacharacters
(\1) Nu kijken we of de letter 2 keer achter elkaar staat. Dit doen we doormiddel van \1. Hierin staat de informatie van het stukje van het eerste haakje
. In een regex matched de . alles behalve spaties
{1} Door middel van {1} geven we aan dat het precies 1 keer mag matchen.
) Einde metacharacters
(\1) Nu kijken we of de letter 2 keer achter elkaar staat. Dit doen we doormiddel van \1. Hierin staat de informatie van het stukje van het eerste haakje
Om 2 keer achter elkaar te kijken wordt een beetje gevaarlijk. Want je kan in woorden als een ook 2 keer eenzelfde letter hebben. Dus je kan beter kijken op 3 tekens:
Dit wordt allemaal uitgebreid en beter uitgelegd in de tutorial die ik je net gaf. Ik raad je aan die te lezen en dan deze uitleg.
Gewijzigd op 12/02/2011 19:17:26 door Wouter J
Deze duidelijke uitleg is me zeer gunstig geweest, en ook de tut is zeer goed.
Hier zullen meerdere mensen gebruik van kunnen maken!
Ik test hem nu uit.
Toevoeging op 12/02/2011 19:54:28:
Ik heb hem zonet uitgetest en het blijkt niet te werken..
Weet je wat ik fout doe?
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?PHP
// Anti Speciale tekens
if( !preg_match("/[A-Za-z0-9\'\"\.:;@!?\)\(]/", $ber) ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je hebt ongeldige tekens gebruikt.<BR><B>Let op:</B> buiten leestekens zijn er geen speciale karakters toegelaten, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
}
?>
// Anti Speciale tekens
if( !preg_match("/[A-Za-z0-9\'\"\.:;@!?\)\(]/", $ber) ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je hebt ongeldige tekens gebruikt.<BR><B>Let op:</B> buiten leestekens zijn er geen speciale karakters toegelaten, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
}
?>
Gewijzigd op 12/02/2011 19:58:07 door Pello Mugica-Gonzalez
Een ? moet je ook met een \ ervoor doen.
Dit is mijn script dan is het wat duidelijker.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?PHP
function postmsg($naam, $ber)
{
if(antiflood() == true)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je kunt maar 1 bericht per minuut plaatsen!</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
$naam = mysql_real_escape_string($naam);
$ber = mysql_real_escape_string($ber);
// Anti Speciale tekens
if( !preg_match("/[A-Za-z0-9\'\"\.:;@!\?]/", $ber) ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je hebt ongeldige tekens gebruikt.<BR><B>Let op:</B> buiten leestekens zijn er geen speciale karakters toegelaten, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Anti vijfdubbel lettergebruik tekens
if( preg_match("/(.{1})(\1)(\1)/", $ber) === false ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;"><B>Let op:</B> Je kan slechts 5 maal dezelfde letter in 1 woord gebruiken, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of er een veld leeg is
if(empty($naam) || empty($ber) || $naam == "Kies een schuilnaam.")
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Alle velden moeten worden ingevuld.<BR>Vergat je uw schuilnaam niet in te vullen?</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of het bericht langer is dan 250 karakters
if (strlen($ber) > 400)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Een bericht mag maximum 400 karakters bevatten.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of het bericht korter is dan 5 karakters
if (strlen($ber) < 5)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Een bericht moet minumum 5 karakters bevatten.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren op scheldwoorden
$searchWord = array("kut", "hoer", "loser", "motherfucker", "aars", "viagra", "penis", "kut", "vagina", "aarsridder", "klootzak", "hoer", "zwerver", "dikzak", "dik", "lelijk", "lul", "eikel", "homo", "teringlijer", "fuck", "fuckyou", "rot");
foreach($searchWord as $word)
{
if(strpos($ber, $word) != false) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Hou het vriendelijk.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit;
}
}
// Als alles goed is, naar de database sturen
$sql = "INSERT INTO shout (naam, bericht) VALUES ('".strip_tags($naam)."', '".strip_tags($ber)."')";
$res = mysql_query($sql);
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je bericht is geplaatst.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
}
?>
function postmsg($naam, $ber)
{
if(antiflood() == true)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je kunt maar 1 bericht per minuut plaatsen!</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
$naam = mysql_real_escape_string($naam);
$ber = mysql_real_escape_string($ber);
// Anti Speciale tekens
if( !preg_match("/[A-Za-z0-9\'\"\.:;@!\?]/", $ber) ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je hebt ongeldige tekens gebruikt.<BR><B>Let op:</B> buiten leestekens zijn er geen speciale karakters toegelaten, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Anti vijfdubbel lettergebruik tekens
if( preg_match("/(.{1})(\1)(\1)/", $ber) === false ) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;"><B>Let op:</B> Je kan slechts 5 maal dezelfde letter in 1 woord gebruiken, dit om spam te voorkomen.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of er een veld leeg is
if(empty($naam) || empty($ber) || $naam == "Kies een schuilnaam.")
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Alle velden moeten worden ingevuld.<BR>Vergat je uw schuilnaam niet in te vullen?</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of het bericht langer is dan 250 karakters
if (strlen($ber) > 400)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Een bericht mag maximum 400 karakters bevatten.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren of het bericht korter is dan 5 karakters
if (strlen($ber) < 5)
{
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Een bericht moet minumum 5 karakters bevatten.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit();
}
// Controleren op scheldwoorden
$searchWord = array("kut", "hoer", "loser", "motherfucker", "aars", "viagra", "penis", "kut", "vagina", "aarsridder", "klootzak", "hoer", "zwerver", "dikzak", "dik", "lelijk", "lul", "eikel", "homo", "teringlijer", "fuck", "fuckyou", "rot");
foreach($searchWord as $word)
{
if(strpos($ber, $word) != false) {
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Hou het vriendelijk.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
exit;
}
}
// Als alles goed is, naar de database sturen
$sql = "INSERT INTO shout (naam, bericht) VALUES ('".strip_tags($naam)."', '".strip_tags($ber)."')";
$res = mysql_query($sql);
echo '<div style="margin-top: 150px; font-size: 30px; color: #999999;">Je bericht is geplaatst.</div>';
echo "<head>
<meta http-equiv='refresh' content='3; URL=index.php'>
</head>";
}
?>
Gewijzigd op 12/02/2011 20:32:15 door Pello Mugica-Gonzalez
Sorry zie nu de fout. Als er iets matched is het spam. Dus je moet niet kijken of preg_match true weergeeft.
Zo ja -> Spam
Zo nee -> Normaal bericht
En nog wat extra's. Met het extraheren van de regex (staat uitgelegd in de tutorial) kun je ook nog zorgen dat de gebruiker ziet welke tekens er verkeerd waren.
Gewijzigd op 13/02/2011 12:37:07 door Wouter J
Zomaar even een opmerking, er zijn natuurlijk ook geldige woorden met 3x dezelfde letter. Vaak hoort daar dan bijvoorbeeld een trema op, zoals "een reeele kans", maar die wordt nog wel eens achterwege gelaten :)