Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP]captcha
b4rt3kk
post
Post #1





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Witam, napisałem sobie system captcha, oto klasa:

  1. class captcha{
  2.  
  3. public $width;
  4. public $height;
  5. public $characters;
  6. public $lines;
  7.  
  8. function __construct($width, $height, $characters, $lines){
  9. $this -> width = $width;
  10. $this -> height = $height;
  11. $this -> characters = $characters;
  12. $this -> lines = $lines;
  13. }
  14.  
  15. function drawCaptcha(){
  16.  
  17. // set up margin as 10% of image height
  18.  
  19. $margin = ceil($this -> height * 0.1);
  20.  
  21. // randomize background RGB color
  22.  
  23. $backgroundR = mt_rand(100,150);
  24. $backgroundG = mt_rand(100,150);
  25. $backgroundB = mt_rand(100,150);
  26.  
  27. // font color
  28.  
  29. $fontR = mt_rand(0,20);
  30. $fontG = mt_rand(0,20);
  31. $fontB = mt_rand(0,20);
  32.  
  33. // lines color
  34.  
  35. $linesR = mt_rand(200,255);
  36. $linesG = mt_rand(200,255);
  37. $linesB = mt_rand(200,255);
  38.  
  39. // create image
  40.  
  41. $image = imagecreatetruecolor($this -> width, $this -> height);
  42.  
  43. // colors
  44.  
  45. $backgroundColor = imagecolorallocate($image, $backgroundR, $backgroundG, $backgroundB);
  46. $fontColor = imagecolorallocate($image, $fontR, $fontG, $fontB);
  47. $linesColor = imagecolorallocate($image, $linesR, $linesG, $linesB);
  48. imagefill($image, 0, 0, $backgroundColor);
  49.  
  50. // draw lines on background
  51.  
  52. for ($i=0; $i<$this -> lines; $i++) {
  53. imageline($image, rand(0, $this -> width), 0, rand(0, $this -> width), $this -> height, $linesColor);
  54. imageline($image, 0, rand(0, $this -> height), $this -> width, rand(0, $this -> height), $linesColor);
  55. }
  56.  
  57. $font = '../font/Delicious-Roman.otf';
  58. $charTable = '0123456789abcdefghijklmnoprstuwyzABCDEFGHIJKLMNOPRSTUWYZ';
  59.  
  60. // code generation
  61.  
  62. $character = array();
  63. $angle = array();
  64.  
  65. for ($i=1; $i<=$this -> characters; $i++) {
  66. $character[] = $charTable[mt_rand(0, strlen($charTable)-1)];
  67. $angle[] = mt_rand(-20,20);
  68. }
  69.  
  70. $captchaCode = implode($character);
  71. $_SESSION['captchaCode'] = $captchaCode;
  72.  
  73. // count max font size
  74.  
  75. $fontSizeMax = floor($this -> height - $margin * 2);
  76.  
  77. do {
  78.  
  79. $fontSizeMax--;
  80. $captchaWidth = 0;
  81. $charHeight = array();
  82.  
  83. for ($i=0; $i<sizeof($character); $i++) {
  84.  
  85. $bbox = imageftbbox($fontSizeMax, $angle[$i], $font, $character[$i]);
  86. $captchaWidth += $charWidth = max(abs($bbox[0])+abs($bbox[2]), abs($bbox[4])+abs($bbox[6]))+$margin;
  87. $charHeight[] = max(abs($bbox[1])+abs($bbox[3]), abs($bbox[5])+abs($bbox[7]));
  88.  
  89. }
  90.  
  91. } while (max($charHeight) >= $this -> height OR $captchaWidth >= $this -> width - 2*$margin);
  92.  
  93. // draw text to image
  94.  
  95. $x = ($this -> width - $captchaWidth) / 2;
  96. $fontSpacing=$margin;
  97.  
  98. for ($i=0; $i<sizeof($character); $i++) {
  99.  
  100. $bbox = imageftbbox($fontSizeMax, $angle[$i], $font, $character[$i]);
  101. $charWidth = max(abs($bbox[0])+abs($bbox[2]), abs($bbox[4])+abs($bbox[6]))+$margin;
  102. imagettftext($image, $fontSizeMax, $angle[$i], $x+$fontSpacing, $this -> height/2+$margin, $fontColor, $font, $character[$i]);
  103. $fontSpacing += $charWidth;
  104.  
  105. }
  106.  
  107. Header('Content-type: image/png');
  108. imagepng($image);
  109.  
  110. }
  111.  
  112. }


Plik index wygląda tak:

  1.  
  2. echo '<img src="img/captcha.php"/>';
  3. echo $_SESSION['captchaCode'];


