Go to comments

PHP100 上传文件

一、知识点

1. form 标签的 enctype 属性值

默认情况的编码格式是 application/x-www-form-urlencoded,不能用于文件上传

<form action="" enctype="multipart/form-data" method="post" name="upform">
  上传文件:
  <input name="upfile" type="file">
  <input type="submit" name="sub" value="上传">
</form>


因为上传文件的时候是二进制编码,必须的要使用 enctype="multipart/form-data" 的编码格式,才能完整的传递文件数据

意思将表单内容设置成 MIME 编码,它是一种二进制的编码


input 要使用 type="file" 文件类型


2. $_FILES 系统函数

$_FILES 函数接收上传文件的内容,将上传的内容转为我们所需的数组,

它类似于 $_POST 和 $_GET 函数,都是接收表单传递过来的内容,区别 $_FILES 是将表单上传的内容转换成一个数组


几个重要的键值

$_FILES['upfile']['name']  客户端上传文件的名称(原名)

$_FILES['upfile']['type']    文件MIME类型,可以从服务器端严格的限制文件类型

$_FILES['upfile']['size']     当前上传文件的大小,单位是字节。可以限制上传的文件大小

$_FILES['upfile']['tmp_name']  储存的临时文件名,一般是系统默认。后面将临时文件移动到我们所需要的位置

$_FILES['upfile']['error']  当前上传文件相关错误代码


通过 MIME 限制上传的文件类型

image/jpg

image/jpeg

image/png

image/pjpeg

image/gif

image/bmp

image/x-png

application/x-zip-compressed

...


$_FILES['upfile']['error'] 的错误信息

0 文件上传成功

1 超过系统限制的文件大小,可以在php.ini文件中配置

2 超过了文件大小,MAX_FILE_SIZE 选项指定的值

3 文件只有部分被上传

4 没有文件被上传,没有上传成功返回4

5 上传文件大小为0,比如上传文件本身就 0k 返回为5


3. move_uploaded_file(临时文件, 目标位置和文件名)

上传后,文件放在服务器的临时文件夹中,该函数把文件移动到我们需要的位置,移动的文件可以重命名


4. is_uploaded_file 函数

判断上传 MIME 类型的文件函数,判断上传的文件是否成功了


二、示例

主要的就三步

1. from表单元素的 enctype属性设置为 enctype="multipart/form-data"

    input框为上传类型 type="file",要设置 name 属性

2. $_FILES['upfile'] 接收表单内容是一个数组,upfile是上面name属性的值,

    其实到这已经上传成功了,只是上传的文件在临时文件夹中 $_FILES['upfile']['tmp_name']

3. move_uploaded_file(临时文件, 目标位置和文件名) 把在临时文件夹中的上传文件,移动到响应的位置


课程代码

<?php

if(is_uploaded_file($_FILES['upfile']['tmp_name'])){ // 首先判断上传的临时文件是否成功了

  $upfile = $_FILES["upfile"]; // 获取的是一个数组,upfile是input框name的值
  $name = $upfile["name"];
  $type = $upfile["type"];
  $size = $upfile["size"]; // 大小的单位是字节,1024进位,比如105542有150k左右
  $tmp_name = $upfile["tmp_name"]; // 这个时候文件已经上传成功了,只是放在了临时文件夹中
  $error = $upfile["error"];

  switch($type){
    case 'image/pjpeg' : $ok=1;
      break;
    case 'image/jpeg' : $ok=1;
      break;
    case 'image/gif' : $ok=1;
      break;
    case 'image/png' : $ok=1;
      break;
  }

  if($ok && $error=='0'){
    move_uploaded_file($tmp_name, 'uploads/'.$name); // 把上传的文件移动到我们需要的位置
    echo "上传成功";
  }
}

?>

<form action="" enctype="multipart/form-data" method="post" name="upform">
  上传文件:
  <input name="upfile" type="file">
  <input type="submit" value="上传"><br>
</form>


自己练习写一个函数,需要在PHP文件同级目录,建一个 uploads 文件夹

<?php
// error_reporting(E_ALL & ~E_NOTICE);

$_POST['sub'] = isset($_POST['sub'])? $_POST['sub'] : null;

