(Negeer de vorige submit, daar zaten nog een klein bugje in. Deze is volledig getest en werkt.)
(Url werkt nog niet, maar zal binnenkort (~week) online komen.)
Ik had geen zin om een erg grafische AntiSpam methode te gebruiken op mijn website (dit omdat deze niet mooi in mijn layout pasten). Ik herinnerde me wel een leuke methode, namelijk de gebruiker vragen naar een (makkelijke) wiskunde bewerking. Aangezien ik hier geen mooi script (klasse) voor vond, heb ik er zelf eentje geschreven.
Hieronder de klasse die alles afhandeld. Hoe je het moet gebruiken staat tevens in dit script (zie comments bovenaan). (User input wordt sowieso gevalideerd in de klasse zelf. Op zich is het dus niet nodig dit nog eens extern te doen.)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
<?php
/**
* Anti Spam class file
*
* This file defines the AntiSpam class. This class is just a very
* simple AntiSpam class, no very advanced technics are being used.
* The AntiSpam method used is a simple mathematic operation (between
* two integers) the user has to solve.
*
* @author Hans De Mulder <info@sxdev.be>
* @version $Revision v1.0.3$
* @copyright Copyright (c) 2009, Hans De Mulder
* @license http://opensource.org/licenses/gpl-3.0.html GNU Public License version 3
* @package AntiSpam
*
* <code>
* <?php
* // Parameter is the prefix you want to use for the session.
* // This parameter is optional (only really needed if you want to
* // create multiple instances of AntiSpam).
* $antispam = new AntiSpam();
*
* // Validate
* // The value THE_ANSWER is being validated by the class itself,
* // so it isn't necessary do some special tricks with it to prevend
* // injections or any other bad things.
* if($antispam -> Validate(THE_ANSWER))
* {
* // If correct, continue
* }
* else
* {
* // Renew anti-spam
* // Generates new mathematic question
* $antispam -> Renew();
* }
*
* // Shows the mathematic question, in following style:
* // first_integer operation second_integer
* // (Example: 1 + 1)
* echo $antispam -> GetQuestion();
* </code>
*/
/**
* Changelog:
*
* - v1.0.3: Added optional parameter to constructer. This parameter is the prefix
* to be used for the session data. If you want to use multiple instances
* of this class, you will need to give each instance a different prefix.
*
* - v1.0.2: Fixed bug for the minus operation (when the last integer equals
* or is greater than the first integer, it always return false).
* Generation of the question ($this -> calc) now in one method instead
* of duplicate code in two other methods (__construct and Renew).
*
* - v1.0.1: Fixed some little bugs (forgot self:: on some class constants).
* Generating an integer now in one method instead of duplicate code
* in two methods (GenFint and GenLint).
* GetQuestion returned the integer alias of the operation instead of the
* string value of the operation (uses now method GetOperation to
* retrieve the string value).
*
* - v1.0.0: Initial release
*/
/**
* Start a new session if there is non started.
*/
if(!isset($_SESSION))
{
session_start();
}
class AntiSpam
{
/**
* Defines the operations to use. Each operation
* is represented by an integer.
*/
const OpAdd = 1;
const OpMinus = 2;
const OpMultiply = 3;
/**
* Minimum and maximum integer to use in the
* mathematical question.
*/
const MinInt = 1;
const MaxInt = 10;
/**
* Array containing the anti spam mathematical question
* f_int = first integer
* operation = operation to perform between f_int and l_int
* l_int = second integer
*
* @access private
* @var array
*/
private $calc = array();
/**
* Prefix for the session variable, default AS
* The session data will be PREFIX_variable
*
* @access private
* @var string
*/
private $prefix;
/**
* The constructor fills in the mathematical question.
* @param string $prefix The prefix to be used for the session data (needed with multiple instances!)
*/
public function __construct($prefix = 'AS')
{
$this -> prefix = !is_string($prefix) ? 'AS' : $prefix;
$this -> GenQuestion();
}
/**
* Renews the mathematical question.
*/
public function ReNew()
{
$this -> GenQuestion(true);
}
/**
* Returns the mathematical question in a simple form:
* first_integer operation second_integer
* (Example: 1 + 1)
*
* @return string
*/
public function GetQuestion()
{
return $this -> calc['f_int'] .' '. $this -> GetOperation() .' '. $this -> calc['l_int'];
}
/**
* Validates the answer provided by the user
*
* @param integer $answer
* @return boolean
*/
public function Validate($answer)
{
if(!ctype_digit($answer))
{
return false;
}
$correctanswer = 0;
switch($this -> calc['operation'])
{
case self::OpAdd:
$correctanswer = $this -> calc['f_int'] + $this -> calc['l_int'];
break;
case self::OpMinus:
$correctanswer = $this -> calc['f_int'] - $this -> calc['l_int'];
break;
case self::OpMultiply:
$correctanswer = $this -> calc['f_int'] * $this -> calc['l_int'];
break;
default:
return false;
break;
}
return ($answer == $correctanswer);
}
/**
* Generates the mathematical question
*
* @param boolean $renew Whether to renew the question or not
* @return void
*/
private function GenQuestion($renew = false)
{
$this -> calc['f_int'] = $this -> GenFint($renew);
$this -> calc['operation'] = $this -> GenOperation($renew);
$this -> calc['l_int'] = $this -> GenLint($renew);
}
/**
* Generates the first integer and puts it in a session variable. It also
* returns this value.
*
* @param boolean $renew Whether to renew the session variable or not
* @return integer
*/
private function GenFint($renew = false)
{
if($renew || empty($_SESSION[$this -> prefix.'_f_int']) || intval($_SESSION[$this -> prefix.'_f_int']) < self::MinInt || intval($_SESSION[$this -> prefix.'_f_int']) > self::MaxInt)
{
$_SESSION[$this -> prefix.'_f_int'] = $this -> GenInt();
}
return intval($_SESSION[$this -> prefix.'_f_int']);
}
/**
* Generates the (mathematical) operation to use and puts it in a session
* variable. It also return this value (note: the integer is an alias for
* the actual operation).
*
* @param boolean $renew Whether to renew the session variable or not
* @return integer
*/
private function GenOperation($renew = false)
{
if($renew || empty($_SESSION[$this -> prefix.'_operation']) || intval($_SESSION[$this -> prefix.'_operation']) < self::OpAdd || intval($_SESSION[$this -> prefix.'_operation']) > self::OpMultiply)
{
$_SESSION[$this -> prefix.'_operation'] = rand(self::OpAdd, self::OpMultiply);
}
return intval($_SESSION[$this -> prefix.'_operation']);
}
/**
* Generates the first integer and puts it in a session variable. It also
* returns this value.
*
* @param boolean $renew Whether to renew the session variable or not
* @return integer
*/
private function GenLint($renew = false)
{
if($renew || empty($_SESSION[$this -> prefix.'_l_int']) || intval($_SESSION[$this -> prefix.'_l_int']) < self::MinInt || intval($_SESSION[$this -> prefix.'_l_int']) > self::MaxInt)
{
if($this -> calc['operation'] == self::OpMinus)
{
do
{
$_SESSION[$this -> prefix.'_l_int'] = $this -> GenInt();
}
while($_SESSION[$this -> prefix.'_l_int'] >= $this -> calc['f_int']);
}
else
{
$_SESSION[$this -> prefix.'_l_int'] = $this -> GenInt();
}
}
return intval($_SESSION[$this -> prefix.'_l_int']);
}
/**
* Generates an integer, respecting the limits set in the constants
* above (MinInt and MaxInt).
*
* @return integer
*/
private function GenInt()
{
return rand(self::MinInt, self::MaxInt);
}
/**
* Returns the string value (symbol) of the operation used in the
* mathematical question.
*
* @return string
*/
private function GetOperation()
{
switch($this -> calc['operation'])
{
case self::OpAdd:
return '+';
break;
case self::OpMinus:
return '-';
break;
case self::OpMultiply:
return '*';
break;
default:
return '';
break;
}
}
}
|
|
|
Download (248)