1、PHP上传文件
PHP后台获取上传文件,利用全局变量$_FILES获取上传文件。
$schemaTmpFile = $_FILES['owndata_schema'];
# 文件属性
array(5) {
'name' =>
string(12) "desc-foo.csv"
'type' =>
string(24) "application/vnd.ms-excel"
'tmp_name' =>
string(19) "/data/tmp/php8zDKJi"
'error' =>
int(0)
'size' =>
int(180)
}
文件属性:
- 1、 name: 下标指的是上传文件的文件名。
- 2、**type:下标指的是上传文件的类型。 **
- 3、 **tmp_name: 下标指的是上传的文件在服务器端存放的临时文件名。 **
- 4、**error: 下标是上传文件错误的表示,可用于检测文件是否上传,以便找到错误的原因。 **
- 5、**size: 下标是上传文件的大小,单位是字节。 **
2、PHP拉取远程文件
如果文件是远程文件,首先需要判断远程文件是否真的存在。
① 判断远程文件是否存在
curl经过验证是最为靠谱的方法。
/**
* 判断远程文件是否存在
* @param $remoteFile
* @return bool
*/
public function remoteFileExists($remoteFile)
{
$curl = curl_init($remoteFile);
// CURLOPT_NOBODY设置为true,因为不需要真正的读取文件内容,只需要判断是否存在
curl_setopt($curl, CURLOPT_NOBODY, true);
$result = curl_exec($curl);
$ret = false;
//if request did not fail
if ($result !== false) {
//if request was ok, check response code
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode == 200) {
$ret = true;
}
}
curl_close($curl);
return $ret;
}
② 获取远程文件大小
/**
* 获取远程文件大小
* @param $remoteFile
* @return mixed
*/
public static function getRemoteFileSize($remoteFile)
{
$headerInfo = get_headers($remoteFile,true);
return $headerInfo['Content-Length'];
}
get_headers(): 返回一个数组,包含有服务器响应一个 HTTP 请求所发送的标头。可以从头部信息的Content-Length字段获取文件大小。
demo示例如下:
$remoteFile = "http://km.oa.com/files/photos/pictures/201801/1516586415_55_w157_h211.jpg";
$headerInfo = get_headers($remoteFile,true);
var_dump($headerInfo);
// 打印结果如下:
array(11) {
[0] =>
string(15) "HTTP/1.1 200 OK"
'Server' =>
string(12) "nginx/1.10.1"
'Date' =>
string(29) "Wed, 24 Jan 2018 09:04:03 GMT"
'Content-Type' =>
string(10) "image/jpeg"
'Content-Length' =>
string(5) "15893"
'Last-Modified' =>
string(29) "Mon, 22 Jan 2018 02:00:14 GMT"
'Connection' =>
string(5) "close"
'ETag' =>
string(15) ""5a6545ae-3e15""
'Expires' =>
string(29) "Fri, 23 Feb 2018 09:04:03 GMT"
'Cache-Control' =>
string(15) "max-age=2592000"
'Accept-Ranges' =>
string(5) "bytes"
}
3、下载远程文件
下载远程文件思路:
- 1、获取文件内容,然后写到服务器本地地址。
- 2、大文件,需要分片读取。
/**
* 下载文件&存储文件到磁盘
* @param string $fileUrl
* @return bool|string
*/
protected function downFile($fileUrl = '')
{
$time = time();
$taskDir = FILE_UPLOAD_BASE_PATH . '/owndata_schema';
if (!is_dir($taskDir)) {
if (mkdir($taskDir)) {
Log::info("create dir succ:" . $taskDir);
} else {
Log::info("create dir fail:" . $taskDir);
$this->err_msg = "文件路径创建失败";
return false;
}
}
$pathParts = pathinfo($fileUrl);
$fileName = $pathParts['basename'];
$fileName = $time . '_' . $fileName;
$saveFileUrl = $taskDir . '/' .$fileName;
// 下面核心代码
// fopen()可以读入大文件,每次可以指定读取一部分的内容。在操作大文件的时候也很有用。
$rfp = fopen($fileUrl, "rb");
$wfp = fopen($saveFileUrl, "a+");
while (!feof($rfp)) {
$tmpContent = fread($rfp, 1024*8);
fwrite($wfp, $tmpContent);
}
fclose($rfp);
fclose($wfp);
// 返回磁盘临时存储文件路径
return $saveFileUrl;
}
总结:利用PHP下载文件时,应该要注重场景。如果本身只是几个小文件被下载,那么使用PHP下载比较好;但是如果PHP要承受大量下载请求,这时下载文件就不该交给PHP做,应该采取异步方式进行下载。
4、文件编码
获取上传文件或者远程文件时,有个时候需要对文件的编码进行处理。
① 获取文件编码函数
mb_detect_encoding()
② 针对UTF-8文件,去掉文件BOM头
/**
* UTF8 去掉文本中的 bom头
* @param $contents
* @return mixed
*/
private function clearBom($contents)
{
$bom = chr(239) . chr(187) . chr(191);
return str_replace($bom, '', $contents);
}
/**
* 文件编码格式处理
* @param $fileUrl
*/
private function clearFileBom($fileUrl)
{
$encodeList = ['GBK', 'UTF-8'];
$contents = file_get_contents($fileUrl);
$encode = mb_detect_encoding($contents, $encodeList);
if ($encode == 'UTF-8') {
$contents = $this->clearBom($contents);
file_put_contents($fileUrl, $contents);
} else {
$contents = StringUtil::gbkToutf8($contents);
file_put_contents($fileUrl, $contents);
}
}
|
请发表评论