ThinkPHP V6.0.12在php8.1下驗證碼出現問題

来源:https://www.cnblogs.com/zhangxilong/archive/2022/05/11/16257933.html
-Advertisement-
Play Games

一、問題描述 1、項目需求要求使用PHP8.1.*版本 2、運行程式發現驗證碼不生效報錯如下: 二、錯誤描述 1、報錯信息得出:從浮點(數字)到整數的隱式轉換將失去精度 三、解決流程 1、找到報錯文件位置 vendor\topthink\think-captcha\src\Captcha.php l ...


一、問題描述

1、項目需求要求使用PHP8.1.*版本

2、運行程式發現驗證碼不生效報錯如下:

二、錯誤描述

1、報錯信息得出:從浮點(數字)到整數的隱式轉換將失去精度

三、解決流程

1、找到報錯文件位置

vendor\topthink\think-captcha\src\Captcha.php line 309

2、發現是第309行報錯,將代碼改成以下內容(也可直接替換)

    /**
     * 畫雜點
     * 往圖片上寫不同顏色的字母或數字
     */
    protected function writeNoise(): void
    {
        $codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
        for ($i = 0; $i < 10; $i++) {
            //雜點顏色
            $noiseColor = imagecolorallocate($this->im, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225));
            for ($j = 0; $j < 5; $j++) {
                // 繪雜點
                imagestring($this->im, 5, mt_rand(-10, (int) $this->imageW), mt_rand(-10, (int)$this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor);
            }
        }
    }

3、此時刷新頁面發現了新的報錯信息(意思基本相同):

4、搜索(writeCurve)方法直接替換:

/**
     * 畫一條由兩條連在一起構成的隨機正弦函數曲線作干擾線(你可以改成更帥的曲線函數)
     *
     *      高中的數學公式咋都忘了涅,寫出來
     *        正弦型函數解析式:y=Asin(ωx+φ)+b
     *      各常數值對函數圖像的影響:
     *        A:決定峰值(即縱向拉伸壓縮的倍數)
     *        b:表示波形在Y軸的位置關係或縱向移動距離(上加下減)
     *        φ:決定波形與X軸位置關係或橫向移動距離(左加右減)
     *        ω:決定周期(最小正周期T=2π/∣ω∣)
     *
     */
    protected function writeCurve(): void
    {
        $px = $py = 0;

        // 曲線前部分
        $A = mt_rand(1, (int) $this->imageH / 2); // 振幅
        $b = mt_rand(-intval($this->imageH / 4), intval($this->imageH / 4)); // Y軸方向偏移量
        $f = mt_rand(-intval($this->imageH / 4), intval($this->imageH / 4)); // X軸方向偏移量
        $T = mt_rand((int) $this->imageH, intval($this->imageW * 2)); // 周期
        $w = (2 * M_PI) / $T;

        $px1 = 0; // 曲線橫坐標起始位置
        $px2 = mt_rand($this->imageW / 2, $this->imageW * 0.8); // 曲線橫坐標結束位置

        for ($px = $px1; $px <= $px2; $px = $px + 1) {
            if (0 != $w) {
                $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
                $i  = (int) ($this->fontSize / 5);
                while ($i > 0) {
                    imagesetpixel($this->im, (int) $px + $i, (int) $py + $i, $this->color); // 這裡(while)迴圈畫像素點比imagettftext和imagestring用字體大小一次畫出(不用這while迴圈)性能要好很多
                    $i--;
                }
            }
        }

        // 曲線後部分
        $A   = mt_rand(1, intval($this->imageH / 2)); // 振幅
        $f   = mt_rand(-intval($this->imageH / 4), intval($this->imageH / 4)); // X軸方向偏移量
        $T   = mt_rand((int) $this->imageH, intval($this->imageW * 2)); // 周期
        $w   = (2 * M_PI) / $T;
        $b   = $py - $A * sin($w * $px + $f) - $this->imageH / 2;
        $px1 = $px2;
        $px2 = $this->imageW;

        for ($px = $px1; $px <= $px2; $px = $px + 1) {
            if (0 != $w) {
                $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
                $i  = (int) ($this->fontSize / 5);
                while ($i > 0) {
                    imagesetpixel($this->im, (int) $px + $i, (int) $py + $i, $this->color);
                    $i--;
                }
            }
        }
    }

