Нехороший код, хочется лучше. Подскажите как.

vamfirius

Новичок
Доброго времени суток.
Проблема в следующем. Пишу свой первый движок. Возникла необходимость сделать антифлуд(введите цифирки с картинки и будет вам счастье.) Вот что пришло в голову и собственно говоря работает -

PHP:
*Введите число с картинки:</br>
<?php
$dp=opendir(ABS_PATH);
while($fNames[]=readdir($dp)){}
closedir($dp);
if(is_file($fNames[2])){unlink($fNames[2]);}
$img=@imagecreate(70,50);
for($i=0;$i<27;$i++){
	if($i<17){$vars[$i]=mt_rand(0,255);}
	else if($i<23){$vars[$i]=mt_rand(0,9);}
	else{$vars[$i]=mt_rand(5,30);}
}
$bgcolor=imagecolorallocate($img,$vars[0],$vars[1],$vars[2]);
$num1=imagecolorallocate($img,$vars[3],$vars[4],$vars[5]);
$num2=imagecolorallocate($img,$vars[6],$vars[7],$vars[8]);
$num3=imagecolorallocate($img,$vars[9],$vars[10],$vars[11]);
$num4=imagecolorallocate($img,$vars[12],$vars[13],$vars[14]);
$num5=imagecolorallocate($img,$vars[15],$vars[16],$vars[17]);
imagefill($img,0,0,$bgcolor);
imagechar($img,5,5,$vars[23],$vars[18],$num1);
imagechar($img,5,20,$vars[24],$vars[19],$num1);
imagechar($img,5,35,$vars[25],$vars[20],$num1);
imagechar($img,5,45,$vars[26],$vars[21],$num1);
imagechar($img,5,55,$vars[27],$vars[22],$num1);
imagepng($img,"$vars[9].png");
imagedestroy($img);
$q=$vars[18].$vars[19].$vars[20].$vars[21].$vars[22];
echo "<img src=$vars[9].png>";
echo "<input type=hidden name=quest value=$q>";
?>
<input type=text name=ans>
Почему сделал рандомное имя картинки и удаление её в начале загрузки, потому что иначе она не обновляется при переходе по ссылке с GET переменной, только после обновления страницы через кнопку браузера. Почему вообще не вынес скрипт формирования катринки в отдельный файл, потому что не знаю как вытащить из него переменные для проверки.
Насколько я знаю мой код будет довольно сильно нагружать сервер при достаточной посещаемости, поэтому прошу совета как сделать так чтобы картинка не сохранялась в файл и её не приходилось бы потом удалять.
 

vamfirius

Новичок
Прочитал про сессии. Узнал кое что об улучшении безопаности. Статьи phpclub как всегда на высоте. В общем полезно и в дальнейшем обязательно воспользуюсь изложенными там советами. Однако не могу понять как сессии можно использовать для решения моей проблемы. Или можно сохранять картинки в переменные сессии а потом как-то их выводить?
 

Mamont

Новичок
гугл "captcha"
Тебе надо:
1. в форме <img src="captcha.php" /><input ...
2. В скрипте captcha.php генерируешь какой-то уникальный ключ, сохраняешь в сессии. Ключ рисуешь на картинке, картинку отдаешь в браузер.
3. В скрипте получения формы извлекаешь ключ из сессии
 

vamfirius

Новичок
Переписал код следующим образом -
Файл image.php

PHP:
<?php
header('Content-type: image/png');
$img=@imagecreate(70,50);
for($i=0;$i<27;$i++){
	if($i<17){$vars[$i]=mt_rand(0,255);}
	else if($i<23){$vars[$i]=mt_rand(0,9);}
	else{$vars[$i]=mt_rand(5,30);}
}
$bgcolor=imagecolorallocate($img,$vars[0],$vars[1],$vars[2]);
$num1=imagecolorallocate($img,$vars[3],$vars[4],$vars[5]);
$num2=imagecolorallocate($img,$vars[6],$vars[7],$vars[8]);
$num3=imagecolorallocate($img,$vars[9],$vars[10],$vars[11]);
$num4=imagecolorallocate($img,$vars[12],$vars[13],$vars[14]);
$num5=imagecolorallocate($img,$vars[15],$vars[16],$vars[17]);
imagefill($img,0,0,$bgcolor);
imagechar($img,5,5,$vars[23],$vars[18],$num1);
imagechar($img,5,20,$vars[24],$vars[19],$num1);
imagechar($img,5,35,$vars[25],$vars[20],$num1);
imagechar($img,5,45,$vars[26],$vars[21],$num1);
imagechar($img,5,55,$vars[27],$vars[22],$num1);
imagepng($img);
imagedestroy($img);
session_start();
$_SESSION['capcha']=$vars[18].$vars[19].$vars[20].$vars[21].$vars[22];
?>
Вставка в страницу -

PHP:
<img src='путь/image.php'>
<?php
echo $_SESSION['capcha'];
unset($_SESSION['capcha']);
session_destroy();
?>
В переменной $_SESSION['capcha'] храниться предидущее число а не то которое на картинке в данный момент. Почему, подскажите плиз. Голову уже сломал не доходит до меня.
 

Mamont

Новичок
Каптчу нужно удалять только после проверки, а не сразу.
captcha.php
PHP:
<?php
header('Content-type: image/png');
session_start();
define('CAPTCHA_NUM_CHARS', 6 );

//Генерируем код для катринки
$chars = '0123456789qwertyuiopasdfghjklzxcvbnm';
$code = '';
for( $i=0; $i<CAPTCHA_NUM_CHARS; $i++ )
	$code .= $chars{ mt_rand(0,strlen($chars)-1) };

//Сохраняем его в сессии
$_SESSION['captcha'] = $code;

//Хитро рисуем код на картинке, ну пока не очень хитро
$img=imagecreate(CAPTCHA_NUM_CHARS*10+10,50);
$bgcolor=imagecolorallocate( $img, mt_rand(0,155), mt_rand(0,155), mt_rand(0,155) );
imagefill($img,0,0,$bgcolor);

for( $i=0; $i<CAPTCHA_NUM_CHARS; $i++ ){
	$color = imagecolorallocate( $img, mt_rand(55,255), mt_rand(55,255), mt_rand(55,255) );
	imagechar( $img, 5, $i*10+5, mt_rand(4,30), $code{$i}, $color );
}

imagepng($img);
imagedestroy($img);
test.php
PHP:
<?php
session_start();

if( isset($_POST['secret_word']) && isset($_SESSION['captcha']) ){

	if( $_POST['secret_word']==$_SESSION['captcha'] )
		echo "Угадали!";
	else
		echo "Промах!";

	unset($_SESSION['captcha']);
	echo "<br /><a href='{$_SERVER['REQUEST_URI']}'>Попытаться снова</a>";
} else {

echo <<< HTML
<form action="" method="post">
Введите код с картинки: <img src="captcha.php" /><br />
<input type="text" name="secret_word" />
<input type="submit" />
</form>
HTML;
}
 
Сверху