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
  • 在C#中使用SQL Server實現事務的ACID(原子性、一致性、隔離性、持久性)屬性和使用資料庫鎖(悲觀鎖和樂觀鎖)時,你可以通過ADO.NET的SqlConnection和SqlTransaction類來實現。下麵是一些示例和概念說明。 實現ACID事務 ACID屬性是事務處理的四個基本特征, ...
  • 我們在《SqlSugar開發框架》中,Winform界面開發部分往往也用到了自定義的用戶控制項,對應一些特殊的界面或者常用到的一些局部界面內容,我們可以使用自定義的用戶控制項來提高界面的統一性,同時也增強了使用的便利性。如我們Winform界面中用到的分頁控制項、附件顯示內容、以及一些公司、部門、菜單的下... ...
  • 在本篇教程中,我們學習瞭如何在 Taurus.MVC WebMVC 中進行數據綁定操作。我們還學習瞭如何使用 ${屬性名稱} CMS 語法來綁定頁面上的元素與 Model 中的屬性。通過這些步驟,我們成功實現了一個簡單的數據綁定示例。 ...
  • 是在MVVM中用來傳遞消息的一種方式。它是在MVVMLight框架中提供的一個實現了IMessenger介面的類,可以用來在ViewModel之間、ViewModel和View之間傳遞消息。 Send 接受一個泛型參數,表示要發送的消息內容。 Register 方法用於註冊某個對象接收消息。 pub ...
  • 概述:在WPF中,通過EventHandler可實現基礎和高級的UI更新方式。基礎用法涉及在類中定義事件,併在UI中訂閱以執行更新操作。高級用法藉助Dispatcher類,確保在非UI線程上執行操作後,通過UI線程更新界面。這兩種方法提供了靈活而可靠的UI更新機制。 在WPF(Windows Pre ...
  • 概述:本文介紹了在C#程式開發中如何利用自定義擴展方法測量代碼執行時間。通過使用簡單的Action委托,開發者可以輕鬆獲取代碼塊的執行時間,幫助優化性能、驗證演算法效率以及監控系統性能。這種通用方法提供了一種便捷而有效的方式,有助於提高開發效率和代碼質量。 在軟體開發中,瞭解代碼執行時間是優化程式性能 ...
  • 概述:Cron表達式是一種強大的定時任務調度工具,通過配置不同欄位實現靈活的時間規定。在.NET中,Quartz庫提供了簡便的方式配置Cron表達式,實現精準的定時任務調度。這種靈活性和可擴展性使得開發者能夠根據需求輕鬆地制定和管理定時任務,例如每天備份系統日誌或其他重要操作。 Cron表達式詳解 ...
  • 概述:.NET提供多種定時器,如System.Windows.Forms.Timer適用於UI,System.Web.UI.Timer用於Web,System.Diagnostics.Timer用於性能監控,System.Threading.Timer和System.Timers.Timer用於一般 ...
  • 問題背景 有同事聯繫我說,在生產環境上,訪問不了我負責的common服務,然後我去檢查common服務的health endpoint, 沒問題,然後我問了下異常,timeout導致的System.OperationCanceledException。那大概率是客戶端的問題,會不會是埠耗盡,用ne ...
  • 前言: 在本篇 Taurus.MVC WebMVC 入門開發教程的第四篇文章中, 我們將學習如何實現數據列表的綁定,通過使用 List<Model> 來展示多個數據項。 我們將繼續使用 Taurus.Mvc 命名空間,同時探討如何在視圖中綁定並顯示一個 Model 列表。 步驟1:創建 Model ...