ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
主要解决方法: 1)继承Yii2的yii\captcha\CaptchaAction,重写run方法进行验证码的生成、显示等操作。 2)改变getVerifyCode的参数false改为true,让每次刷新和请求都更新验证码 3)让验证码更美观,用新的字体,加上线条,背景等 有其他特殊需求可以在这些代码中自己添加即可。 控制器代码SiteController.php: public function actions() { return [ 'captcha' => [ 'class' => 'common\components\MyCaptcha', //'class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 'maxLength' => 4, //生成的验证码最大长度 'minLength' => 4, //生成的验证码最短长度 'width'=>130, 'height'=>50, ], ]; } 验证码common/components/MyCaptcha.php: <?php namespace common\components; use Yii; use yii\captcha\CaptchaAction; use yii\helpers\Url; use yii\web\Response; class MyCaptcha extends CaptchaAction { public function init() { parent::init(); $this->fontFile = dirname(Yii::$app->basePath) . '/source/font/elephant.ttf'; } /** * Runs the action. */ public function run() { if (Yii::$app->request->getQueryParam(self::REFRESH_GET_VAR) !== null) { // AJAX request for regenerating code $code = $this->getVerifyCode(true); Yii::$app->response->format = Response::FORMAT_JSON; return [ 'hash1' => $this->generateValidationHash($code), 'hash2' => $this->generateValidationHash(strtolower($code)), // we add a random 'v' parameter so that FireFox can refresh the image // when src attribute of image tag is changed 'url' => Url::to([$this->id, 'v' => uniqid()]), ]; } else { $this->setHttpHeaders(); Yii::$app->response->format = Response::FORMAT_RAW; return $this->renderImage($this->getVerifyCode(true)); } } /** * Renders the CAPTCHA image based on the code using GD library. * @param string $code the verification code * @return string image contents in PNG format. */ protected function renderImageByGD($code) { $image = imagecreatetruecolor($this->width, $this->height); $backColor = imagecolorallocate($image, mt_rand(157,255), mt_rand(157,255), mt_rand(157,255)); imagefilledrectangle($image, 0, 0, $this->width - 1, $this->height - 1, $backColor); imagecolordeallocate($image, $backColor); if ($this->transparent) { imagecolortransparent($image, $backColor); } $foreColor = imagecolorallocate($image,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156)); //雪花线条 for ($i=0;$i<6;$i++) { $color = imagecolorallocate($image,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156)); imageline($image,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color); } for ($i=0;$i<100;$i++) { $color = imagecolorallocate($image,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); imagestring($image,mt_rand(1,5),mt_rand(0,$this->width),mt_rand(0,$this->height),'*',$color); } $length = strlen($code); $box = imagettfbbox(30, 0, $this->fontFile, $code); $w = $box[4] - $box[0] + $this->offset * ($length - 1); $h = $box[1] - $box[5]; $scale = min(($this->width - $this->padding * 2) / $w, ($this->height - $this->padding * 2) / $h); $x = 10; $y = round($this->height * 27 / 40); for ($i = 0; $i < $length; ++$i) { $fontSize = (int) (rand(26, 32) * $scale * 0.8); $angle = rand(-10, 10); $letter = $code[$i]; $box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter); $x = $box[2] + $this->offset; } imagecolordeallocate($image, $foreColor); ob_start(); imagepng($image); imagedestroy($image); return ob_get_clean(); } } 视图中的代码: <ul> <li><i class="icon-user"></i><input type="text" id="user" placeholder="请输入账号" maxlength="20" autocomplete="false"><span></span></li> <li><i class="icon-pwd"></i><input type="password" id="pwd" placeholder="请输入密码" maxlength="20" autocomplete="false"><span></span></li> <li><i class="icon-ver"></i><input type="text" id="ver" placeholder="请输入验证码" maxlength="4" autocomplete="false"><span></span> <?php echo Captcha::widget(['name'=>'captchaimg','captchaAction'=>'site/captcha','imageOptions'=>['class'=>'captchaimg', 'title'=>'换一个', 'alt'=>'换一个'],'template'=>'{image}']);?></li> <li><button id="login">登录</button></li> </ul> <script type="text/javascript"> $(".captchaimg").click(function(){ var date = new Date(); $(this).attr('src',['site/captcha','data=',(new Date())].join('?')); }) <script>