最近闲来无聊想写个微信小程序,在小程序内看保存在群晖NAS里的PDF文件,相关pdf的文件存在mysql里.这就需要先用php从NAS搭建的ftp上下载文件到电脑本地,再通过接口传给微信小程序,进行阅读.
之后发现ftp提供的下载地址如:
ftp://xxx.xxx.xxx.xxx/DISK/PDF/%C4%A7%B6%BC%D2%B9%BE%B0.pdf
这里的%C4%A7%B6%BC%D2%B9%BE%B0转为中文是[魔都夜景]
在小程序端读取mysql获取到的是pdf的中文名,拼接后是中文的下载地址.如ftp://xxx.xxx.xxx.xxx/DISK/PDF/魔都夜景.pdf
而这个中文地址无法通过crul下载,会提示该文件不存在.
所以需要将%C4%A7%B6%BC%D2%B9%BE%B0转为中文[魔都夜景]拼接后才可顺利下载.
这里做个笔记
public function getFileFromFTP($host, $user, $pass, $path, $fileSavePath)
{
$curlobj = curl_init();//初始化
$path_split = explode("/", $path);
curl_setopt($curlobj, CURLOPT_URL, "ftp://" . $host . "/" . $path_split[2] . "/" . $path_split[3] . "/" .
rawurlencode(mb_convert_encoding($path_split[sizeof($path_split) - 1], "gb2312", "utf-8")));
$outfile = fopen($fileSavePath, 'w+'); //保存到本地文件的文件名
curl_setopt($curlobj, CURLOPT_FILE, $outfile);
$rtn = curl_exec($curlobj);
if (curl_errno($curlobj)) {
writeLog('Curl error: ' . curl_error($curlobj));
}
fclose($outfile);
curl_close($curlobj);
if ($rtn == 1) {
return true;
} else {
unlink($fileSavePath);//如果下载失败,但是本地open了这个文件,所以要删除
return false;
}
}
这里的重点是需要先通过mb_convert_encoding函数将文件名从utf-8转为gb2312,我本地的代码都是以utf-8保存的.而ftp的连接是通过gb2312保存的.之后再通过rawurlencode进行加密就可得到[%C4%A7%B6%BC%D2%B9%BE%B0]
而如果不使用mb_convert_encoding函数直接rawurlencode的话得到的是UTF-8加密后的代码[%E9%9D%92%E8%97%8F%E9%AB%98%E5%8E%9F%E6%97%85%E6%B8%B8%E6%8C%87%E5%8D%97]
另外还有一点需要注意的是,phpstorm的设置里搜索encode,
将encode相关的选项选为utf-8,否则调试时,debug里显示的变量值会变成乱码.
最后补充几句:
NAS是有提供SMB服务的,
本想通过php直接访问smb服务,后来发现php要访问smb服务有点难,加上mac本本是catalina系统,权限被加强了,导致各种permission denied…
后又想通过php直接执行shell命令方式下载到本来,shell单独执行没有任何问题,一到php里执行,system(),exec()各种试,各种返回127,126…无奈…
最后还是通过ftp解决了…
方法很多,条条大路通罗马,虽然我只通了1条.另外2条看看csdn里有没有高人指点一二…