Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]captcha
Forum PHP.pl > Forum > Przedszkole
b4rt3kk
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...
irmidjusz
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.
d3ut3r
Sama klasa captcha, nie powinna nic zapisywać w sesji jest to sprzeczne z paradygmatem obiektowości 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ć biggrin.gif
b4rt3kk
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. smile.gif
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-2025 Invision Power Services, Inc.