WooCommerce中配置外部PHP脚本动态提供的可下载产品时出现「文件未找到」的问题求助
WooCommerce中配置外部PHP脚本动态提供的可下载产品时出现「文件未找到」的问题求助
问题背景
我在WooCommerce商店里需要售卖由PHP脚本动态提供的JPEG图片——这些图片来自一个拥有数万张图片的远程目录,必须通过API按需获取,没法本地存储所有文件。我写了一个PHP脚本fetch_image.php,通过id参数指定目录标识符就能返回对应图片,比如https://example.com/fetch_image.php?id=12345,浏览器直接访问能正常下载test.jpg。
但遇到了两个棘手的问题:
- 直接把这个PHP脚本URL设为产品下载链接时,WooCommerce拒绝了,提示「不允许的文件类型」,我不想开启PHP文件类型的权限(怕有安全风险)。
- 我用
.htaccess做了重定向,把带jpg后缀的URL指向这个脚本:
手动访问RewriteRule ^REDIRECT_shop_download.jpg https://example.com/fetch_image.php [L,R=301]https://example.com/REDIRECT_shop_download.jpg?id=12345能正常获取图片,但用它作为产品下载链接时,购买后点击下载却提示「文件未找到」,哪怕去掉脚本里的下载头信息也没用。
可能的原因分析
根据我处理类似问题的经验,这个问题大概率出在这几个地方:
- 重写规则丢失查询参数:你当前的RewriteRule没有传递
id参数,当WooCommerce生成的下载链接带id以及自身的验证参数(比如key、expires)时,重定向后这些参数会丢失,导致脚本无法获取正确的图片ID,最终返回404。 - WooCommerce的下载验证机制:WooCommerce会对下载链接做安全校验,外部301重定向可能被它的安全逻辑拦截;另外它默认更认可本地存在的文件,对动态生成的内容识别有限制。
- 服务器重定向类型问题:外部重定向(R=301)会让浏览器跳转,但WooCommerce的下载流程可能期望内部处理,而不是外部跳转。
解决方案尝试
1. 修复.htaccess重写规则,保留查询参数
把你的重写规则改成这样,用QSA(Query String Append)参数保留原有的所有查询参数,并且使用内部重定向(去掉R=301,避免外部跳转):
RewriteRule ^REDIRECT_shop_download.jpg$ /fetch_image.php [QSA,L]
这样访问REDIRECT_shop_download.jpg?id=12345时,脚本能正常接收到id参数,同时WooCommerce附加的验证参数也能被传递过去(脚本可以忽略这些无关参数,只提取id)。
2. 让WooCommerce认可动态下载链接
如果内部重写还是不行,可以通过WooCommerce的钩子来绕过默认的文件验证逻辑。比如添加以下代码到主题的functions.php或者自定义插件里:
add_filter('woocommerce_downloadable_product_file_paths', 'custom_dynamic_download_path', 10, 2); function custom_dynamic_download_path($file_paths, $product) { foreach ($file_paths as $key => $path) { // 检查是否是你的动态下载URL if (strpos($path, 'REDIRECT_shop_download.jpg') !== false) { // 直接返回真实路径,告诉WooCommerce不要强制验证本地文件 $file_paths[$key] = $path; } } return $file_paths; } // 或者直接自定义下载处理逻辑 add_action('woocommerce_download_product_file', 'custom_process_dynamic_download', 10, 4); function custom_process_dynamic_download($file_path, $product, $download_id, $args) { if (strpos($file_path, 'REDIRECT_shop_download.jpg') !== false) { // 提取id参数 parse_str(parse_url($file_path, PHP_URL_QUERY), $query); $image_id = isset($query['id']) ? $query['id'] : ''; if ($image_id) { // 调用你的API获取图片逻辑 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, '远程API地址?id=' . $image_id); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); // 输出图片 header('Content-Type: image/jpeg'); header('Content-Disposition: attachment; filename="image-' . $image_id . '.jpg"'); echo $result; exit; } } }
这个方法直接在WooCommerce的下载流程里处理动态图片,绕开了默认的文件存在性检查。
3. 检查服务器日志排查问题
如果以上方法都没用,建议查看服务器的错误日志和访问日志:
- 错误日志里可能会显示脚本执行时的错误(比如API请求失败、权限不足)。
- 访问日志可以看到WooCommerce发起的请求是什么样的,是否传递了正确的
id参数,以及脚本返回的HTTP状态码(比如404、500)。
内容来源于stack exchange
相关产品推荐
相关产品推荐

