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

PHP从外部CSV更新本地CSV失败求助(WordPress/WooCommerce场景)

问题解决与代码修正

一、核心问题分析

你的代码存在四个关键问题:

  1. 文件路径错误:使用/pricelist_206876.csv指向的是服务器根目录,而非PHP文件所在的同目录
  2. 未实现指定列提取:直接覆盖整个CSV,没有筛选需要的目标字段
  3. Cron命令错误:命令中多余的/dev/null参数会干扰正常执行
  4. 未实现追加逻辑:当前代码是覆盖原有数据,而非追加新内容

二、修正后的完整代码

<?php
// 开启错误记录,方便排查问题
error_reporting(E_ALL);
ini_set('error_log', __DIR__ . '/datafeed_error.log');
ini_set('log_errors', 1);

// 远程CSV地址
$remoteCsvUrl = "https://cdn.sandberg.world/feeds/5dkmiglm.csv";
// 本地CSV路径:使用__DIR__获取当前PHP文件所在目录,确保路径正确
$localCsvPath = __DIR__ . "/pricelist_206876.csv";

// 需要提取的目标字段列表
$targetFields = [
    'Partno',
    'Name',
    'Weight',
    'Width',
    'Height',
    'SE:retailPriceIncVat',
    'sv:CategoryName'
];

// 1. 获取远程CSV内容
$remoteContent = file_get_contents($remoteCsvUrl);
if ($remoteContent === false) {
    error_log("无法获取远程CSV文件");
    exit(1);
}

// 2. 解析远程CSV内容
$remoteRows = array_map('str_getcsv', explode("\n", trim($remoteContent)));
if (empty($remoteRows)) {
    error_log("远程CSV无有效内容");
    exit(1);
}

// 匹配目标字段对应的表头索引
$header = array_shift($remoteRows);
$fieldIndexes = [];
foreach ($targetFields as $field) {
    $index = array_search($field, $header);
    if ($index === false) {
        error_log("缺少必填字段:{$field}");
        exit(1);
    }
    $fieldIndexes[] = $index;
}

// 3. 处理本地CSV:若文件不存在则先写入表头
$localExists = file_exists($localCsvPath);
$outputRows = [];

if (!$localExists) {
    $outputRows[] = $targetFields;
}

// 4. 提取每行的目标字段,构建输出内容
foreach ($remoteRows as $row) {
    if (count($row) < count($fieldIndexes)) {
        continue; // 跳过不完整的无效行
    }
    $extractedRow = [];
    foreach ($fieldIndexes as $index) {
        $extractedRow[] = $row[$index];
    }
    $outputRows[] = $extractedRow;
}

// 5. 格式化CSV内容并追加到本地文件
$outputContent = '';
foreach ($outputRows as $row) {
    // 处理含逗号、引号的字段,符合CSV规范
    $formattedFields = array_map(function($value) {
        return '"' . str_replace('"', '""', $value) . '"';
    }, $row);
    $outputContent .= implode(',', $formattedFields) . "\n";
}

// 写入本地文件:FILE_APPEND实现追加,LOCK_EX避免并发写入冲突
if (file_put_contents($localCsvPath, $outputContent, FILE_APPEND | LOCK_EX) === false) {
    error_log("无法写入本地CSV文件");
    exit(1);
}

error_log("数据导入成功,共添加 " . count($outputRows) . " 行");
?>

三、关键修正点说明

  • 路径修正:用__DIR__获取当前PHP文件的目录,确保本地CSV路径指向正确的同目录文件
  • 字段筛选:通过表头匹配目标字段的索引,精准提取需要的列,解决新旧CSV列数不同的问题
  • 追加逻辑:使用FILE_APPEND标记实现追加写入,而非覆盖原有数据;添加LOCK_EX避免多进程并发写入冲突
  • 错误处理:添加错误日志记录,方便排查远程CSV获取失败、本地写入失败等问题
  • CSV规范兼容:自动处理字段中的逗号和引号,避免破坏CSV文件格式

四、Cron命令修正

原命令中的/dev/null参数无效,正确的Cron命令应为:

/usr/bin/php -q "/home/goffero/domains/goffero.com/datafeedcode.php"

若需要记录Cron执行日志,可修改为:

/usr/bin/php -q "/home/goffero/domains/goffero.com/datafeedcode.php" >> "/home/goffero/domains/goffero.com/cron_log.log" 2>&1

五、额外排查步骤

  1. 文件权限检查:确保pricelist_206876.csv和PHP文件所在目录的权限为755(目录)和644(文件),且运行Cron的用户(通常为服务器用户名或apache)拥有写入权限
  2. 远程资源访问测试:在服务器终端执行curl https://cdn.sandberg.world/feeds/5dkmiglm.csv,确认服务器能正常访问远程CSV
  3. 错误日志排查:查看代码生成的datafeed_error.log和Cron日志,定位具体错误原因

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:05:19