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文件夹的路径,因为我不知道如何添加),但文件名前面是文件夹的名称。因此,如果下载的文件是word1.mp3,则该文件将保存为bootstrapword1.mp3如何使用原始名称保存文件,而不使用任何前缀,并使用正确的路径?

这一行就是问题所在:

$file=fopen(目录名(目录名)(file))$target,'w+');

将其更改为这个解决了问题:

$file=fopen(目录名(目录名)(file))。"/发音/"。$target,'w+');

fopen()中没有/,这两个字符串只是连接在一起,因此文件名带有前缀的目录名。

一个更简单的解决方案是使用实际路径;)

$file = fopen(__DIR__."/../pronunciations/".$target,'w+');

注意以下几点:

  • 这使用__DIR__常量,该常量表示当前脚本的目录。它相当于dirname(__FILE__),但IMO更清晰、更深思熟虑
  • 路径中的..表示"父目录"。是的,你可以在路径中使用它!所以为了你,我希望你已经确保$target是一个有效的文件名
  • 显然,如果目录不存在,那么它将失败。我们可以假设当前目录存在(否则文件怎么存在?),也可以假设父目录(..)也存在。然而,我们不应该假设pronunciations存在。。。

    $dir = __DIR__."/../pronunciations";
    if( !file_exists($dir)) {
        mkdir($dir);
    }
    if( !is_dir($dir)) {
        throw new RuntimeException("Target directory not found");
    }
    

    现在您知道该目录存在,可以尝试对其进行写入。错误处理很重要!