oraz plik obrazka:
  1.  
  2. function __autoload($class){
  3. require_once('../class/'.$class.'.class.php');
  4. }
  5.  
  6. $captcha = new captcha(150, 50, 6, 10);
  7. $captcha -> drawCaptcha();


No i po wyświetleniu pliku index.php generuje mi elegancko obrazek, natomiast $_SESSION['captchaCode'] na początku zwraca notice, że zmienna jest pusta, a po odświeżeniu jest nowo wygenerowany obrazek a $_SESSION zawiera kod poprzedniego, jak to przekazać, nie musi być w sesji, bym miał jednocześnie kod w postaci stringa i obrazek z tym samym kodem...

Ten post edytował b4rt3kk 17.07.2012, 00:50:19
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
irmidjusz
post
Post #2





Grupa: Zarejestrowani
Postów: 279
Pomógł: 60
Dołączył: 25.02.2012

Ostrzeżenie: (0%)
-----


No tak na prosto, to skoro klasa captcha generuje kod i zapisuje go w sesji, to trzeba ten kod wygenerować zanim spróbujesz z niego skorzystać w jakimkolwiek innym miejscu programu. Nie trzeba generować od razu obrazka, wystarczy wygenerować tylko nowy 'captchaCode' i zapisać go np. w sesji, a klasa przy tworzeniu obrazka mogła by pobrać ten kod (a utworzy nowy, jeśli go jeszcze nie ma). Tylko musisz się upewnić, że za każdym odświeżeniem strony generowany jest nowy kod i nowy obrazek.
Go to the top of the page
+Quote Post
d3ut3r
post
Post #3





Grupa: Zarejestrowani
Postów: 709
Pomógł: 176
Dołączył: 24.10.2010

Ostrzeżenie: (0%)
-----


Sama klasa captcha, nie powinna nic zapisywać w sesji jest to sprzeczne z paradygmatem obiektowości (IMG:style_emoticons/default/smile.gif) , powinna za to mieć metodę np. getCurrentCode, która zwraca ciąg jaki jest dostępny na obrazku, na zewnątrz klasy zapisujesz ten kod do sesji czy gdzie tam sobie chcesz.

Co do twojego problemu przyczyną jest sposób w jaki to robisz zobacz pierwsze wywołanie:

  1. echo '<img src="img/captcha.php"/>'; //dopiero gdy user to odbierze, przeglądarka wywoła żądanie obrazka i dopiero wtedy ustawi captchaCode
  2. echo $_SESSION['captchaCode']; // w pierwszym wywołaniu to nie istnieje


drugie

  1. echo '<img src="img/captcha.php"/>'; //dopiero gdy user to odbierze, przeglądarka wywoła żądanie obrazka i dopiero wtedy ustawi captchaCode
  2. echo $_SESSION['captchaCode']; // w drugim wywołaniu to ma wartość pierwszego wywołania (z tego samego powodu z którego w pierwszym wywołaniu jest puste


Jaśniej nie potrafię tego napisać (IMG:style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
b4rt3kk
post
Post #4





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Dzięki, mała modyfikacja klasy:

  1. function generateCode(){
  2.  
  3. $charTable = '0123456789abcdefghijklmnoprstuwyzABCDEFGHIJKLMNOPRSTUWYZ';
  4.  
  5. $character = array();
  6. $angle = array();
  7.  
  8. for ($i=1; $i<=$this -> characters; $i++) {
  9. $character[] = $charTable[mt_rand(0, strlen($charTable)-1)];
  10. $angle[] = mt_rand(-20,20);
  11. }
  12.  
  13. $code = array($character, $angle);
  14.  
  15. return $code;
  16.  
  17. }
  18.  
  19. function drawCaptcha($character, $angle){


indexu:

  1. $width = 150;
  2. $height = 50;
  3. $characters = 6;
  4. $lines = 10;
  5.  
  6. $captcha = new captcha($width, $height, $characters, $lines);
  7.  
  8. $_SESSION['code'] = $captcha -> generateCode();
  9. $_SESSION['captchaCode'] = implode($_SESSION['code'][0]);
  10.  
  11. echo '<img src="img/captcha.php?w='.$width.'&h='.$height.'&c='.$characters.'&l='.$lines.'"/>';
  12. echo $_SESSION['captchaCode'];


i samego obrazka:

  1. $width = $_GET['w'];
  2. $height = $_GET['h'];
  3. $characters = $_GET['c'];
  4. $lines = $_GET['l'];
  5.  
  6. $captcha = new captcha($width, $height, $characters, $lines);
  7. $captcha -> drawCaptcha($_SESSION['code'][0], $_SESSION['code'][1]);


pomogły. (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 15:45