5、最後一步,搜索(create)方法直接替換:

 /**
     * 輸出驗證碼並把驗證碼的值保存的session中
     * @access public
     * @param null|string $config
     * @param bool        $api
     * @return Response
     */
    public function create(string $config = null, bool $api = false): Response
    {
        $this->configure($config);

        $generator = $this->generate();

        // 圖片寬(px)
        $this->imageW || $this->imageW = $this->length * $this->fontSize * 1.5 + $this->length * $this->fontSize / 2;
        // 圖片高(px)
        $this->imageH || $this->imageH = $this->fontSize * 2.5;
        // 建立一幅 $this->imageW x $this->imageH 的圖像
        $this->im = imagecreate((int) $this->imageW, (int) $this->imageH);
        // 設置背景
        imagecolorallocate($this->im, $this->bg[0], $this->bg[1], $this->bg[2]);

        // 驗證碼字體隨機顏色
        $this->color = imagecolorallocate($this->im, mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150));

        // 驗證碼使用隨機字體
        $ttfPath = __DIR__ . '/../assets/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/';

        if (empty($this->fontttf)) {
            $dir  = dir($ttfPath);
            $ttfs = [];
            while (false !== ($file = $dir->read())) {
                if ('.' != $file[0] && substr($file, -4) == '.ttf') {
                    $ttfs[] = $file;
                }
            }
            $dir->close();
            $this->fontttf = $ttfs[array_rand($ttfs)];
        }

        $fontttf = $ttfPath . $this->fontttf;

        if ($this->useImgBg) {
            $this->background();
        }

        if ($this->useNoise) {
            // 繪雜點
            $this->writeNoise();
        }
        if ($this->useCurve) {
            // 繪干擾線
            $this->writeCurve();
        }

        // 繪驗證碼
        $text = $this->useZh ? preg_split('/(?<!^)(?!$)/u', $generator['value']) : str_split($generator['value']); // 驗證碼

        foreach ($text as $index => $char) {

            $x     = $this->fontSize * ($index + 1) * mt_rand((int) 1.2, (int) 1.6) * ($this->math ? 1 : 1.5);
            $y     = $this->fontSize + mt_rand(10, 20);
            $angle = $this->math ? 0 : mt_rand(-40, 40);

            imagettftext($this->im, $this->fontSize, $angle, (int) $x, (int) $y, $this->color, $fontttf, $char);
        }

        ob_start();
        // 輸出圖像
        imagepng($this->im);
        $content = ob_get_clean();
        imagedestroy($this->im);

        return response($content, 200, ['Content-Length' => strlen($content)])->contentType('image/png');
    }

 

說明:以上是按照報錯信息依次修改;如有大佬有更好的解決辦法歡迎評論留言


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 跟著教程寫了幾種方法,才發現自己寫的雖然能實現,但比較繁瑣。教程有三種方法: 1.移位法,每次左移一位,相比我自己寫的,優點是不用把每一種情況都寫出來。但是需要考慮左移到最後一位時需要自己再寫個賦值語句重新回到第一位。 2.位拼接法,迴圈左移,每一次都把最後一位放到第一位,其他六位左移一位,剋服了移 ...
  • JUC自定義線程池練習 首先上面該線程池的大致流程 自定義阻塞隊列 首先定義一個雙向的隊列和鎖一定兩個等待的condition 本類用lock來控制多線程下的流程執行 take和push方法就是死等,調用await就是等,後面優化為限時等待 take調用後取出阻塞隊列的task後會調用fullWai ...
  • Google支付Java服務端訂單校驗 原文鏈接:https://blog.csdn.net/qq_40193787/article/details/123507578 一、Google Play 結算系統概覽 Google Play 結算系統是一項可讓您在 Android 應用中銷售數字產品和內容 ...
  • 前言 現如今,視頻!每個人飯後或睡前都會刷一刷,查看每日新奇或小姐姐帥哥、明星視頻~ 而我們今天採集得是一個開眼界、漲知識的視頻 App, 作為國內領先的中視頻平臺,它源源不斷地為不同人群提供優質內容, 讓人們看到更豐富和有深度的世界,收穫輕鬆的獲得感,點亮對生活的好奇心。 準備工作 第三方模塊: ...
  • 📕併發基本概念以及實現、進程、線程基本概念 一、併發、進程、線程的基本概念和綜述 這些詳細概念具體去看os筆記; 1.1 併發 兩個或者更多的任務(獨立的活動)同時發生(進行):一個程式同時執行多個獨立的任務; 以往電腦,單核cpu(中央處理器):某一個時刻只能執行一個任務,由操作系統調度,每秒 ...
  • 來源:toutiao.com/i6698255904053133827 這是一位讀者帶回來的面試題 Nginx 是如何實現併發的?為什麼 Nginx 不使用多線程?Nginx常見的優化手段有哪些?502錯誤可能原因有哪些? 面試官心理分析 主要是看應聘人員的對NGINX的基本原理是否熟悉,因為大多數 ...
  • @ 一、前言 我們先來聊聊消息中間件: 消息中間件利用高效可靠的消息傳遞機制進行平臺無關的數據交流,並基於數據通信來進行分散式系統的集成。通過提供消息傳遞和消息排隊模型,它可以在分散式環境下擴展進程間的通信。(來自百度百科) 我們常見的中間件其實有很多種了,例如ActiveMQ、RabbitMQ、R ...
  • 介紹 powerjob提供了容器功能,用來做一些靈活的任務處理。這裡容器為 JVM 級容器,而不是操作系統級容器(Docker)。(至於為什麼取“容器”這個有歧義的名字是因為作者沒想出來更合適的稱呼,哈哈) 用途 有一些任務完全獨立於業務,代碼量也不大,既不希望耦合於原業務代碼,也不值得再搞一套新建 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...