PageRenderTime 55ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Framework/Component/Captcha.php

http://lxsphp.googlecode.com/
PHP | 195 lines | 109 code | 23 blank | 63 comment | 12 complexity | bf183bdbd0d6c829bdc83d6303ac12b9 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * ????
  4. *
  5. * [Code]
  6. * $c = App::C('Captcha');
  7. * $c->display(1, array('bordercolor'=>'#C5C5C5', 'width'=>148, 'height'=>26));
  8. * [/Code]
  9. *
  10. * @version $Id: Captcha.php 312 2012-03-06 09:00:15Z linsir123 $
  11. * @package Component
  12. */
  13. class comCaptcha
  14. {
  15. /**
  16. * @var ??,??????????
  17. */
  18. public $options = array('bordercolor'=>null, 'width'=>70, 'height'=>21);
  19. /**
  20. * @var ???
  21. */
  22. public $code;
  23. /**
  24. * @var ????
  25. */
  26. public $expired;
  27. /**
  28. * @var ????
  29. */
  30. private $_im;
  31. /**
  32. * @var ????
  33. */
  34. private $_width;
  35. /**
  36. * @var ????
  37. */
  38. private $_height;
  39. /**
  40. * ????
  41. */
  42. public function __construct()
  43. {
  44. @session_start();
  45. $this->code = isset($_SESSION['CaptchaCode']) ? $_SESSION['CaptchaCode'] : '';
  46. $this->expired = isset($_SESSION['CaptchaExpired']) ? $_SESSION['CaptchaExpired'] : 0;
  47. }
  48. /**
  49. * ????
  50. *
  51. * @param int $type ???????
  52. * @param array $options ????
  53. */
  54. public function display($type = 0, $options = array())
  55. {
  56. $this->_code($type);
  57. ///
  58. if (is_array($options))
  59. $this->options = array_merge($this->options, $options);
  60. $this->_width = intval($this->options['width']);
  61. $this->_height = intval($this->options['height']);
  62. $this->_background();
  63. $this->_ttfont();
  64. ///
  65. header('Content-type:image/png');
  66. imagepng($this->_im);
  67. imagedestroy($this->_im);
  68. }
  69. /**
  70. * ???????????
  71. *
  72. * @param string $code ????????
  73. * @return bool
  74. */
  75. public function check($code)
  76. {
  77. return (time() < $this->expired && strtoupper($code) == strtoupper($this->code));
  78. }
  79. /// ??????? ///
  80. /**
  81. * ????
  82. */
  83. private function _background()
  84. {
  85. $this->_im = imagecreate($this->_width, $this->_height);
  86. ///
  87. for($i = 0; $i < 3; $i++) {
  88. $start[$i] = mt_rand(200, 255);
  89. $end[$i] = mt_rand(100, 150);
  90. $step[$i] = ($end[$i] - $start[$i]) / $this->_width;
  91. $c[$i] = $start[$i];
  92. }
  93. for($i = 0; $i < $this->_width; $i++) {
  94. $color = imagecolorallocate($this->_im, $c[0], $c[1], $c[2]);
  95. imageline($this->_im, $i, 0, $i, $this->_height, $color);
  96. $c[0] += $step[0];$c[1] += $step[1];$c[2] += $step[2];
  97. }
  98. ///
  99. $linenums = $this->_height / 10;
  100. for($i=0; $i <= $linenums; $i++) {
  101. $color = imagecolorallocate($this->_im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
  102. $x = mt_rand(0, $this->_width);
  103. $y = mt_rand(0, $this->_height);
  104. if (mt_rand(0, 1))
  105. imagearc($this->_im, $x, $y, mt_rand(0, $this->_width), mt_rand(0, $this->_height), mt_rand(0, 360), mt_rand(0, 360), $color);
  106. else
  107. imageline($this->_im, $x, $y, $linex + mt_rand(0, $linemaxlong), $liney + mt_rand(0, mt_rand($this->_height, $this->_width)), $color);
  108. }
  109. ///
  110. if ($this->options['bordercolor']) {
  111. list($r, $g, $b) = lpString::hex2rgb($this->options['bordercolor']);
  112. $color = imagecolorallocate($this->_im, $r, $g, $b);
  113. imagerectangle($this->_im, 0, 0, $this->_width - 1, $this->_height - 1, $color);
  114. }
  115. }
  116. /**
  117. * ????
  118. */
  119. private function _ttfont()
  120. {
  121. $widthtotal = 0;
  122. $seccode = $this->code;
  123. $seccodelength = strlen($seccode);
  124. for ($i = 0; $i < $seccodelength; $i++) {
  125. $font[$i]['font'] = dirname(__FILE__).DS.'fonts/verdanab.ttf';
  126. $font[$i]['size'] = 12;
  127. $box = imagettfbbox($font[$i]['size'], 0, $font[$i]['font'], $seccode[$i]);
  128. $font[$i]['height'] = max($box[1], $box[3]) - min($box[5], $box[7]);
  129. $font[$i]['width'] = (max($box[2], $box[4]) - min($box[0], $box[6])) + mt_rand(0, $this->_width / 8);
  130. $font[$i]['width'] = $font[$i]['width'] > $this->_width / $seccodelength ? $this->_width / $seccodelength : $font[$i]['width'];
  131. $widthtotal += $font[$i]['width'];
  132. }
  133. ///
  134. $x = mt_rand(1, $this->_width - $widthtotal);
  135. for ($i = 0; $i < $seccodelength; $i++) {
  136. $fontcolor = array(mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
  137. $text_shadowcolor = imagecolorallocate($this->_im, 255 - $fontcolor[0], 255 - $fontcolor[1], 255 - $fontcolor[2]);
  138. $text_color = imagecolorallocate($this->_im, $fontcolor[0], $fontcolor[1], $fontcolor[2]);
  139. $y = mt_rand($font[$i]['height'] + 2, $this->_height - 5);
  140. imagettftext($this->_im, $font[$i]['size'], 0, $x + 1, $y + 1, $text_shadowcolor, $font[$i]['font'], $seccode[$i]);
  141. imagettftext($this->_im, $font[$i]['size'], 0, $x, $y, $text_color, $font[$i]['font'], $seccode[$i]);
  142. $x += $font[$i]['width'];
  143. }
  144. }
  145. /**
  146. * ?????
  147. *
  148. * @param int $type ???????
  149. */
  150. private function _code($type)
  151. {
  152. switch ($type) {
  153. case 1:
  154. $seed = '0123456789';
  155. break;
  156. case 2:
  157. $seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  158. break;
  159. default:
  160. $seed = '012346789ABCDEFGHJKLMNPQRTUVWXYZabcdefghijklmnopqrstuvwxyz';
  161. break;
  162. }
  163. ///
  164. $this->code = '';
  165. list($usec, $sec) = explode(' ', microtime());
  166. srand($sec + $usec * 100000);
  167. for ($i = 0; $i < 4; $i++)
  168. $this->code .= substr($seed, rand(0, strlen($seed) - 1), 1);
  169. $_SESSION['CaptchaCode'] = $this->code;
  170. $_SESSION['CaptchaExpired'] = $this->expired = time() + 900;
  171. }
  172. }