04 php文件编程
https://www.runoob.com/php/php-file-upload.html
文件编程:利用php代码对文件(文件夹)进行增删改查的相关操作
1. 目录操作
1.1 创建目录mkdir()
mkDir(路径名称):创建成功返回true,创建失败返回false
// 创建一个名为test的文件夹(目录)
$res=mkdir('test');
echo $res;
1.2 删除目录rmdir()
// 创建一个名为test的文件夹(目录)
$res=rmdir('test');
echo $res;
在创建或删除目录的时候,会出现创建同名目录或删除不存在目录的情况,此时就会报错,为了这种不很友好的报错,我们可以使用@来抑制错误: @mkdir('test')和@rmdir('test')
1.3 读取目录
读取方式:将文件夹(目录)按照资源方式打开
opendir()
打开资源,返回一个路径资源,返回指定目录下的所有文件(文件夹)
readdir()
从资源中读取指针所在位置的文件名字,然后指针下移,知道指针移出资源
<?php
// 获取资源
$re=opendir('file');
echo $re.'</br>';
// 读取资源
echo readdir($re).'</br>'; // .当前目录
echo readdir($re).'</br>'; // .上一级目录
echo readdir($re).'</br>';
echo readdir($re).'</br>';
// 循环遍历获取所有的文件和文件夹
while($file=readdir(($re))){
echo $file.'</br>';
}
遍历目录:将指定目录下的所有文件和目录、一级目录下的所有文件都读取出来
<?php
/*
* 遍历目录:将指定目录下的所有文件和目录、一级目录下的所有文件都读取出来
* @params1 string $dir 指定路径
* @params2 int $level 层级,默认是0 主要用于缩进
* */
function readDir_func($dir,$level=0)
{
// 是否是目录
if (!is_dir($dir)) {
die($dir . '不是一个目录文件夹');
}
// 读取全部路径信息,遍历输出
$files = scandir($dir);
// 遍历输出
foreach ($files as $file) {
// $file是一个文件名 str_repeat可以缩进
echo str_repeat(' ',$level), $file. '</br>';
// 排除 . 和 ..
if ($file == '.' || $file == '..') continue;
// 构造新的路径
$file_dir = $dir . '/' . $file;
// echo $file_dir. '</br>';
if (is_dir($file_dir)) {
readDir_func($file_dir,$level+1);
}
}
}
// 读取文件和文件夹
readDir_func('./file');
1.4 关闭目录closedir()
1.5 其他目录相关
dirname:输出当前文件所处目录位置
echo dirname('F:/mylpj/phpdemo/curl/dir.php');
// 输出:F:/mylpj/phpdemo/curl
is_dir(路径):判定指定的路径是否是一个目录
2. 文件操作
2.1 PHP5常见文件操作函数
file_get_contents(文件路径):获取指定文件的内容,返回字符串
$tr = file_get_contents('welcome.txt');
echo $tr;
file_put_contents(文件路径,内容):将指定内容写入到指定文件中
如果文件路径下制定的文件不存在,会自动创建
<?php
// 如果写入成功,返回的是写入内容的长度(字节)
$res = file_put_contents('welcome.txt', '');
echo $res;
2.2 PHP4常见文件操作函数
php4中的操作主要是将文件用资源的方式处理的
2.2.1 fopen():打开文件
如果指定的文件不存在,会自动创建该文件
<?php
/*
fopen() : 第一个参数包含被打开的文件名,
第二个参数规定打开文件的模式
*/
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("webdictionary.txt"));
// 关闭文件
fclose($myfile);
2.2.2 fread():读取打开的文件
fread() 的第一个参数包含待读取文件的文件名,第二个参数规定待读取的最大字节数
2.2.3 fwrite():将内容写入指定的文件
fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串
<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Bill Gates\n";
fwrite($myfile, $txt); //第一次写入
$txt = "Steve Jobs\n";
fwrite($myfile, $txt); //第二次写入
fclose($myfile);
输出结果:
Bill Gates
Steve Jobs
2.2.4 fclose()
用完文件后把它们全部关闭是一个良好的编程习惯
fclose() 需要待关闭文件的名称(或者存有文件名的变量)
<?php
$myfile = fopen("webdictionary.txt", "r");
// some code to be executed....
fclose($myfile);
3. 其他文件操作
3.1 readfile()
函数
readfile() 函数读取文件,并把它写入输出缓冲
3.2 读取单行文件 - fgets()用于从文件读取单行
调用 fgets() 函数之后,文件指针会移动到下一行
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fgets($myfile);
fclose($myfile);
?>
3.3 检查 End-Of-File - feof() 检查是否已到达 "end-of-file" (EOF)
feof() 对于遍历未知长度的数据很有用
逐行读取 "webdictionary.txt" 文件,直到 end-of-file
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
// 输出单行直到 end-of-file
while(!feof($myfile)) {
echo fgets($myfile) . "<br>";
}
fclose($myfile);
?>
3.4 读取单字符 - fgetc() 用于从文件中读取单个字符
在调用 fgetc() 函数之后,文件指针会移动到下一个字符
逐字符读取 "webdictionary.txt" 文件,直到 end-of-file
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
// 输出单字符直到 end-of-file
while(!feof($myfile)) {
echo fgetc($myfile);
}
fclose($myfile);
?>
3.5 is_file():判断是否是文件,不识别路径
3.6 file_exists():判断文件是否存在,识别路径
3.7 filesize():获取文件大小
3.8 unlink():取消文件名与磁盘地址的链接
3.9 filemtime():获取文件最后一次修改的时间
3.10 fseek():设定fopen打开的文件的指针位置
3.11 file():读取整个文件,类似file_get_contents(),区别在于是返回一个数组,一行就是一个元素
2 PHP 文件上传
通过 PHP,可以把文件上传到服务器上指定的目录下
2.1 文件上传的原理
1、 创建文件上传表单:浏览器请求一个包含文件上传表单的服务器的html脚本
2、用户从本地选择一个文件上传
3、用户点击上传:文件会通过网络传输到服务器上
4、服务器操作系统会将文件保存到临时目录:一般是window的tmp目录里面
5、服务器脚本开始工作:判断文件的有效性
6、服务器脚本将有效文件从临时目录里面移动到指定目录下
2.2 文件上传
2.2.1 创建一个文件上传表单
<html>
<head>
<meta charset="utf-8" />
<title>文件上传表单</title>
</head>
<body>
<!--
method:表单提交的方式,必须是post
enctype 属性规定了在提交表单时要使用哪种内容类型。
在表单需要二进制数据时,比如文件内容,一般是使用 "multipart/form-data"-->
<form action="uploadFile.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file" /><br />
<input type="submit" name="submit" value="提交" />
</form>
</body>
</html>
2.2.2 创建上传脚本
将临时文件保存到指定目录
<?php
/**
* $_FILES返回的对象:name属性的数组:$_FILES['file']
* size:文件大小
* type:文件类型
* error:错误结果类型 int 为0表示上传成功
* tmp_name:文件临时存储目录
* name:本机电脑目录下的文件名
*/
// 获取上传的文件结果数据
$file=$_FILES['image'];
// is_uploaded_file:检查指定的文件是否是通过 HTTP POST 上传的的文件
if(is_uploaded_file($file['tmp_name'])){
// 允许上传的图片后缀
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $file["name"]);
$extension = end($temp); // 获取文件后缀名
$type=$file['type']; // 文件类型
if ((($type == "image/gif")
//限制文件上传的文件格式
|| ($type == "image/jpeg")
|| ($type == "image/jpg")
|| ($type == "image/pjpeg")
|| ($type == "image/x-png")
|| ($type == "image/png"))
//限制上传文件的大小
&& ($file["size"] < 204800) // 小于 200 kb
&& in_array($extension, $allowedExts)
) {
if ($file["error"] > 0) {
echo "错误:: " . $file["error"] . "<br>";
} else {
echo "上传文件名: " . $file["name"] . "<br>";
echo "文件类型: " . $file["type"] . "<br>";
echo "文件大小: " . ($file["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $file["tmp_name"] . "<br>";
// 文件上传的目录
$result_upload="D:\\xampp\\tmp\\upload\\";
// 判断当前目录下是否存在同名文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists($result_upload . $file["name"])) {
echo $file["name"] . " 同名文件已经存在。 ";
} else {
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
// move_uploaded_file将文件从临时目录保存在指定服务器目录:必须有文件名
move_uploaded_file($file["tmp_name"], $result_upload . $file["name"]);
echo "文件上传成功,目录是: " . $result_upload .$file["name"];
}
}
} else {
echo "非法的文件格式";
}
}else{
echo '不是上传文件';
}
$_FILES变量:接收上传的文件
$_FILES返回的文件对象:name属性的数组:$_FILES['file']-file是上传表单的name属性名称
size:文件大小
type:文件类型
error:错误结果类型 int 为0表示上传成功
tmp_name:文件临时存储目录
name:本机电脑目录下的文件名
文件上传错误类型 error
1、UPLOAD_ERR_OK
其值为 0,没有错误发生,文件上传成功
2、UPLOAD_ERR_INI_SIZE
其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize选项限制的值
3、UPLOAD_ERR_FORM_SIZE
其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值
4、UPLOAD_ERR_PARTIAL
其值为 3,文件只有部分被上传。
5、UPLOAD_ERR_NO_FILE
其值为 4,没有文件被上传。
6、UPLOAD_ERR_NO_TMP_DIR
其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
7、UPLOAD_ERR_CANT_WRITE
其值为 7,文件写入失败。PHP 5.1.0 引进
2.3 多文件上传
1、 当商品需要上传多个图片进行展示的时候:针对的是同一个内容,但是不同的文件说明,使用同名表单
上传表单:
上传表单:
2、 当商品需要多个不同的维度展示图片的时候:针对的是不同的内容,就是批量上传不同的图片
上传表单:
结果:
单文件上传函数的封装
<?php
/**
* 实现单文件上传功能
* @param1 array $file 文件信息:一维数组:name、type、size、type_name、error
* @param2 array $arrow_type 允许上传的MIME文件类型
* @param3 string $path 上传成功后存储的路径
* @param4 string &$error 错误信息
* @param5 array $arrow_format=array() 允许上传的文件格式:文件后缀名
* @param6 int $max_size=200000,允许上传文件的最大值,默认是2M
*/
function upload_single_file($file, $path, &$error, $arrow_format = array('png', 'jpg', 'gif', 'peg'), $max_size = 2000000, $arrow_type = array('image/jpeg', 'image/jpg', 'image/png', 'image/x-png', 'image/gif'))
{
var_dump($file);
echo '<br/>';
if (!is_array($file) || !isset($file['error'])) {
$error = '不是一个有效的文件';
return false;
}
// 判断文件存储路径是否有效
if (!is_dir($path)) {
// 路径不存在
$error = '存储路径有误!' . $path;
return false;
}
// 判断文件上传过程中是否出错
switch ($file['error']) {
case 1:
case 2:
$error = "文件超出服务器大小";
return false;
case 3:
$error = '文件上传过程中出现问题,只上传一部分';
return false;
case 4:
$error = '用户没有选择要上传的文件,空文件';
return false;
case 6:
case 7:
$error = '服务器出错,文件保存失败';
return false;
}
// 判断文件类型
if (!in_array($file['type'], $arrow_type)) {
$error = '文件类型报错,请上传指定的文件类型:' . implode(',', $arrow_type);
return false;
}
// 判断文件后缀
// 获取文件后缀名
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!empty($arrow_format) && !in_array($extension, $arrow_format)) {
$error = '文件格式不允许上传:' . implode(',', $arrow_format);
return false;
}
// 判断文件大小
if ($file['size'] > $max_size) {
$error = '当前文件过大,最大允许:' . $max_size;
return false;
}
// 判断是否是上传文件
if (!is_uploaded_file($file['tmp_name'])) {
$error = '错误:不是上传文件';
return false;
}
// 保存到指定目录
$newDir = $path . '\\' . date('Ymd') . '\\';
if (!is_dir($newDir)) {
// 如果目录不存在,创建一个当前日期目录
if (!mkdir($newDir, 0755, true)) {
$error = '无法创建目录';
return false;
}
}
// 构建文件名:年月日\随机字符串.后缀名
$filename = generateRandomNumber() . '.' . $extension;
if (move_uploaded_file($file['tmp_name'], $newDir . $filename)) {
$error = '文件上传成功';
return $path . $filename;
} else {
$error = '文件上传失败';
return false;
}
}
// 生成10位随机数字:用来给上传的文件重命名
function generateRandomNumber($digits = 10): int
{
return mt_rand(pow(10, $digits - 1), pow(10, $digits) - 1);
}
// 调用函数:上传文件到:D:\\xampp\\tmp\\upload\\
if ($filename = upload_single_file($_FILES['image'], 'D:\\xampp\\tmp\\upload\\', $error)) {
echo $filename;
} else {
echo $error;
}
5 文件下载
文件下载:从服务器将文件通过HTTP协议传输到浏览器,浏览器不解析,保存成相应的文件
php下载的流程:
读取文件内容,以文件流的方式传递给浏览器,然后再响应头中告知浏览器不要解析,激活下载框实现下载
<?php
// 1. 指定浏览器解析字符集
header('Content-type:text/html;charset=utf-8');
$file = 'welcome.txt';
// 2. 设置响应头
// 2.1 设定文件返回类型:image/jpg application/octem-stream
// 2.2 设定返回文件的计算方式:Accept-ranges:bytes
// 2.3 设定下载提示:Content-disposition:attachment;filename='文件名'
// 2.4 设定文件大小:Accept-length
header('Content-type:application/octem-stream'); // 以文件流的形式传输数据给浏览器
header('Accept-ranges:bytes');
header('Content-disposition:attachment;filename=' . $file . ''); // 附件下载,指定命名
// 如果文件名是从文件夹读取出来的,而且存在中文的时候,会出现乱码,此时需要对文件名进行字符集的转码 intdiv('GBK', 'UTF-8', $file)
header('Accept-length:' . filesize($file) . '');
// 3. 输出文件
// 3.1 如果文件大小很小,可以使用php5的file_get_contents()获取文件 echo file_get_contents($file);
// 3.2 如果文件大小很大(或者网络不好),可以使用php4的操作方式:不一次性全部读取数据
// @fopen错误抑制符
$f = @fopen($file, 'r') or die();
// 4. 读取文件
while (!feof($f)) {
echo fread($f, 1024);
}
// 5. 关闭文件
fclose($f);