背景

最近有需求下载头像到本地,以文件形式上传到第三方,遇坑就填

curl

第一版

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true, // TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出(因为要写文件)
    CURLOPT_HEADER         => false, // 启用时会将头文件的信息作为数据流输出(适合调试)
    CURLOPT_URL            => 'url',
]);

$data = curl_exec($ch);
curl_close($ch);

curl_setopt配置手册(文档地址),配置项需要什么翻着找找

遇到几个问题:

  1. 部分图片所在主站防盗链机制,header头部需要加refer
  2. 部分图片地址是facebook,要配代理,并且图片会重定向到其他图片服务器上
  3. 挂代理加超时,有时不定时拿不到,加重试机制

因此解决:

  1. 配置项加CURLOPT_REFERER => 'xx地址'
  2. 配置项加

    CURLOPT_FOLLOWLOCATION  => true, // TRUE 时将会根据服务器返回 HTTP 头中的 "Location: " 重定向
    CURLOPT_PROXY           => '代理地址',
    CURLOPT_PROXYPORT       => '代理端口',
    CURLOPT_PROXYTYPE       => CURLPROXY_SOCKS5, // 可以是 CURLPROXY_HTTP (默认值) CURLPROXY_SOCKS4、 CURLPROXY_SOCKS5、 CURLPROXY_SOCKS4A 或 CURLPROXY_SOCKS5_HOSTNAME
  3. 随便加个循环,比如while

第二版

$curl_opts = [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => false,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_URL            => '图片地址',
    CURLOPT_REFERER        => '防盗链主站地址',
    CURLOPT_TIMEOUT        => 20,
];

foreach (['fbcdn', 'facebook'] as $domain) {
    if (stripos('图片地址', $domain) !== false) {
        $curl_opts += [
            CURLOPT_PROXY     => '代理地址',
            CURLOPT_PROXYPORT => '代理端口',
            CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5,
        ];

        break;
    }
}

$retry_time = 2;
while ($retry_time > 0) {
    $ch = curl_init();
    curl_setopt_array($ch, $curl_opts);

    try {
        $data = curl_exec($ch); //data即为文件流
        curl_close($ch);

        break;
    } catch (\Exception $e) {
        // 可进行其他异常处理
        $retry_time--;
    }
}

进行curl_setopt配置时,注意参数有版本限制,低版过低本不支持,使用curl_version()确认当前环境版本

sftp

使用之前shell确认是已安装ssh2扩展,php -m | grep ssh2

$sftp_connection = ssh2_connect('地址', '端口');

// 如果是公钥认证,ssh2_auth_pubkey_file()
ssh2_auth_password($sftp_connection, '用户名','密码');

$sftp = ssh2_sftp($sftp_connection);

$remote_uri = sprintf('ssh2.sftp://%s/write/%s', (int) $sftp, '远程文件名'); // 强转资源句柄
file_put_contents($remote_uri, file_get_contents('本地文件地址')); // 上传写入远程

大坑注意
这里ssh2_sftp获取到的资源句柄使用时需要强转int,官方坑人示例


em0t
758 声望23 粉丝

Talk is cheap, show me the code