You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP集成TCPDF生成PDF时hexdec()无效字符传入报错的解决咨询

TCPDF生成PDF时hexdec()弃用警告的解决方法

问题背景

在PHP项目中集成TCPDF生成PDF时,触发了如下弃用警告:

Deprecated: Invalid characters passed for attempted conversion, these have been ignored in C:\wamp64\www\projects\include\tcpdf_colors.php on line 388

问题出在TCPDF处理十六进制颜色的代码段(tcpdf_colors.php第370-390行):

// HEXADECIMAL REPRESENTATION
switch (strlen($color_code)) {
    case 3: {
        // 3-digit RGB hexadecimal representation
        $r = substr($color_code, 0, 1);
        $g = substr($color_code, 1, 1);
        $b = substr($color_code, 2, 1);
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, hexdec($r.$r)));
        $returncolor['G'] = max(0, min(255, hexdec($g.$g)));
        $returncolor['B'] = max(0, min(255, hexdec($b.$b)));
        break;
    }
    case 6: {
        // 6-digit RGB hexadecimal representation
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2))));
        $returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2))));
        $returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2))));
        break;
    }

排查发现传入的$color_code是带无效字符的超长十六进制数(比如末尾带“l”),临时用$color_code = substr($color_code, 0, -1);能生成PDF,但这个方案不可靠——无效字符的位置不固定,可能出现在颜色码的任意位置。

原因分析

高版本PHP对hexdec()、base_convert()等函数做了严格校验:传入无效字符时会触发弃用警告,尽管仍会忽略无效字符计算结果,但不符合新的规范。TCPDF原有代码没有对输入的颜色码做严格校验,导致非法字符流入hexdec()触发警告。

可靠解决方案

方案1:提前过滤非法字符

在处理颜色码前,先清理掉所有非十六进制字符,再按原有逻辑处理:

// 保留颜色码中的合法十六进制字符(0-9, a-f, A-F)
$color_code = preg_replace('/[^0-9a-fA-F]/', '', $color_code);

// HEXADECIMAL REPRESENTATION
switch (strlen($color_code)) {
    case 3: {
        // 原代码不变
        $r = substr($color_code, 0, 1);
        $g = substr($color_code, 1, 1);
        $b = substr($color_code, 2, 1);
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, hexdec($r.$r)));
        $returncolor['G'] = max(0, min(255, hexdec($g.$g)));
        $returncolor['B'] = max(0, min(255, hexdec($b.$b)));
        break;
    }
    case 6: {
        // 原代码不变
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2))));
        $returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2))));
        $returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2))));
        break;
    }
    // 可选:处理清理后长度不足的情况,返回默认颜色
    default:
        return array('R' => 0, 'G' => 0, 'B' => 0);
}

方案2:严格校验颜色格式

先校验颜色码是否为合法的3位或6位十六进制值,非法则返回默认颜色:

// 校验颜色格式:仅允许3位或6位十六进制字符
if (!preg_match('/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/', $color_code)) {
    // 返回默认颜色(示例为黑色)
    return array('R' => 0, 'G' => 0, 'B' => 0);
}

// 处理3位转6位的情况
if (strlen($color_code) == 3) {
    $color_code = $color_code[0].$color_code[0].$color_code[1].$color_code[1].$color_code[2].$color_code[2];
}

// 直接处理6位颜色
$returncolor = array();
$returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2))));
$returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2))));
$returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2))));

方案3:封装安全的十六进制转十进制函数

自定义函数过滤非法字符后再调用hexdec(),替换原有代码中的hexdec:

// 安全的十六进制转十进制函数
function safe_hexdec($hex_str) {
    // 过滤非法字符
    $clean_hex = preg_replace('/[^0-9a-fA-F]/', '', $hex_str);
    // 处理空值情况
    return $clean_hex ? hexdec($clean_hex) : 0;
}

// 修改原有代码中的hexdec调用
switch (strlen($color_code)) {
    case 3: {
        $r = substr($color_code, 0, 1);
        $g = substr($color_code, 1, 1);
        $b = substr($color_code, 2, 1);
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, safe_hexdec($r.$r)));
        $returncolor['G'] = max(0, min(255, safe_hexdec($g.$g)));
        $returncolor['B'] = max(0, min(255, safe_hexdec($b.$b)));
        break;
    }
    case 6: {
        $returncolor = array();
        $returncolor['R'] = max(0, min(255, safe_hexdec(substr($color_code, 0, 2))));
        $returncolor['G'] = max(0, min(255, safe_hexdec(substr($color_code, 2, 2))));
        $returncolor['B'] = max(0, min(255, safe_hexdec(substr($color_code, 4, 2))));
        break;
    }
}

为什么临时截断不可靠

无效字符可能出现在颜色码的开头、中间或末尾,直接截断会导致颜色值偏离预期;若清理后颜色码长度不符合3/6位,后续switch逻辑无法匹配,还可能引发其他异常。

内容的提问来源于stack exchange,提问作者Rinku27

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:35:20