PHP: fopen() 中的目标文件路径
PHP: Target file path in fopen()
我有一个cURL下载功能如下:
function down($url, $target){
set_time_limit(0);
$file = fopen(dirname(dirname(__FILE__)) . $target, 'w+');
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_BINARYTRANSFER => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FILE => $file,
CURLOPT_TIMEOUT => 50,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
]);
$response = curl_exec($curl);
if($response === false) {
throw new \Exception('Curl error: ' . curl_error($curl));
}
$response;
}
我的脚本在以下路径中:
a-s/bootstrap/php/downloadscript.php
我的目标是将下载的文件存储在:
a-s/bootstrap/pronunciations/
当我 运行 这个脚本时,它会按预期将文件下载到 bootstrap
文件夹(我还没有将路径添加到 pronunciations
文件夹,因为我不知道不知道如何)但文件名前面加上文件夹的名称。因此,如果下载的文件是word1.mp3,文件保存为bootstrapword1.mp3。如何使文件以原始名称保存且没有任何前缀并保存在正确的路径中?
问题出在这一行:
$file = fopen(dirname(dirname(FILE)) . $target, 'w+');
将其更改为此解决了问题:
$file = fopen(dirname(dirname(FILE)) . "/pronunciations/" .
$target, 'w+');
在 fopen() 中没有 /
,这两个字符串只是简单地连接在一起,因此文件名带有前缀目录名。
一个更简单的解决方案是使用实际路径 ;)
$file = fopen(__DIR__."/../pronunciations/".$target,'w+');
注意几件事:
- 这使用
__DIR__
常量,指示当前脚本的目录。它等同于 dirname(__FILE__)
但 IMO 更清晰、更慎重。
路径中的 ..
表示 "parent directory"。是的,您可以在路径中使用它!因此,为了您的利益,我希望您确保 $target
是一个有效的文件名!!
显然,如果目录不存在,那么它将失败。我们可以假设当前目录存在(否则文件怎么在那里?)并且我们可以假设父目录(..
)也存在。然而,我们不应该假设pronunciations
存在...
$dir = __DIR__."/../pronunciations";
if( !file_exists($dir)) {
mkdir($dir);
}
if( !is_dir($dir)) {
throw new RuntimeException("Target directory not found");
}
现在您知道该目录存在并且您可以尝试写入它。错误处理很重要!
我有一个cURL下载功能如下:
function down($url, $target){
set_time_limit(0);
$file = fopen(dirname(dirname(__FILE__)) . $target, 'w+');
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_BINARYTRANSFER => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FILE => $file,
CURLOPT_TIMEOUT => 50,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
]);
$response = curl_exec($curl);
if($response === false) {
throw new \Exception('Curl error: ' . curl_error($curl));
}
$response;
}
我的脚本在以下路径中:
a-s/bootstrap/php/downloadscript.php
我的目标是将下载的文件存储在:
a-s/bootstrap/pronunciations/
当我 运行 这个脚本时,它会按预期将文件下载到 bootstrap
文件夹(我还没有将路径添加到 pronunciations
文件夹,因为我不知道不知道如何)但文件名前面加上文件夹的名称。因此,如果下载的文件是word1.mp3,文件保存为bootstrapword1.mp3。如何使文件以原始名称保存且没有任何前缀并保存在正确的路径中?
问题出在这一行:
$file = fopen(dirname(dirname(FILE)) . $target, 'w+');
将其更改为此解决了问题:
$file = fopen(dirname(dirname(FILE)) . "/pronunciations/" . $target, 'w+');
在 fopen() 中没有 /
,这两个字符串只是简单地连接在一起,因此文件名带有前缀目录名。
一个更简单的解决方案是使用实际路径 ;)
$file = fopen(__DIR__."/../pronunciations/".$target,'w+');
注意几件事:
- 这使用
__DIR__
常量,指示当前脚本的目录。它等同于dirname(__FILE__)
但 IMO 更清晰、更慎重。
路径中的 ..
表示 "parent directory"。是的,您可以在路径中使用它!因此,为了您的利益,我希望您确保$target
是一个有效的文件名!!显然,如果目录不存在,那么它将失败。我们可以假设当前目录存在(否则文件怎么在那里?)并且我们可以假设父目录(
..
)也存在。然而,我们不应该假设pronunciations
存在...$dir = __DIR__."/../pronunciations"; if( !file_exists($dir)) { mkdir($dir); } if( !is_dir($dir)) { throw new RuntimeException("Target directory not found"); }
现在您知道该目录存在并且您可以尝试写入它。错误处理很重要!