函数封装
文件操作相关
创建文件
/**
* create_file, 根据文件路径, 创建文件
*
* @param string $filename 文件路径
*
* @return boolean true表示创建成功, false表示创建失败
*/
function create_file(string $filename) {
// 判断文件名是否存在
if (file_exists($filename)) {
// 如果存在, 则返回false
return false;
}
// 判断路径是否存在, 如果不存在, 则创建
if (!file_exists(dirname($filename))) {
// 如果不存在文件夹, 则创建, 权限给777, 递归创建, 就是如果有多级, 就创建多个文件夹, 比如"hello/world"
mkdir(dirname($filename), 0777, true);
}
// 往文件里写数据, 判断是否可写, 如果不可写, 会返回false
if (file_put_contents($filename, '') !== false) {
return true;
}
// 最后给一个返回值, 否则没有返回值的函数, 会返回null, 尽量做到, 每个函数都有返回值
return false;
}
复制代码
删除文件
/**
* del_file 根据文件路径, 删除文件
*
* @param string $filename 文件路径
*
* @return boolean true表示创建成功, false表示创建失败
*/
function del_file(string $filename) {
// 先判断以下, 如果文件不存在, 或者文件不可写, 都返回false, 之所以先判断是否可写, 因为如果有写保护, 文件会删不掉
if (!file_exists($filename) || !is_writable($filename)) {
// 返回false
return false;
}
// 如果删除成功, 返回true
if (unlink($filename)) {
// 返回成功
return true;
}
// 如果走到这一步了, 说明之前没有删除成功, 返回false
return false;
}
复制代码
复制文件
/**
* copy_file 复制文件到新的路径
*
* @param string $filename 文件路径
* @param string $dest 新的目录路径
*
* @return boolean true表示创建成功, false表示创建失败
*/
function copy_file(string $filename, string $dest) {
// 如果第二个参数不是目录, 递归创建
if (!is_dir($dest)) {
// 权限777, 最高权限, 递归创建
mkdir($dest, 0777, true);
}
// DIRECTORY_SEPARATOR, 系统常量, 表示系统分隔符,
// 因为每个操作系统的分隔符都不一样, 所以写成常量, 可以做到跨平台/操作系统
// $destName为新的文件路径
$destName = $dest . DIRECTORY_SEPARATOR . basename($filename);
// 如果文件已经存在, 则返回false, 不让复制
if (file_exists($destName)) {
// 返回false
return false;
}
// 如果复制成功, 返回true
if (copy($filename, $destName)) {
// 返回true, 表示成功
return true;
}
// 如果走到这一步, 说明之前的系统函数copy()没有成功, 返回false
return false;
}
复制代码
重命名文件
/**
* rename_file 重命名文件
*
* @param string $oldName 文件路径
* @param string $newName 新的文件的名字, 只要名字即可, 因为是同一个路径
*
* @return boolean true表示创建成功, false表示创建失败
*/
function rename_file(string $oldName, string $newName) {
// 重命名之前, 先判断参数一是不是文件, 不是文件则不能重命名, 因为只有文件可以重命名
if (!is_file($oldName)) {
// 返回false
return false;
}
// 获取参数一的路径
$path = dirname($oldName);
// 拼接出新文件的路径
$destName = $path . DIRECTORY_SEPARATOR . $newName;
// 重命名之前, 先判断有没有重名函数
if (is_file($destName)) {
// 如果已经存在同名文件, 返回false
return false;
}
// 使用系统函数rename, 来重命名文件
if (rename($oldName, $newName)) {
// 如果成功, 返回true
return true;
}
// 如果走到这一步, 说明系统函数rename()没有执行成功, 返回false
return false;
}
复制代码
剪切文件
/**
* cut_file 剪切文件
*
* @param string $filename 文件路径
* @param string $dest 剪切到的目录路径
*
* @return boolean true表示创建成功, false表示创建失败
*/
function cut_file(string $filename, string $dest) {
// 剪切文件之前, 需要判断是不是文件, 如果不是文件, 返回false
if (!is_file($filename)) {
// 如果不是文件, 返回false
return false;
}
// 判断路径是否存在, 如果不存在, 则创建
if (!is_dir($dest)) {
// 递归创建路径, 给与最高权限, 777
mkdir($dest, 0777, true);
}
// 拼接文件路径
$destName = $dest . DIRECTORY_SEPARATOR . basename($filename);
// 如果存在重名文件, 则不能剪切
if (is_file($destName)) {
// 返回false
return false;
}
// 使用系统函数rename, 来实现剪切功能
if (rename($filename, $destName)) {
// 成功返回true
return true;
}
// 如果走到这一步, 说明系统函数rename(), 没有执行成功, 返回false
return false;
}
复制代码
文件信息相关
返回文件信息
/**
* get_file_info 获取文件信息, 返回的是一个关联数组
*
* @param string $filename 文件路径
*
* @return array 返回包括文件信息的关联数组
* @return array['atime'] 访问时间
* @return array['mtime'] 修改时间
* @return array['ctime'] 创建时间
* @return array['size'] 文件大小, 调用trans_byte函数进行转换
* @return array['type'] 返回文件类型, 调用系统函数filetype
*/
function get_file_info(string $filename) {
// 获取文件信息的前提: 可以找到这个文件, 并且该文件可读
if (!is_file($filename) || !is_readable($filename)) {
// 如果找不到文件或者不可读, 返回false
return false;
}
// 返回一个数组, 时间格式为 年-月-日 时:分:秒
return [
// 访问时间
'atime' => date("Y-m-d H:i:s", fileatime($filename)),
// 修改时间
'mtime' => date("Y-m-d H:i:s", filemtime($filename)),
// 创建时间
'ctime' => date("Y-m-d H:i:s", filectime($filename)),
// 文件大小, 调用trans_byte函数进行转换
'size' => trans_byte(filesize($filename)),
// 返回文件类型, 调用系统函数filetype
'type' => filetype($filename),
];
}
复制代码
字节单位转换的函数
/**
* trans_byte 文件大小的单位转换
*
* @param int $byte 总的字节数
* @param int $precision 四舍五入时, 保留的小数点位数, 默认两位
*
* @return string 带上单位的文件大小
*/
function trans_byte(int $byte, int $precision = 2) {
// 定义一些变量, 用来描述单位之间的换算关系
$kb = 1024;
// 1mb = 1024kb
$mb = 1024 * $kb;
// 1gb = 1024mb
$gb = 1024 * $mb;
// 1tb = 1024gb
$tb = 1024 * $gb;
// 进行单位转换
if ($byte < $kb) { // 如果不足1kb, 单位为b
// 返回字节数
return $byte . 'B';
} elseif ($byte < $mb) { // 如果不够1mb, 返回kb数
// 四舍五入, 保留两位
return round($byte / $kb, $precision) . 'KB';
} elseif ($byte < $gb) { // 如果不够1gb, 返回mb数
// 四舍五入, 保留两位
return round($byte / $mb, $precision) . 'MB';
} elseif ($byte < $tb) { // 如果不够1tb, 返回gb数
// 四舍五入, 保留两位
return round($byte / $gb, $precision) . 'GB';
} else { // 最后不管多大, 返回都是TB数
// 四舍五入, 保留两位
return round($byte / $tb, $precision) . 'TB';
}
}
复制代码
读取文件内容,返回字符串
/**
* read_file 根据文件路径, 获取/读取文件的内容
*
* @param string $filename 文件路径
*
* @return string 文件的内容
*/
function read_file(string $filename) {
// 读取文件信息的前提, 是文件能找到, 并且可读
if (is_file($filename) && is_readable($filename)) {
// 如果能找到文件, 并且拥有读的权限, 则使用系统函数 file_get_contents()来获取文件信息, 并且返回
return file_get_contents($filename);
}
// 如果走到这一步, 说明没能返回文件的内容, 那么返回false
return false;
}
复制代码
读取文件中的内容到数组中
/**
* read_file_array 获取文件内容, 返回数组, 一行是一个元素
*
* @param string $filename 文件路径
* @param boolean $skip_empty_lines 是否跳过空行, 默认false, 不跳过
*
* @return array 文件内容, 一行是一个元素
*/
function read_file_array(string $filename, bool $skip_empty_lines = false) {
// 能够读取文件的前提: 存在文件, 并且该文件可读
if (is_file($filename) && is_readable($filename)) {
// 是否要跳过空行
if ($skip_empty_lines) {
// 如果跳过空行, 需要设置第二个参数, 需要同时设置两个
// FILE_IGNORE_NEW_LINES 在数组每个元素的末尾不要添加换行符
// FILE_SKIP_EMPTY_LINES 跳过空行
// 必须同时设置, 不设置FILE_IGNORE_NEW_LINES的话, 只有一个换行符也会当成一行, 因为不是空行
return file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
} else {
// 如果不跳过空行, 直接调用系统函数file(), 来返回文件内容的数组
return file($filename);
}
}
// 如果走到这一步, 说明没能返回文件的内容, 那么返回false
return false;
}
复制代码
向文件中写入内容
/**
* write_file 把变量写入文件中
*
* @param string $filename 文件路径
* @param mixed $data 需要写入文件的变量, 数据类型不限
*
* @return boolean 操作结果, 如果成功返回true, 失败返回false
*/
function write_file(string $filename, $data) {
// 获取文件的路径部分
$dirname = dirname($filename);
// 如果路径不存在, 则创建
if (!file_exists($dirname)) {
// 根据路径, 创建文件夹, 权限777, 递归创建
mkdir($dirname, 0777, true);
}
// 判断是否为数组或者对象, 如果是, 需要序列化成字符串, 因为不能直接写
if (is_array($data) || is_object($data)) {
// 序列化数组或者对象
$data = serialize($data);
}
// 如果能成功写入, 返回true
if (file_put_contents($filename, $data) !== false) {
// 代表能够写入
return true;
} else {
// 否则返回false
return false;
}
}
复制代码
向文件中写入内容,之前内容不清空
/**
* write_file1 写入文件, 可以选择是否保留原来的内容
*
* @param string $filename 文件路径
* @param mixed $data 要写入的变量, 数据类型不限
* @param bool $clearFlag 是否清除内容, true为清除, false为不清除(保留内容)
*
* @return boolean 操作结果, 如果成功返回true, 失败返回false
*/
function write_file1(string $filename, $data, bool $clearFlag = false) {
// 获取文件路径的目录部分
$dirname = dirname($filename);
// 如果目录不存在, 则创建
if (!file_exists($dirname)) {
// 权限777, 递归创建目录
mkdir($dirname, 0777, true);
}
// 如果文件存在, 并且可读, 就读取数据
if (is_file($filename) && is_readable($filename)) {
// 获取文件中的内容
$srcData = file_get_contents($filename);
}else{
// 否则内容为空字符串
$srcData = "";
}
// 如果变量是数组或者是对象, 则需要序列化, 不然写不到文件里去
if (is_array($data) || is_object($data)) {
// 序列换数组或者对象
$data = serialize($data);
}
// 如果不清除文件, 则采用拼接的方式
if(!$clearFlag){
// 把内容拼接到文件的最后, 类似于append
$data = $srcData . $data;
}
// 如果写入成功, 返回true, 否则返回false
if (file_put_contents($filename, $data) !== false) {
return true; // 成功
} else {
return false; // 失败
}
}
复制代码
截断文件到指定大小
/**
* truncate_file 将文件截断到给定的长度
*
* @param string $filename 文件路径
* @param int $length 截取长度, 可以是负数, 为变成0
*
* @return bool 操作结果, 如果成功返回true, 失败返回false
*/
function truncate_file(string $filename, int $length) {
// 如果是文件并且可写, 则进行操作, 否则返回false
if (is_file($filename) && is_writable($filename)) {
// 使用fopen获取文件句柄
$handle = fopen($filename, 'r+');
// 判断截断的长度, 如果为负数, 则改成0
$length = $length < 0 ? 0 : $length;
// 使用系统函数ftruncate进行截断
ftruncate($handle, $length);
// 关闭文件
fclose($handle);
// 返回成功
return true;
}
// 如果走到这一步, 说明操作失败, 返回false
return false;
}
复制代码
下载文件
function down_file(string $filename, array $allowDownExt = array('jpeg', 'jpg', 'png', 'gif', 'txt', 'html', 'php', 'rar', 'zip')) {
if (!is_file($filename) || !is_readable($filename)) {
return false;
}
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowDownExt)) {
return false;
}
header('Content-Type:application/octet-stream');
header('Accept-Ranges: bytes');
header('Accept-Length: ' . filesize($filename));
header('Content-Disposition: attachment;filename=king_' . basename($filename));
readfile($filename);
exit;
}
复制代码
下载文件
/**
* down_file 根据文件路径, 下载文件
*
* @param string $filename 文件路径
* @param array $allowDownExt 允许的后缀名
*
* @return void
*/
function down_file(string $filename, array $allowDownExt = array('jpeg', 'jpg', 'png', 'gif', 'txt', 'html', 'php', 'rar', 'zip')) {
// 判断文件是否存在, 并且可读, 因为我们需要往里写数据
if (!is_file($filename) || !is_readable($filename)) {
// 不可读, 或者不存在, 则报错
return false;
}
// 获取后缀名
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// 如果后缀名不符合要求, 则返回false, 不让下载
if (!in_array($ext, $allowDownExt)) {
return false;
}
//通过header()发送头信息
//告诉浏览器输出的是字节流
header('Content-Type:application/octet-stream');
//告诉浏览器返回的文件大小是按照字节进行计算的
header('Accept-Ranges: bytes');
// 获取文件大小
$filesize = filesize($filename);
//告诉浏览器返回的文件大小
header('Accept-Length: ' . $filesize);
//告诉浏览器文件作为附件处理,告诉浏览器最终下载完的文件名称
header('Content-Disposition: attachment;filename=king_' . basename($filename));
//读取文件中的内容
//规定每次读取文件的字节数为1024字节,直接输出数据
$read_buffer = 1024;
// 获取文件句柄
$handle = fopen($filename, 'rb');
// 循环读取, 直到文件结束
while (!feof($handle)) {
echo "hello";
// fread 系统函数, 文件句柄, 每次读取的大小
echo fread($handle, $read_buffer);
}
// 关闭句柄
fclose($handle);
// 退出
exit;
}
复制代码
单文件上传
/**
* upload_file 上传文件
* @param array $fileInfo 文件信息
* @param string $uploadPath 上传后, 文件保存的路径
* @param bool|boolean $imageFlag 是否检测为真实的图片
* @param array $allowExt 允许的后缀
* @param int|integer $maxSize 上传文件的最大值
* @return string|bool 如果成功, 返回保存的文件路径, 如果失败返回false
*/
function upload_file(array $fileInfo, string $uploadPath = './uploads', bool $imageFlag = true, array $allowExt = array('jpeg', 'jpg', 'png', 'gif'), int $maxSize = 2097152) {
// 定义常量, UPLOAD_ERRS, 上传错误信息, 是一个关联数组
define('UPLOAD_ERRS', [
'upload_max_filesize' => '超过了PHP配置文件中upload_max_filesize选项的值',
'form_max_size' => '超过了表单MAX_FILE_SIZE选项的值',
'upload_file_partial' => '文件部分被上传',
'no_upload_file_select' => '没有选择上传文件',
'upload_system_error' => '系统错误',
'no_allow_ext' => '非法文件类型',
'exceed_max_size' => '超出允许上传的最大值',
'not_true_image' => '文件不是真实图片',
'not_http_post' => '文件不是通过HTTP POST方式上传上来的',
'move_error' => '文件移动失败',
]);
// 上传成功没有错误的处理逻辑
if ($fileInfo['error'] === 0) {
// 获取文件后缀
$ext = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
// 判断后缀是否符合要求, 不符合, 输出信息"非法文件类型", 返回false
if (!in_array($ext, $allowExt)) {
echo UPLOAD_ERRS['no_allow_ext'];
return false;
}
// 如果文件大小过大, 输出信息"超出允许上传的最大值", 返回false
if ($fileInfo['size'] > $maxSize) {
echo UPLOAD_ERRS['exceed_max_size'];
return false;
}
// 如果需要检测图片是否为真是图片
if ($imageFlag) {
// 判断一下, 如果不是图片, 输出信息"文件不是真实图片", 返回false
// getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组
if (@!getimagesize($fileInfo['tmp_name'])) {
echo UPLOAD_ERRS['not_true_image'];
return false;
}
}
// 如果文件不是走的http post, 输出信息"文件不是通过HTTP POST方式上传上来的", 返回false
// is_uploaded_file() 函数检查指定的文件是否是通过 HTTP POST 上传的
if (!is_uploaded_file($fileInfo['tmp_name'])) {
return UPLOAD_ERRS['not_http_post'];
}
// 开始保存
// 上传文件的保存路径是否存在, 如果不存在, 则递归创建
if (!is_dir($uploadPath)) {
mkdir($uploadPath, 0777, true);
}
// 给文件起一个名字, 目的是为了排重
// microtime(true) 秒级时间戳.毫米级时间戳
// uniqid生成唯一id, 使用microtime作为前缀
// md5加密, 生成32位字符串
$uniName = md5(uniqid(microtime(true), true)) . '.' . $ext;
// 生成需要保存的完整文件名
$dest = $uploadPath . DIRECTORY_SEPARATOR . $uniName;
// move_uploaded_file 函数将上传的文件移动到新位置
if (@!move_uploaded_file($fileInfo['tmp_name'], $dest)) {
// 如果失败, 输出"文件移动失败""
echo UPLOAD_ERRS['move_error'];
return false;
}
// 如果没有问题, 输出 文件上传成功
echo '文件上传成功';
// 返回上传完以后的文件路径
return $dest;
} else {
// 判断具体上传失败时的错误, 返回中文信息
switch ($fileInfo['error']) {
case 1:
$mes = UPLOAD_ERRS['upload_max_filesize']; // 超过了PHP配置文件中upload_max_filesize选项的值
break;
case 2:
$mes = UPLOAD_ERRS['form_max_size']; // 超过了表单MAX_FILE_SIZE选项的值
break;
case 3:
$mes = UPLAOD_ERRS['upload_file_partial']; // 文件部分被上传
break;
case 4:
$mes = UPLOAD_ERRS['no_upload_file_select']; // 没有选择上传文件
break;
case 6:
case 7:
case 8:
$mes = UPLAOD_ERRS['upload_system_error']; // 系统错误
break;
}
// 错误信息
echo $mes;
// 返回false
return false;
}
}
复制代码
压缩单个文件
/**
* zip_file 压缩单个文件
*
* @param string $filename 文件路径
*
* @return bool true表示压缩成功, false表示压缩失败
*/
function zip_file(string $filename) {
// 判断文件是否存在, 没有则返回false
if (!is_file($filename)) {
return false;
}
// 实例化一个ZipArchive对象
$zip = new ZipArchive();
// 设置压缩文件的文件名, 原文件后面加zip, 类似于: hello.txt ==> hello.txt.zip
$zipName = basename($filename) . '.zip';
// 打开一个压缩文件, 开始往里写内容, 如果没有就创建, 如果有就覆盖
if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
// 往压缩包里添加文件, 把结果赋值给一个变量
$result = $zip->addFile($filename);
// 关闭压缩包
$zip->close();
// 如果变量为true, 说明添加成功, 删除原文件
if ($result) {
// 删除原文件
unlink($filename);
}
// 返回成功
return true;
} else {
// 返回失败
return false;
}
}
复制代码
多文件压缩
/**
* zip_files 多文件压缩
*
* @param string $zipName 自定义压缩文件名
* @param mixed $files 需要压缩的文件路径, 个数不限
*
* @return bool 成功返回true, 失败返回false
*/
function zip_files(string $zipName, ...$files) {
// 获取后缀名
$zipExt = strtolower(pathinfo($zipName, PATHINFO_EXTENSION));
// 如果后缀名不是zip, 返回false
if ('zip' !== $zipExt) {
return false;
}
// 实例化ZipArchive()对象
$zip = new ZipArchive();
// 打开一个压缩文件, 开始往里写内容, 如果没有就创建, 如果有就覆盖
if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
// 遍历文件, 要压缩的文件的路径
foreach ($files as $file) {
// 判断是否可以找到文件
if (is_file($file)) {
// 如果没有问题, 添加到压缩文件里
$zip->addFile($file);
}
}
// 关闭压缩文件
$zip->close();
// 返回 true
return true;
} else {
// 返回 false
return false;
}
}
复制代码
解压缩
/**
* unzip_file 解压缩文件到指定路径
*
* @param string $zipName 压缩包的文件路径
* @param string $dest 解压缩到指定路径
*
* @return bool 成功返回true, 失败返回false
*/
function unzip_file(string $zipName, string $dest) {
// 判断能否找到压缩文件, 如果找不到, 返回false
if (!is_file($zipName)) {
return false;
}
// 判断解压路径是否存在, 没有则创建
if (!is_dir($dest)) {
mkdir($dest, 0777, true);
}
// 实例化ZipArchive对象
$zip = new ZipArchive();
// 打开压缩文件, 解压到指定路径
if ($zip->open($zipName)) {
// 解压到路径
$zip->extractTo($dest);
// 关闭压缩文件
$zip->close();
// 返回true
return true;
} else {
// 返回false
return false;
}
}
复制代码
$_FILES详解
$_FILES参数详解:
$_FILES["file"]["name"]–被上传文件的名称
$_FILES["file"]["type"]–被上传文件的类型
$_FILES["file"]["size"]–被上传文件的大小, 以字节计
$_FILES["file"]["tmp_name"]–存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"]–由文件上传导致的错误代码
$_FILES["file"]["error"]中的["error"]值情况
UPLOAD_ERR_OK
0: 没有错误发生, 文件上传成功
UPLOAD_ERR_INI_SIZE
1: 上传的文件超过了php.ini中upload_max_filesize(默认情况为2M)选项限制的值
UPLOAD_ERR_FORM_SIZE
2: 上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值
UPLOAD_ERR_PARTIAL
3: 文件只有部分被上传
UPLOAD_ERR_NO_FILE
4: 没有文件被上传
5: 传文件大小为 0