if($_POST['sub']){

  $result = up_file('uploads', 'upfile');

  if($result){
    echo '上传成功';
  }else if($result == 0){
    echo '没有选择上传的文件';
  }
}

function up_file($load = 'uploads', $fileName = 'file'){

  $up = $_FILES[$fileName];
  $name = $up["name"];
  $type = $up["type"];
  $size = $up["size"];
  $tmp_name = $up["tmp_name"];
  $error = $up["error"];

  if(!is_uploaded_file($tmp_name)){
    return 0; // 没有上传文件
    exit;
  }

  if(move_uploaded_file($tmp_name, './'. $load. '/img' .time().'.jpg')){
    return true;
  }
}

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>

<form enctype="multipart/form-data" action="" method="post">
  <input type="file" name="upfile">
  <input type="submit" name="sub" value="上传">
</form> 

</body>
</html>


PHP100课程文件包中的代码,功能比较完善,注释风格清晰

<?php
  /************************************************************

  参数说明:
  $max_file_size  : 上传文件大小限制, 单位BYTE
  $destination_folder : 上传文件路径
  $watermark   : 是否附加水印(1为加水印,其他为不加水印);

  使用说明:
  1. 将PHP.INI文件里面的"extension=php_gd2.dll"一行前面的;号去掉,因为我们要用到GD库;
  2. 将extension_dir =改为你的php_gd2.dll所在目录;
  ************************************************************/

  //上传文件类型列表
  $uptypes=array(
    'image/jpg',
    'image/jpeg',
    'image/png',
    'image/pjpeg',
    'image/gif',
    'image/bmp',
    'image/x-png'
  );

  $max_file_size=2000000;     //上传文件大小限制, 单位BYTE
  $destination_folder="uploadimg/"; //上传文件路径
  $watermark=1;      //是否附加水印(1为加水印,其他为不加水印);
  $watertype=1;      //水印类型(1为文字,2为图片)
  $waterposition=1;     //水印位置(1为左下角,2为右下角,3为左上角,4为右上角,5为居中);
  $waterstring="http://www.xplore.cn/";  //水印字符串
  $waterimg="xplore.gif";    //水印图片
  $imgpreview=1;      //是否生成预览图(1为生成,其他为不生成);
  $imgpreviewsize=1/2;    //缩略图比例
?>

