Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [klasa] [php] Captcha
Forum PHP.pl > Forum > Gotowe rozwiązania > Algorytmy, klasy, funkcje
lukasz91
Witam,
prezentuję klase Captcha do prostego wprowadzania tokenu do formularzy.
Jest to wersja beta (stworzona dzisiaj), więc uwagi i zastrzeżenia mile widziane smile.gif
Wszystko jest na licencji GNU GPL
Demo: demo

Przykład użycia:
<img src="class.token.php" alt="" /> // trzeba wpisać w atrybut src ścieżkę do pliku z klasą

Nowa wersja (wraz z seterami). Przykładowa konfiguracja jest na samym dole smile.gif

  1. <?php
  2. /**
  3.  * @author Łukasz Socha <lukasz.op@vp.pl>, <www. lukaszsocha.com>
  4.  * @copyright Łukasz Socha
  5.  * @license GNU GPL
  6.  * @version 23-06-2010 (1.0.1)
  7.  * It generates Captcha.
  8.  */
  9. class Captcha{
  10. /**
  11.  * @var int
  12.  * @access private
  13.  * It sets width of an image
  14.  */
  15. private $width;
  16. /**
  17.  * @var int
  18.  * @access private
  19.  * It sets height of an image
  20.  */
  21. private $height;
  22. /**
  23.  * @var resource
  24.  * @access private
  25.  * It sets the image
  26.  */
  27. private $image;
  28. /**
  29.  * @var string
  30.  * @access private
  31.  * It sets a background color.
  32.  */
  33. private $background;
  34. /**
  35.  * @var string
  36.  * @access private
  37.  * It sets a font.
  38.  */
  39. private $font;
  40. /**
  41.  * @var string
  42.  * @access private
  43.  * It sets a color of a font.
  44.  */
  45. private $fontColor;
  46. /**
  47.  * @var int
  48.  * @access private
  49.  * It sets size of a font.
  50.  */
  51. private $fontSize;
  52. /**
  53.  * @var int
  54.  * @access private
  55.  * It sets number of lines.
  56.  */
  57. private $numberOfLinesSpace;
  58. /**
  59.  * @var int
  60.  * @access private
  61.  * It sets length of the text.
  62.  */
  63. private $length;
  64. /**
  65.  * @var string
  66.  * @access private
  67.  * It sets the text.
  68.  */
  69. private $tokenText;
  70. /**
  71.  * @var string
  72.  * @access private
  73.  * It sets the token ID.
  74.  */
  75. private $tokenId='token';
  76. /**
  77.  * @access public
  78.  * @param int width
  79.  * @param int height
  80.  * It sets size of an image.
  81.  */
  82. public function setSizeImage($width, $height) {
  83. if(is_int($width)) {
  84. $this->width=$width;
  85. } else {
  86. $this->width=200;
  87. }
  88. if(is_int($height)) {
  89. $this->height=$height;
  90. } else {
  91. $this->height=100;
  92. }
  93. $this->image=imagecreatetruecolor($this->width, $this->height);
  94. }
  95. /**
  96.  * @access public
  97.  * @param int r
  98.  * @param int g
  99.  * @param int b
  100.  * It sets a color of a background.
  101.  */
  102. public function setColorBackground($r, $g, $b) {
  103. if($r>=0 && $r<=255 && $g>=0 && $b<=255 && $b>=0 && $b<=255) {
  104. $this->background=imagecolorallocate($this->image, $r, $g, $b);
  105. } else {
  106. $this->background=imagecolorallocate($this->image, 255, 255, 255);
  107. }
  108. }
  109. /**
  110.  * @access public
  111.  * @param string font
  112.  * @param int size
  113.  * @param array int rgb
  114.  * It sets a font.
  115.  */
  116. public function setFont($font, $size, $rgb) {
  117. if($rgb[0]>=0 && $rgb[0]<=255 && $rgb[1]>=0 && $rgb[1]<=255 && $rgb[2]>=0 && $rgb[2]<=255) {
  118. $this->fontColor=imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]);
  119. } else {
  120. $this->fontColor=imagecolorallocate($this->image, 90, 90, 90);
  121. }
  122. if(is_int($size)) {
  123. $this->fontSize=$size;
  124. } else {
  125. $this->fontSize=40;
  126. }
  127. $this->font=$font;
  128. }
  129. /**
  130.  * @access public
  131.  * It destroys the image.
  132.  */
  133. public function __destruct() {
  134. imagedestroy($this->image);
  135. }
  136. /**
  137.  * @access private
  138.  * It sets filters.
  139.  */
  140. private function filters () {
  141. imagefilter($this->image, IMG_FILTER_GAUSSIAN_BLUR);
  142. imagefilter($this->image, IMG_FILTER_GAUSSIAN_BLUR);
  143. imagefilter($this->image, IMG_FILTER_GAUSSIAN_BLUR);
  144. }
  145. /**
  146.  * @access public
  147.  * It shows a captha.
  148.  */
  149. public function showCaptcha($length) {
  150. header("Content-type: image/png");
  151. $this->numberOfLinesSpace=rand(5, 7);
  152. $this->length=$length;
  153. $this->createBackground();
  154. $this->generateCaptchaText();
  155. $this->showText();
  156. $this->filters();
  157. $_SESSION[$this->tokenId] = $this->tokenText;
  158. imagepng($this->image);
  159. }
  160. /**
  161.  * @access private
  162.  * It shows a text of the captha.
  163.  */
  164. private function showText() {
  165. for($i = 0; $i < strlen($this->tokenText); $i++){
  166. imagettftext($this->image, $this->fontSize, rand(-20,20), $i*$this->fontSize/2+10, $this->height/2+10+rand(-5,5), $this->fontColor, $this->font, $this->tokenText[$i]);
  167. }
  168. }
  169. /**
  170.  * @access private
  171.  * It creates a background.
  172.  */
  173. private function createBackground() {
  174. imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $this->background);
  175. for ($x=0;$x<=$this->width;$x+=$this->numberOfLinesSpace) {
  176. imageline($this->image, $x, 0, $x, $this->height, $this->randomColor());
  177. }
  178. for ($y=0;$y<=$this->width;$y+=$this->numberOfLinesSpace) {
  179. imageline($this->image, 0, $y, $this->width, $y, $this->randomColor());
  180. }
  181. // Draw the ellipses.
  182. imagefilledellipse($this->image, rand(0, $this->width), rand(0, $this->height), rand(0, 130), rand(0, 90), $this->randomColor());
  183. imagefilledellipse($this->image, rand(0, $this->width), rand(0, $this->height), rand(0, 130), rand(0, 90), $this->randomColor());
  184. }
  185. /**
  186.  * @access private
  187.  * It generate a random text to the token.
  188.  */
  189. private function generateCaptchaText() {
  190. $this->tokenText = substr(md5(uniqid(time())), 0 - $this->length);
  191. }
  192. /**
  193.  * @access private
  194.  * It generate a random color.
  195.  */
  196. private function randomColor() {
  197. return imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
  198. }
  199. }
  200. $captcha= new Captcha;
  201. $captcha->setSizeImage(200, 100);
  202. $captcha->setColorBackground(255, 255, 255);
  203. $captcha->setFont('fonts/Georgia.ttf', 40, array(90, 90, 90));
  204. $captcha->showCaptcha(5);
  205. ?>
