За последние 24 часа нас посетили 103342 программиста и 5693 робота. Сейчас ищут 3160 программистов ...

Captcha

Тема в разделе "PHP для новичков", создана пользователем Николай_, 8 май 2016.

  1. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    Подскажите, пожалуйста!

    Не работает captcha.

    Как установить captcha на обычной странице (например, http://host/index.php?p=valid),

    чтобы при клике на эту ссылку генерировалось новое изображение, без привлечения JS?

    Множество вариантов, предложенных в сети – не работают (или совсем, или не полностью).

    Вариант 1

    PHP:
    1. <?php
    2.  
    3.  
    4. $count=5;  /* количество символов */
    5.  
    6. $width=100; /* ширина картинки */
    7.  
    8. $height=48; /* высота картинки */
    9.  
    10. $font_size_min=32; /* минимальная высота символа */
    11.  
    12. $font_size_max=32; /* максимальная высота символа */
    13.  
    14. $font_file="./Comic_Sans_MS.ttf"; /* путь к файлу относительно w3captcha.php */
    15.  
    16. $char_angle_min=-10; /* максимальный наклон символа влево */
    17.  
    18. $char_angle_max=10;  /* максимальный наклон символа вправо */
    19.  
    20. $char_angle_shadow=5;  /* размертени */
    21.  
    22. $char_align=40;  /* выравнивание символа по-вертикали */
    23.  
    24. $start=5;  /* позиция первого символа по-горизонтали */
    25.  
    26. $interval=16;  /* интервал между началами символов */
    27.  
    28. $chars="0123456789"; /* набор символов */
    29.  
    30. $noise=10; /* уровень шума */
    31.  
    32.  
    33. $image=imagecreatetruecolor($width, $height);
    34.  
    35.  
    36. $background_color=imagecolorallocate($image, 255, 255, 255); /* rbg-цветфона */
    37.  
    38. $font_color=imagecolorallocate($image, 32, 64, 96); /* rbg-цветтени */
    39.  
    40.  
    41. imagefill($image, 0, 0, $background_color);
    42.  
    43.  
    44. $str="";
    45.  
    46.  
    47. $num_chars=strlen($chars);
    48.  
    49. for ($i=0; $i<$count; $i++)
    50.  
    51. {
    52.  
    53.   $char=$chars[rand(0, $num_chars-1)];
    54.  
    55.   $font_size=rand($font_size_min, $font_size_max);
    56.  
    57.   $char_angle=rand($char_angle_min, $char_angle_max);
    58.  
    59.   imagettftext($image, $font_size, $char_angle, $start, $char_align, $font_color, $font_file, $char);
    60.  
    61.   imagettftext($image, $font_size, $char_angle+$char_angle_shadow*(rand(0, 1)*2-1), $start, $char_align, $background_color, $font_file, $char);
    62.  
    63.   $start+=$interval;
    64.  
    65.   $str.=$char;
    66.  
    67. }
    68.  
    69.  
    70. if ($noise)
    71.  
    72. {
    73.  
    74.   for ($i=0; $i<$width; $i++)
    75.  
    76.   {
    77.  
    78.   for ($j=0; $j<$height; $j++)
    79.  
    80.   {
    81.  
    82.   $rgb=imagecolorat($image, $i, $j);
    83.  
    84.   $r=($rgb>>16) & 0xFF;
    85.  
    86.   $g=($rgb>>8) & 0xFF;
    87.  
    88.   $b=$rgb & 0xFF;
    89.  
    90.   $k=rand(-$noise, $noise);
    91.  
    92.   $rn=$r+255*$k/100;
    93.  
    94.   $gn=$g+255*$k/100;
    95.  
    96.   $bn=$b+255*$k/100;
    97.  
    98.   if ($rn<0) $rn=0;
    99.  
    100.   if ($gn<0) $gn=0;
    101.  
    102.   if ($bn<0) $bn=0;
    103.  
    104.   if ($rn>255) $rn=255;
    105.  
    106.   if ($gn>255) $gn=255;
    107.  
    108.   if ($bn>255) $bn=255;
    109.  
    110.   $color=imagecolorallocate($image, $rn, $gn, $bn);
    111.  
    112.   imagesetpixel($image, $i, $j , $color);
    113.  
    114.   }
    115.  
    116.   }
    117.  
    118. }
    119.  
    120.  
    121. $_SESSION["captcha"]=$str;
    122.  
    123.  
    124. if (function_exists("imagepng"))
    125.  
    126. {
    127.  
    128.   header("Content-type: image/png");
    129.  
    130.   imagepng($image);
    131.  
    132. }
    133.  
    134. elseif (function_exists("imagegif"))
    135.  
    136. {
    137.  
    138.   header("Content-type: image/gif");
    139.  
    140.   imagegif($image);
    141.  
    142. }
    143.  
    144. elseif (function_exists("imagejpeg"))
    145.  
    146. {
    147.  
    148.   header("Content-type: image/jpeg");
    149.  
    150.   imagejpeg($image);
    151.  
    152. }
    153.  
    154.  
    155. imagedestroy($image);
    156.  
    157. ?>
    Выводит бинарный код в браузер (что и указано в описании imagepng и ей подобным).

    Как от него избавиться? Header уже вне игры, echo задействована.


    Вариант 2

    То же, но вывод сгенерированного изображения в файл. Казалось бы, прекрасно и все должно работать, но:

    - при ссылке на созданное изображение с помощью img (src="image.png") - не работает обновление

    изображения при клике на ссылку http://host/index.php?p=valid, а f5 срабатывает.

    - если в дескриптор изображения поместить сценарий, создающий изображение

    (<img src="captcha.php">) - обновление работает и при клике на ссылку и по f5.

    Но тогда не доступна переменная сессии (echo показывает пустую строку) в которой сохранена

    уникальная строка для последующей проверки ее со значением из формы.


    Пробовал уникальные ссылки, кодировки (не понял, зачем это здесь, но умные люди советовали),

    кеширование и многое другое (на мой непрофессиональный взгляд не имеющее к данному вопросу отношения).

    Ничего пока не помогло. Уверен, что есть простой

    и надежный способ сделать код рабочим, но не знаю какой. Поэтому и обратился на специализированный

    форум.
     
    #1 Николай_, 8 май 2016
    Последнее редактирование модератором: 8 май 2016
  2. mr.akv

    mr.akv Активный пользователь

    С нами с:
    31 мар 2015
    Сообщения:
    1.599
    Симпатии:
    206
  3. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    Можно вообще не изучать php– использовать готовые скрипты и сайты.
    Кстати, это и есть один из велосипедов, предложенных в сети.
    Это простой код и он должен работать.
     
  4. mr.akv

    mr.akv Активный пользователь

    С нами с:
    31 мар 2015
    Сообщения:
    1.599
    Симпатии:
    206
    Не самое лучшее сравнение. Ну да ладно. Может кто подскажет.
    Библиотека ImageMagic то хоть установлена?
     
  5. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    Нет и не будет установлена. Зачем?
    ImageMagick 6.9.2-1 Q16 x86_64 2015-11-09 http://www.imagemagick.org
    Эта установка поможет?
     
  6. mr.akv

    mr.akv Активный пользователь

    С нами с:
    31 мар 2015
    Сообщения:
    1.599
    Симпатии:
    206
    сорян, не ImageMagic, а GD.
    --- Добавлено ---
    о, а GD встроена в сам PHP теперь, оказывается.
    Ну теперь остаётся ждать, когда кто-нибудь знающий подойдёт. :)
     
  7. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    А как без GD будет работать вышеуказанный код?
     
  8. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    есть такая конструкция как:
    PHP:
    1.  
    2. echo 'hello';
    3. echo 'world';
    4.  
    5. $text = ob_get_contents();
    'hello' и 'world' НЕ будут выведены в браузер, а будут записаны в $text, это должно помочь. Но я когда то столкнулся с такой проблемой что картинка норм, а в браузере не отображалось. А точнее отдельно в файле картинка открывалась, а вот на странице wordpress в теге img нет.
    Может как то можно приспособить в твоём вопросе.

    а вообще я вижу это так, код должна генерировать сама картинка - captcha_imp.php
    а обновляться (картинку и код) она как раз должна при клике на картинку, следующим образом - изменение адреса картинки, на все тот же, но тут есть проблема если адрес тот же ни чего не произойдет, т.е. к адресу надо добавлять какие то GET параметры что бы каждый раз адрес был разный.
     
  9. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    Пробовал это – не работает. Не понимаю простого, почему сценарию не доступна переменная сессии. А если доступна, то нет обновления кликом по ссылке. f5 – работает. Не писать же – для обновления captcha нажмите f5. А вообще, правильно понимаю, что $_SESSION должна быть доступна везде и всюду, после того как мы ее где-то вписали?
     
    #9 Николай_, 9 май 2016
    Последнее редактирование: 9 май 2016
  10. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    при выполнении скрипта она доступна везде после
    PHP:
    но это надо делать ДО вывода чего-либо в браузер.
     
  11. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    PHP:
    1. <?php
    2. //
    3. ?>
    HTML:
    1. <img src="captcha.php">
    В файле captcha.php генерируется изображение. В нем же $_SESSION получает уникальное значение.

    Теперь вопрос, т. к. изображение создается, значит, код php выполняется, следовательно
    $_SESSION существует, но на деле ее нет!?

    Вот этого понять не могу. В файле captcha.php она есть, за пределами этого файла ее нет.

    Один вариант придумал (уникальные адреса файлов) и он номинально работает, но, конечно, неуместен.

    Всех с праздником!
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.333
    Симпатии:
    1.753
    должна быть везде. Сессия на то и сессия.
     
  13. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    вот нашел код в интурнете, возможно он тебе поможет:
    PHP:
    1. function insert_base64_encoded_image($img, $echo = false){
    2.     $imageSize = getimagesize($img);
    3.     $imageData = base64_encode(file_get_contents($img));
    4.     $imageHTML = "<img src='data:{$imageSize['mime']};base64,{$imageData}' {$imageSize[3]} />";
    5.     if($echo == true){
    6.         echo $imageHTML;
    7.     } else {
    8.         return $imageHTML;
    9.     }
    10. }
    там просто в src надо указывать еще тип файла (data), base64 и т.д.
    --- Добавлено ---
    хотя возможно этот код будет работать криво, потому что там 2 раза вызывается картинка, первый раз:
    PHP:
    1. $imageSize = getimagesize($img);
    второй
    PHP:
    1. $imageData = base64_encode(file_get_contents($img));
    соответственно код будет перезаписываться, короче если что имей ввиду, может это ни как не повлияет.
     
  14. Николай_

    Николай_ Новичок

    С нами с:
    8 май 2016
    Сообщения:
    7
    Симпатии:
    0
    Это работает, спасибо, но предыдущий вопрос остается открытым ($_SESSION).
    Чем этот вариант отличается от варианта с тегом <img src="captcha.php">.
    По существу они решают одну задачу, но последний не работает.