PHP从外部CSV更新本地CSV失败求助(WordPress/WooCommerce场景)
问题解决与代码修正
一、核心问题分析
你的代码存在四个关键问题:
- 文件路径错误:使用
/pricelist_206876.csv指向的是服务器根目录,而非PHP文件所在的同目录 - 未实现指定列提取:直接覆盖整个CSV,没有筛选需要的目标字段
- Cron命令错误:命令中多余的
/dev/null参数会干扰正常执行 - 未实现追加逻辑:当前代码是覆盖原有数据,而非追加新内容
二、修正后的完整代码
<?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
五、额外排查步骤
- 文件权限检查:确保
pricelist_206876.csv和PHP文件所在目录的权限为755(目录)和644(文件),且运行Cron的用户(通常为服务器用户名或apache)拥有写入权限 - 远程资源访问测试:在服务器终端执行
curl https://cdn.sandberg.world/feeds/5dkmiglm.csv,确认服务器能正常访问远程CSV - 错误日志排查:查看代码生成的
datafeed_error.log和Cron日志,定位具体错误原因
内容的提问来源于stack exchange,提问作者PrimaryGroupEmployee
相关产品推荐
相关产品推荐