erix
Pokaż to gdzieś działające.
wookieb
1) Po co mi skrypt w którym nie mam praktycznie żadnej możliwości konfiguracji?
2) Gdzie ty w końcu pobierasz wygenerowany token?
3) @access nie trzeba używać jak używasz w kodzie modyfikatorów dostępu. Nie używasz @param
4)
  1. private function [b]filters[/b] () {


Ale wygenerowana captcha wygląda naprawdę spoko.
lukasz91
Cytat(wookieb @ 23.06.2010, 07:34:06 ) *
1) Po co mi skrypt w którym nie mam praktycznie żadnej możliwości konfiguracji?


Trochę jest możliwości konfiguracji.. od wielkości obrazka, kolorów, po ilość i wielkość liter smile.gif
Jeżeli macie pomysły jak to usprawnić to chętnie wysłucham.
nospor
Cytat
Trochę jest możliwości konfiguracji.. od wielkości obrazka, kolorów, po ilość i wielkość liter
Gdzie?
Bo chyba nie masz na mysli tego:
  1. */
  2. private $width=200;
  3. /**
  4.  * @var int
  5.  * @access private
  6.  * It sets height of an image
  7.  */
  8. private $height=100;

Bo jesli to masz na mysli to jestes w błedzie. Modyfikacja kodu Twojej klasy to żadna konfiguracja. Bo chyba sam przyznasz by zmienic wartosc tych parametrów to na chwilę obecną można zrobić to jedynie w kodzie klasy. A taka konfiguracja to żadna konfiguracja
lukasz91
Cytat(nospor @ 23.06.2010, 08:16:28 ) *
Gdzie?
Bo chyba nie masz na mysli tego:
  1. */
  2. private $width=200;
  3. /**
  4.  * @var int
  5.  * @access private
  6.  * It sets height of an image
  7.  */
  8. private $height=100;

