Z6098 2021-11-19 22:26 采纳率: 100%
浏览 33
已结题

php表单验证码怎麽写(下面是表单)

问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
<title>用户登录</title> <fieldset style="width:700px;"><legend style="font-size:16px; font-weight:bolder">用户登录</legend>
用户名:<input id="user" name="user" type="text" />
密码:<input id="pwd" name="pwd" type="password" />
验证码:<input id="code" name="code" type="text" /> ?> </td>
<input value="登录" name="sub" type="submit" />
</fieldset>
运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果

img

  • 写回答

1条回答 默认 最新

  • PHP全栈狼 2021-11-19 23:22
    关注

    思路:
    前端
    1.登录页面打开后,ajax异步获取一个验证码图片的base64,且登录失败或点击验证码图片时,重新获取
    以html+jquery为例的代码

    <div id="captcha"  alt="验证码"></div>
    <script>
    $(function () {
        $('#captcha').click(function () {
           $.post("/admin/login/captcha",{},function(result){
                $(this).html('<img src="result">');  //将base64图片验证码加载到当前div下
            });
        });
    //初始化获取验证码
      $('#captcha').map(function () {
            $(this).trigger('click');  //触发获取验证码,自己写的登录js代码中,如果登录失败也可以$('#captcha').trigger('click')重新生成验证码
        });
    })
    <script>
    

    后端
    1.生成并返回验证码

        //以TP为例生成控制器
        use think\admin\service\CaptchaService;
        public function captcha()
        {
           //初始化验证码
            $image = CaptchaService::instance()->initialize();    
            $data =$image->getData(); //获取验证码图片
            $code = $image->getCode(); //获取验证码字符
            Session::set('captcha',$code );  //保存到session中,也可以保存在redis里,方便登陆方法中获取到
             return  $data ;        输出验证码图片
        }
    

    验证码类参考以下

    <?php
    
    declare (strict_types=1);
    
    namespace think\admin\service;
    
    use think\admin\Service;
    
    /**
     * 图形验证码服务
     * Class CaptchaService
     * @package think\admin\service
     */
    class CaptchaService extends Service
    {
        private $code; // 验证码
        private $uniqid; // 唯一序号
        private $charset = 'ABCDEFGHKMNPRSTUVWXYZ23456789'; // 随机因子
        private $width = 130; // 图片宽度
        private $height = 50; // 图片高度
        private $length = 4; // 验证码长度
        private $fontfile; // 指定字体文件
        private $fontsize = 20; // 指定字体大小
    
        /**
         * 验证码服务初始化
         * @param array $config
         * @return static
         */
        public function initialize(array $config = []): CaptchaService
        {
            // 动态配置属性
            foreach ($config as $k => $v) if (isset($this->$k)) $this->$k = $v;
            // 生成验证码序号
            $this->uniqid = uniqid('captcha') . mt_rand(1000, 9999);
            // 生成验证码字符串
            [$this->code, $length] = ['', strlen($this->charset) - 1];
            for ($i = 0; $i < $this->length; $i++) {
                $this->code .= $this->charset[mt_rand(0, $length)];
            }
            // 设置字体文件路径
            $this->fontfile = __DIR__ . '/bin/captcha.ttf';
            // 缓存验证码字符串
            $this->app->cache->set($this->uniqid, $this->code, 360);
            // 返回当前对象
            return $this;
        }
    
        /**
         * 动态切换配置
         * @param array $config
         * @return $this
         */
        public function config(array $config = []): CaptchaService
        {
            return $this->initialize($config);
        }
    
        /**
         * 获取验证码值
         * @return string
         */
        public function getCode(): string
        {
            return $this->code;
        }
    
        /**
         * 获取图片的内容
         * @return string
         */
        public function getData(): string
        {
            return "data:image/png;base64,{$this->createImage()}";
        }
    
        /**
         * 获取验证码编号
         * @return string
         */
        public function getUniqid(): string
        {
            return $this->uniqid;
        }
    
        /**
         * 获取验证码数据
         * @return array
         */
        public function getAttrs(): array
        {
            return [
                'code'   => $this->getCode(),
                'data'   => $this->getData(),
                'uniqid' => $this->getUniqid(),
            ];
        }
    
        /**
         * 检查验证码是否正确
         * @param string $code 需要验证的值
         * @param null|string $uniqid 验证码编号
         * @return boolean
         */
        public function check(string $code, ?string $uniqid = null): bool
        {
            $_uni = is_string($uniqid) ? $uniqid : input('uniqid', '-');
            $_val = $this->app->cache->get($_uni, '');
            if (is_string($_val) && strtolower($_val) === strtolower($code)) {
                $this->app->cache->delete($_uni);
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * 输出图形验证码
         * @return string
         */
        public function __toString()
        {
            return $this->getData();
        }
    
        /**
         * 创建验证码图片
         * @return string
         */
        private function createImage(): string
        {
            // 生成背景
            $img = imagecreatetruecolor($this->width, $this->height);
            $color = imagecolorallocate($img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
            imagefilledrectangle($img, 0, $this->height, $this->width, 0, $color);
            // 生成线条
            for ($i = 0; $i < 6; $i++) {
                $color = imagecolorallocate($img, mt_rand(0, 50), mt_rand(0, 50), mt_rand(0, 50));
                imageline($img, 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($img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
                imagestring($img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
            }
            // 生成文字
            $_x = $this->width / $this->length;
            for ($i = 0; $i < $this->length; $i++) {
                $fontcolor = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
                if (function_exists('imagettftext')) {
                    imagettftext($img, $this->fontsize, mt_rand(-30, 30), intval($_x * $i + mt_rand(1, 5)), intval($this->height / 1.4), $fontcolor, $this->fontfile, $this->code[$i]);
                } else {
                    imagestring($img, 15, intval($_x * $i + mt_rand(10, 15)), mt_rand(10, 30), $this->code[$i], $fontcolor);
                }
            }
            ob_start();
            imagepng($img);
            $data = ob_get_contents();
            ob_end_clean();
            imagedestroy($img);
            return base64_encode($data);
        }
    }
    

    这样登录方法里,可以取session中的captcha进行对比

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月4日
  • 已采纳回答 11月26日
  • 创建了问题 11月19日

悬赏问题

  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本