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('&nbsp;&nbsp;',$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);

image

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() 函数读取文件,并把它写入输出缓冲

image

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);

posted @ 2023-10-09 18:18  songxia777  阅读(9)  评论(0编辑  收藏  举报