背景
最近有需求下载头像到本地,以文件形式上传到第三方,遇坑就填
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
配置手册(文档地址),配置项需要什么翻着找找
遇到几个问题:
- 部分图片所在主站防盗链机制,header头部需要加refer
- 部分图片地址是facebook,要配代理,并且图片会重定向到其他图片服务器上
- 挂代理加超时,有时不定时拿不到,加重试机制
因此解决:
- 配置项加
CURLOPT_REFERER => 'xx地址'
配置项加
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
- 随便加个循环,比如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
,官方坑人示例