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

为PDF报表生成不同长度表格的PHP代码优化咨询

报表功能PHP代码优化方案

当前报表代码可正常运行,以下从数据处理逻辑、Helper函数、调用逻辑三个维度优化,提升可维护性与复用性:


一、数据处理逻辑优化

核心问题:重复正则处理、冗余循环、硬编码阈值

原代码中多次调用preg_replace处理code_value,且用原生循环拆分数据,可通过Laravel集合方法简化,同时提取阈值常量避免硬编码。

优化后代码:

// 提取阈值常量,便于统一修改
define('REPORT_THRESHOLDS', [
    'none_reactive' => 0.35,
    'low_upper' => 3.49,
    'medium_lower' => 3.5,
    'medium_upper' => 49.99,
    'high_lower' => 50.0,
]);

// 封装数据处理逻辑到Service类(推荐)
class ReportDataProcessor
{
    public static function process($rawData, $foodSense)
    {
        $processedData = collect($rawData)
            ->sortBy('cate_id')
            ->map(function ($item) {
                // 只处理一次code_value,避免重复正则
                $cleanCodeValue = (float)preg_replace('#[^\w()/.%\-&]#', '', $item->code_value);
                
                return [
                    'name' => $item->name,
                    'ar_name' => $item->ar_name,
                    'code_value' => $item->code_value,
                    'clean_code_value' => $cleanCodeValue, // 新增处理后数值,供后续判断
                    'code' => $item->code,
                    'cate_id' => $item->cate_id,
                    'cat_name' => $item->cat_name,
                ];
            })
            ->values(); // 重置索引,避免集合键混乱

        // 用集合filter拆分数据,替代原生循环
        $higherValueData = $processedData->filter(fn($item) => $item['clean_code_value'] > REPORT_THRESHOLDS['none_reactive'])->values()->all();
        $lowerValueData = $processedData->filter(fn($item) => $item['clean_code_value'] <= REPORT_THRESHOLDS['none_reactive'])->values()->all();
        $totalValues = $processedData->all();

        return [
            'lowCount' => self::countLow($processedData),
            'highCount' => self::countHigh($processedData),
            'foodSense' => $foodSense,
            'reportData' => $processedData,
            'mediumCount' => self::countMedium($processedData),
            'lowerValueData' => $lowerValueData,
            'higherValueData' => $higherValueData,
            'noneReactiveCount' => self::countNoneReactive($processedData),
            'totalValues' => $totalValues
        ];
    }

    // 拆分统计逻辑为独立方法,便于复用和测试
    private static function countNoneReactive($data)
    {
        return $data->filter(fn($item) => $item['clean_code_value'] <= REPORT_THRESHOLDS['none_reactive'])->count();
    }

    private static function countLow($data)
    {
        return $data->filter(fn($item) => 
            $item['clean_code_value'] > REPORT_THRESHOLDS['none_reactive'] 
            && $item['clean_code_value'] <= REPORT_THRESHOLDS['low_upper']
        )->count();
    }

    private static function countMedium($data)
    {
        return $data->filter(fn($item) => 
            $item['clean_code_value'] >= REPORT_THRESHOLDS['medium_lower'] 
            && $item['clean_code_value'] <= REPORT_THRESHOLDS['medium_upper']
        )->count();
    }

    private static function countHigh($data)
    {
        return $data->filter(fn($item) => $item['clean_code_value'] >= REPORT_THRESHOLDS['high_lower'])->count();
    }
}

// 调用示例
$data = ReportDataProcessor::process($rawData, $foodSense);

优化点:

  • 仅处理一次code_value,提升性能
  • 用Laravel集合替代原生循环/数组操作,代码更简洁
  • 阈值集中管理,修改无需多处改动
  • 统计逻辑拆分为独立方法,便于单元测试和复用

二、display_table Helper函数优化

核心问题:HTML拼接易出错、逻辑混乱、无XSS防护、参数冗余

原函数用字符串拼接HTML,逻辑绕且无转义,可拆分逻辑、添加XSS防护、优化参数传递。

优化后代码:

if (!function_exists('display_table')) {
    function display_table(array $options)
    {
        $start = $options['start'] ?? 0;
        $end = $options['end'] ?? count($options['tableValue']);
        $tableValue = $options['tableValue'];
        $currentNumber = $options['number'] ?? 1;
        $currentCategory = null;

        // 截取需处理的数据子集
        $subset = array_slice($tableValue, $start, $end - $start);
        $html = '<table class="sensitivity-data-table"><tbody>';

        foreach ($subset as $item) {
            // 输出分类表头(仅当分类变化时)
            if ($currentCategory !== $item['cate_id']) {
                $html .= sprintf(
                    '<tr><th class="th-lg" colspan="2">%s</th><th class="th-sm sensitivity-tab">Sensitivity</th></tr>',
                    htmlspecialchars($item['cat_name']) // XSS防护
                );
                $currentCategory = $item['cate_id'];
            }

            // 输出数据行
            $html .= sprintf(
                '<tr>
                    <td class="td-lg" colspan="2">%d: %s-%s<span>%s</span></td>
                    <td class="td-sm"><span class="sensitivity-circle %s"></span></td>
                </tr>',
                $currentNumber,
                htmlspecialchars($item['name']),
                htmlspecialchars($item['ar_name']),
                htmlspecialchars($item['code_value']),
                getColor($item['clean_code_value'] ?? $item['code_value']) // 优先用处理后的值
            );
            $currentNumber++;
        }

        $html .= '</tbody></table>';

        // 返回清晰的键名,避免歧义
        return [
            'next_number' => $currentNumber,
            'html' => $html,
            'processed_count' => count($subset)
        ];
    }
}

优化点:

  • 用sprintf替代字符串拼接,代码更易读且减少语法错误
  • 添加htmlspecialchars转义输出内容,防止XSS攻击
  • 用数组参数替代多个独立参数,避免参数顺序混乱
  • 逻辑拆分:先处理子集,再遍历生成行,可读性提升
  • 返回键名更清晰(如next_number替代start)

三、调用逻辑优化

核心问题:手动分页易出错、变量拼写错误($hightStart→$highStart)

原调用代码需手动维护start/end,可封装为自动分页函数,减少重复代码。

优化后代码:

// 封装分页生成表格逻辑
function generate_sensitivity_tables(array $data, $perPage = 20)
{
    $total = count($data);
    $currentNumber = 1;
    $currentStart = 0;

    while ($currentStart < $total) {
        $currentEnd = min($currentStart + $perPage, $total);
        $result = display_table([
            'start' => $currentStart,
            'end' => $currentEnd,
            'tableValue' => $data,
            'number' => $currentNumber
        ]);

        echo $result['html'];
        $currentStart = $currentEnd;
        $currentNumber = $result['next_number'];
    }
}

// 调用示例
generate_sensitivity_tables($data['higherValueData'], 20);

优化点:

  • 自动处理分页逻辑,无需手动维护start/end
  • 修复变量拼写错误,避免逻辑bug
  • 封装后可在多处复用,减少重复代码

额外建议

  1. 视图层分离:如果使用Laravel,建议用Blade模板生成HTML表格,而非在Helper中拼接,比如创建components/sensitivity-table.blade.php,将表格逻辑移至视图,更符合MVC架构。
  2. 单元测试:对ReportDataProcessor中的统计方法、display_table函数编写单元测试,确保逻辑修改后不影响现有功能。
  3. 类型提示:PHP 7+支持类型提示,可给函数参数、返回值添加类型,提升代码可读性和IDE支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:44:53