04-php之文件

https://www.runoob.com/php/php-file-upload.html

1 PHP 操作文件

PHP常见的文件操作:创建文件、读取文件、上传文件、编辑文件

请谨慎操作文件

常见的文件操作错误:

  • 编辑错误的文件

  • 被垃圾数据填满硬盘

  • 意外删除文件内容

1.1 readfile() 函数

readfile() 函数读取文件,并把它写入输出缓冲

image

1.2 打开文件 fopen()

<?php
/*
fopen() : 第一个参数包含被打开的文件名,
           第二个参数规定打开文件的模式
*/    

$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("webdictionary.txt"));

// 关闭文件
fclose($myfile);

image

1.3 读取文件 - fread() 读取打开的文件

fread() 的第一个参数包含待读取文件的文件名,第二个参数规定待读取的最大字节数

1.4 闭文件 - fclose()用于关闭打开的文件

用完文件后把它们全部关闭是一个良好的编程习惯

fclose() 需要待关闭文件的名称(或者存有文件名的变量)

<?php
$myfile = fopen("webdictionary.txt", "r");
// some code to be executed....
fclose($myfile);

1.5 读取单行文件 - fgets()用于从文件读取单行

调用 fgets() 函数之后,文件指针会移动到下一行

<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fgets($myfile);
fclose($myfile);
?>

1.6 检查 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);
?>

1.7 读取单字符 - 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);
?>

1.8 创建文件 - fopen()

  • fopen() 函数也用于创建文件
  • 也许有点混乱,但是在 PHP 中,创建文件所用的函数与打开文件的相同。
  • 如果您用 fopen() 打开并不存在的文件,此函数会创建文件,假定文件被打开为写入(w)或增加(a)。
  • 如果您试图运行这段代码时发生错误,请检查您是否有向硬盘写入信息的 PHP 文件访问权限
$myfile = fopen("testfile.txt", "w")

1.9 写入文件 - 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 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;
}

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