<html>
<head>
<title>ZwelL图片上传程序</title>
<style>
body{font-size: 9pt;}
input{background-color: #66CCFF;border: 1px inset #CCCCCC;}
</style>
</head>
<body>

<form enctype="multipart/form-data" method="post" name="upform">
  上传文件:
  <input name="upfile" type="file">
  <input type="submit" value="上传"><br>
  允许上传的文件类型为:<?=implode(', ',$uptypes)?>
</form>

<?php

  if($_SERVER['REQUEST_METHOD'] == 'POST'){
    //是否存在文件
    if (!is_uploaded_file($_FILES["upfile"][tmp_name])){
      echo "图片不存在!";
      exit;
    }

    $file = $_FILES["upfile"];
    
    //检查文件大小
    if($max_file_size < $file["size"]){
      echo "文件太大!";
      exit;
    }

    //检查文件类型
    if(!in_array($file["type"], $uptypes)){
      echo "文件类型不符!".$file["type"];
      exit;
    }

    if(!file_exists($destination_folder)){
      mkdir($destination_folder);
    }

    $filename=$file["tmp_name"];
    $image_size = getimagesize($filename);
    $pinfo=pathinfo($file["name"]);
    $ftype=$pinfo['extension'];
    $destination = $destination_folder.time().".".$ftype;
    if (file_exists($destination) && $overwrite != true){
      echo "同名文件已经存在了";
      exit;
    }

    if(!move_uploaded_file ($filename, $destination)){
      echo "移动文件出错";
      exit;
    }

    $pinfo=pathinfo($destination);
    $fname=$pinfo[basename];
    echo " <font color=red>已经成功上传</font><br>文件名:  <font color=blue>".$destination_folder.$fname."</font><br>";
    echo " 宽度:".$image_size[0];
    echo " 长度:".$image_size[1];
    echo "<br> 大小:".$file["size"]." bytes";

    if($watermark==1){
      $iinfo=getimagesize($destination,$iinfo);
      $nimage=imagecreatetruecolor($image_size[0],$image_size[1]);
      $white=imagecolorallocate($nimage,255,255,255);
      $black=imagecolorallocate($nimage,0,0,0);
      $red=imagecolorallocate($nimage,255,0,0);
      imagefill($nimage,0,0,$white);
      switch ($iinfo[2]){
        case 1:
        $simage =imagecreatefromgif($destination);
        break;
        case 2:
        $simage =imagecreatefromjpeg($destination);
        break;
        case 3:
        $simage =imagecreatefrompng($destination);
        break;
        case 6:
        $simage =imagecreatefromwbmp($destination);
        break;
        default:
        die("不支持的文件类型");
        exit;
      }

      imagecopy($nimage,$simage,0,0,0,0,$image_size[0],$image_size[1]);
      imagefilledrectangle($nimage,1,$image_size[1]-15,80,$image_size[1],$white);

      switch($watertype){
        case 1:   //加水印字符串
        imagestring($nimage,2,3,$image_size[1]-15,$waterstring,$black);
        break;
        case 2:   //加水印图片
        $simage1 =imagecreatefromgif("xplore.gif");
        imagecopy($nimage,$simage1,0,0,0,0,85,15);
        imagedestroy($simage1);
        break;
      }

      switch ($iinfo[2]){
        case 1:
        //imagegif($nimage, $destination);
        imagejpeg($nimage, $destination);
        break;
        case 2:
        imagejpeg($nimage, $destination);
        break;
        case 3:
        imagepng($nimage, $destination);
        break;
        case 6:
        imagewbmp($nimage, $destination);
        //imagejpeg($nimage, $destination);
        break;
      }

      //覆盖原上传文件
      imagedestroy($nimage);
      imagedestroy($simage);
    }

    if($imgpreview==1){
      echo "<br>图片预览:<br>";
      echo "<img src=\"".$destination."\" width=".($image_size[0]*$imgpreviewsize)." height=".($image_size[1]*$imgpreviewsize);
      echo " alt=\"图片预览:\r文件名:".$destination."\r上传时间:\">";
    }
  }

?>

</body>


三、上传接口

配合前端学习,写了一个ajax 上传文件的接口

<?php
error_reporting(E_ALL & ~E_NOTICE);
// error_reporting(0);

header("Access-Control-Allow-Origin: http://127.0.0.1:8848");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: content-type, a");

// 限制上传体积
if ($_SERVER['CONTENT_LENGTH'] > 1024*1024){
  echo '{"code":1, "msg":"上传文件大小超过限制", "data":null }';
  exit();
}

$upfile = $_FILES["upfile"]; 
$name = $upfile["name"];
$type = $upfile["type"];
$size = $upfile["size"];
$tmp_name = $upfile["tmp_name"];
$error = $upfile["error"];

if($tmp_name){

  // 上传失败
  if ($error != 0){
    echo '{"code":1, "msg":"上传文件失败", "data":null }';
    exit();
  }

  // 限制上传文件必须是图片
  $typeArr = ['image/pjpeg', 'image/jpeg','image/gif','image/png'];
  if(!in_array($type, $typeArr)){
    echo '{"code":1, "msg":"上传文件不是图片格式", "data":null }';
    exit();
  }

  // 上传图片重命名
  $Suffix = explode('/', $type)[1];
  $Suffix = $Suffix == 'jpeg'? 'jpg': $Suffix;
  $pathname = 'uploads/pic_'.mt_rand(1000, 100000).'_'.time().'.'.$Suffix;

  // 移动文件到指定位置,并返回响应结果
  if(move_uploaded_file($tmp_name, $pathname)){
    $result = 'http://localhost/mycode/ajax_upload/'.$pathname;
    echo '{"code":0, "msg":"", "data": {"path": "'.$result.'"}}';
  }
}

// echo $_SERVER['PHP_SELF'];
// Array ( [name] => 1995年Cosplay.jfif [type] => image/jpeg [tmp_name] => D:\xampp\tmp\phpF267.tmp [error] => 0 [size] => 32768 ) {"path": "http://localhost/mycode/uploads/1995年Cosplay.jfif"}
?>



Leave a comment 0 Comments.

Leave a Reply

换一张