常用的文件工具类方法,包含创建csv文件、压缩及解压zip文件,下载文件等。
压缩文件(目录)使用方式如:
FileUtils::compressFolder('all.zip', '/data/files/', '*.txt');
<?php
/**
* 文件工具类
* Presented by XServer.
* Author: Nomandia
* Date: 2018/1/25 11:38
*/
abstract class FileUtils
{
/**
* 检查目录
* @param string $path
*/
static function checkPath($path)
{
if (!file_exists($path)) {
mkdir($path, 0777, true);
}
chmod($path, 0777);
}
//*************** 下载工具类 ******************//
/**
* 下载文件
* @param string $filename
* @param string $saveName
* @param string $mimetype
*/
static function sendFile($filename, $saveName, $mimetype = 'application/octet-stream', $srcPath = '/download/')
{
header('Content-type: ' . $mimetype);
// 处理中文文件名
$ua = $_SERVER ["HTTP_USER_AGENT"];
if (preg_match("/MSIE/i", $ua)) {
$encoded_filename = rawurlencode($saveName);
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/i", $ua)) {
header("Content-Disposition: attachment; filename*=\"utf8''" . $saveName . '"');
} else {
header('Content-Disposition: attachment; filename="' . $saveName . '"');
}
header('X-Accel-Redirect: ' . $srcPath . $filename);
}
/**
* 发送内容数据并下载
* @param string $content
* @param string $saveName
* @param string $mimetype
* @param string $charset
*/
static function sendContent($content, $saveName, $mimetype = 'text/plain', $charset = 'UTF-8')
{
header("Content-Type: {$mimetype}; charset={$charset}");
header("Content-Disposition: inline; filename=\"" . $saveName . "\"");
ob_clean();
ob_start();
echo $content;
ob_flush();
ob_end_clean();
exit;
}
/**
* Yii framework支持
* 通过XFile模式下载文件(需要Nginx特殊配置)
* @param string $uri 目标文件名
* @param string $saveName 存储的文件名
* @param array $options 配置表
*
*/
static function xSendFile($uri, $saveName, $mimeType = 'application/octet-stream', $options = [
'mimeType' => 'application/octet-stream',
'terminate' => true,
])
{
/**
* 对应的需要在nginx中配置关联路径
* location /download {
* internal;
* alias /data/www/download/;
* }
* 如此要在URL中下载 http://domain/download/path/target.xxx 则需要将其放置到
* /data/www/download/path/target.xxx 中即可,即这种方式是直接发送文件而不用走PHP程序从而节约资源
*/
$options['mimeType'] = $mimeType;
$options['saveName'] = $saveName;
Yii::app()->getRequest()->xSendFile($uri, $options);
}
//*************** CSV工具 ******************//
/**
* 创建CSV文件
* @param string $csvFile CSV文件路径
* @param array $rows 目标数据
* @param array $title 标题
* @param bool $compress 是否压缩(压缩后将删除.csv文件)
* @return string $compress=true时返回压缩文件名,false时返回原文件名
*/
static function createCSVFile($csvFile, $rows, $title = null, $compress = false)
{
if (file_exists($csvFile)) {
@unlink($csvFile);
}
// 生成csv文件(如果文件存在则清空)
$fh = fopen($csvFile, 'w');
$content = '';
if (is_array($title)) {
$content .= join(',', $title) . "\r\n";
}
foreach ($rows as $row) {
$content .= join(',', $row) . "\r\n";
}
fwrite($fh, $content);
fclose($fh);
// 压缩目标文件
if ($compress) {
$zipFilename = pathinfo($csvFile, PATHINFO_DIRNAME) . pathinfo($csvFile, PATHINFO_FILENAME) . '.zip';
self::compress($zipFilename, $csvFile, true);
return $zipFilename;
}
return $csvFile;
}
//*************** 文件压缩与解压 ******************//
/**
* @var string 临时目录
*/
protected static $_TMP_PATH = '/tmp/';
/**
* @var string 日期时间格式
*/
protected static $_DATETIME_FORMAT = '';
/**
* @var bool 是否增加注释
*/
protected static $_ADD_COMMENT = false;
/**
* @var string 注释文件
*/
protected static $_COMMENT = 'powered by jgyou.com';
/**
* @param bool $open
*/
static function openComment($open = false, $comment = null)
{
self::$_ADD_COMMENT = $open;
if (null !== $comment) {
self::$_COMMENT = $comment;
}
}
/**
* 设置注释
* @param string $comment
*/
static function setComment($comment)
{
self::$_COMMENT = $comment;
}
/**
* 设置压缩文件日期时间后缀
* @param string|bool $format string=日期时间格式 bool=开启默认YmdHis
*/
static function setDatetimeFormat($format = '')
{
self::$_DATETIME_FORMAT = true == $format ? 'YmdHis' : $format;
}
/**
* 设置临时文件夹
* @param string $folder
*/
static function setTmpFolder($folder)
{
self::$_TMP_PATH = $folder;
}
/**
* 解压缩文件
* @param string $zipFilename
* @param string $destDir
* @return bool
*/
static function extractTo($zipFilename, $destDir = '')
{
if (!file_exists($zipFilename)) {
return false;
}
$za = new ZipArchive();
if ($za->open($zipFilename)) {
$zipname = pathinfo($zipFilename, PATHINFO_FILENAME) . '/';
$za->extractTo(($destDir ? pathinfo($destDir, PATHINFO_DIRNAME) : '/tmp/') . $zipname);
return $za->close();
}
return false;
}
/**
* 压缩文件
* @param string $zipFilename 输出的压缩文件名
* @param string|array $srcFilenames 原文件 string=单一文件 array=批量压缩
* @param bool $removeSrc 压缩后是否删除原文件
*/
static function compress($zipFilename, $srcFilenames, $removeSrc = false)
{
if (file_exists($zipFilename)) {
@unlink($zipFilename);
}
$za = new ZipArchive();
if ($za->open($zipFilename, ZipArchive::CREATE)) {
if (!is_array($srcFilenames)) {
$za->addFile($srcFilenames, basename($srcFilenames));
$za->close();
if (!!$removeSrc) {
@unlink($srcFilenames);
}
} else {
foreach ($srcFilenames as $filename) {
$za->addFile($filename, basename($filename));
}
}
if (self::$_ADD_COMMENT) {
$za->setArchiveComment(self::$_COMMENT);
}
$za->close();
if ($removeSrc) {
foreach ($srcFilenames as $filename) {
@unlink($filename);
}
}
}
}
/**
* 压缩文件夹(只能压缩本级目录下的文件)
* @param string $zipFilename 输出的压缩文件名
* @param string $folder 源文件目录
* @param string $pattern 匹配的文件(不指定则选取所有文件)
* @param bool $removeSrc true=删除被压缩的文件
*/
static function compressFolder($zipFilename, $folder, $pattern = '*', $removeSrc = false)
{
if (!class_exists('ZipArchive')) {
throw new Exception('class ZipArchive not available.');
}
$folder .= '/' !== substr($folder, -1, 1) ? '/' : '';
$files = glob($folder . $pattern);
if (file_exists($zipFilename)) {
// 删除原压缩文件
unlink($zipFilename);
}
if (self::$_DATETIME_FORMAT) {
// 增加日期时间戳
$zipFilename = pathinfo($zipFilename, PATHINFO_FILENAME) . '_' . date(self::$_DATETIME_FORMAT) . '.' . pathinfo($zipFilename, PATHINFO_EXTENSION);
}
$za = new ZipArchive();
if ($za->open($folder . basename($zipFilename), ZipArchive::CREATE)) {
foreach ($files as $filename) {
$za->addFile($filename, basename($filename));
if (!!$removeSrc) {
// 移除原文件
unlink($filename);
}
}
if (self::$_ADD_COMMENT) {
$za->setArchiveComment(self::$_COMMENT);
}
return $za->close();
}
return false;
}
}