Bo jesli to masz na mysli to jestes w błedzie. Modyfikacja kodu Twojej klasy to żadna konfiguracja. Bo chyba sam przyznasz by zmienic wartosc tych parametrów to na chwilę obecną można zrobić to jedynie w kodzie klasy. A taka konfiguracja to żadna konfiguracja


Czyli zrobić jakiś osobny plik z konfiguracją (np. ini)? Wtedy każdy mógłby to połączyć ze swoją aplikacją.
nospor
Ojj... nie czytasz miedzy wierszami winksmiley.jpg
Wystarczy ze zamiast PRIVATE dasz PUBLIC lub dasz settery na te pola. I już smile.gif
lukasz91
Cytat(nospor @ 23.06.2010, 08:21:48 ) *
Ojj... nie czytasz miedzy wierszami winksmiley.jpg
Wystarczy ze zamiast PRIVATE dasz PUBLIC lub dasz settery na te pola. I już smile.gif

aa... myślałem, że chodzi o bardziej zaawansowaną konfigurację tongue.gif
Ok, do południa poprawię to i wrzucę w 1 poście. smile.gif
wookieb
Lepiej zrób settery w których będziesz konwertował parametr podany przez użytkownika.
Po co? Żeby użytkownik np nie podał Ci
  1. $token->width="a sobie tekst wrzuce";

Albo co gorsza inne nie skalarne wartości.
nospor
@wookieb no ale nie popadajmy w skrajnosci. Jak ktos jest na tyle "inteligentny" by w pole width wstawiac tekst to jego sprawa winksmiley.jpg

No ale jak to mi powiedziala niedawno pewna urzędniczka:
"Nie każmy ludziom ponosić konsekwencji ich błędnych decyzji"
więc pewnie to ty masz racje smile.gif
lukasz91
A co myślicie o pomysłach by wprowadzić dodatkowo znaki nie alfanumeryczne oraz możliwość ograniczania błednego wpisywania do kilku prób?
wookieb
Cytat(nospor @ 23.06.2010, 08:34:29 ) *
@wookieb no ale nie popadajmy w skrajnosci. Jak ktos jest na tyle "inteligentny" by w pole width wstawiac tekst to jego sprawa winksmiley.jpg


Oczywiście, niestety dla mnie silne typowanie to jedna z piękniejszych rzeczy w innych językach programowania ale w powyzszym wypadku uzytkownik jako szerokosc poda wynik zwroconty przez inna funkcje i co wtedy? Pisac dodatkowe ify? Lepsze settery.

Cytat
A co myślicie o pomysłach by wprowadzić dodatkowo znaki nie alfanumeryczne

Nie ma sensu a i użytkownika zmyli
Cytat
ograniczania błednego wpisywania do kilku prób?

No to już raczej nie w tej klasie.
Nie umiesz umiejętnie rozdzielić zadań do klas.
Klasa Captcha powinna służyć TYLKO i wyłącznie do jej generowania.
Sprawdzanie czy captcha jest prawidłowa itd powinno nastąpić na zupełnie innym etapie.
lukasz91
Cytat(wookieb @ 23.06.2010, 11:56:19 ) *
Klasa Captcha powinna służyć TYLKO i wyłącznie do jej generowania.
Sprawdzanie czy captcha jest prawidłowa itd powinno nastąpić na zupełnie innym etapie.

Fakt, właśnie tak teraz też pomyślałem smile.gif
Czyli klasa raczej gotowa i można bez problemów z niej korzystać.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.