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");
    }
    

    现在您知道该目录存在并且您可以尝试写入它。错误处理很重要!