1

我编写了一个带有单元测试的函数,以使用 PHP 下载图像

// ...
if (!copy($url, $imagePath)) {
    return null;
}
// ...

它在本地工作,但在Bitbucket Pipelines中,单元测试失败。无法下载文件(在存储中找不到文件)。

它可能已被故意禁用。所以我只想在copy()可以下载外部文件的情况下运行这个单元测试。

我试过这个但没有奏效:

public function test_downloadImage()
{
    if (!ini_get('allow_url_fopen') || in_array('copy', explode(',', ini_get('disable_functions')))) {
        return;
    }
    // download the image...
    // assert file exists...
}

如何测试是否copy()可以下载外部文件?

谢谢你。

问题解决了

对此感到抱歉,但问题不是来自 PHP copy()

它试图将图像下载到不存在的目录。事实上,我忘了设置Laravel Public 目录符号链接。它已经在我的电脑上设置好了。

4

2 回答 2

1

用于curl发起 HEAD 请求:

function url_is_readable($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    $res = curl_exec($ch);
    return false !== $res;
}

然后测试一下:

var_dump(url_is_readable('https://imgs.xkcd.com/comics/im_so_random.png'));
var_dump(url_is_readable('http://whyohwhy.example.co/monkey.png'));

然后您可以使用它curl来执行复制。这有几个好处。首先,它的工作原理与是否allow_url_fopen已关闭无关。其次,curl为您提供更多控制、诊断和错误信息。第三,它更酷。:)

于 2017-03-16T01:42:36.223 回答
0

考虑切换到 curl,因为allow_url_fopen出于安全原因,它通常被禁用。


但是,要回答您的问题,您可以使用此处为 file_get_contents() 描述的方法来检查您是否可以从网络获取内容。

  1. 在前面加上 @ 来抑制警告(如PHP 手册file_get_contents所建议的那样,但如果可以避免,请不要使用它)
  2. 检查返回值null
  3. 抛出异常

例子:

public function test_downloadImage($path)
{
    $contents = @file_get_contents($path);
    if($contents === null) {
        $error = error_get_last();
        throw new Exception($error['message']);
    }
    return $contents;
}

使用 try/catch 调用此函数:

try {
    $fileContent = test_downloadImage('http://stackoverflow.com')
    // Success, do something with your file
} catch (Exception $e) {
    // Download failed, log error from $e->getMessage(), show message to user
}
于 2017-03-15T23:44:32.910 回答