ホームページ > バックエンド開発 > PHPチュートリアル > ファイルのアップロードとダウンロードの PHP 実装の例_php の例

ファイルのアップロードとダウンロードの PHP 実装の例_php の例

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2023-03-03 06:04:01
オリジナル
1103 人が閲覧しました

この記事では、PHP でファイルのアップロードとダウンロードを実装する方法を紹介しますので、参考にしてください。編集者をフォローして見てみましょう。

1. アップロードの原理と構成

1.1原則

クライアントファイルをサーバーにアップロードし、サーバーファイル(一時ファイル)を指定されたディレクトリに移動します。

1.2 クライアント設定

必須: フォームページ (アップロードファイルを選択);

具体的には、送信方法はPOST、enctype="multipart/form-data"属性を追加、どちらも必須です(ただし、メリットとデメリットが混在しており、ここではアップロード方法やアップロード後の呼び出しなども制限されています)。 、後述します)


リーリー
1 つ目はフォーム ページ (フロントエンドの問題は自動的に無視してください...)、もう 1 つは入力での type="file" の使用です (強力な拡張を反映しています)。 PHPなど)。

その後、アクションを実行します


リーリー
まずはprint_r($_FILES)の情報を見てみましょう


リーリー
得られるのは 2 次元配列です。その使用方法はすべて基本的なものです (実際には、次元を削減してから使用するのが好きです)。

基本的には冗長ではありません。 tmp_name エラー エラー メッセージ (コード名。後で使用できます)。

次に、エラー情報を使用してユーザーにフィードバックする doAction の最後の部分を見てみましょう。説明する必要があるのは、エラーが報告される理由とエラー情報の内容です。

1.3 エラー報告について

--エラーの理由:

基本的に、ファイルをアップロードするためのサーバーの構成を超えているか、準拠していません。では、サーバー側の構成は何ですか? まず、私たちが使用したものをアップロードすることを検討してください?投稿、アップロード

それでは、php.ini で次のいくつかの項目を探してください:

ファイルアップロード:オン

upload_tmp_dir=——一時ファイル保存ディレクトリ

upload_max_filesize=2M

max_file_uploads=20 - 一度にアップロードできるファイルの最大数 (上記との違いに注意してください。サイズがあるかどうかは考慮しないでください)

post_max_size=8M——post メソッドで送信されるデータの最大サイズ

その他の関連構成

max_exectuion_time=-1—プログラムがサーバー リソースを占有しないようにするための最大実行時間。 max_input_time=60

max_input_nesting_level=64—入力ネストの深さ

memory_limit=128M——単一スレッドの最大独立メモリ使用量

要するに、すべてはリソースの割り当てに関するものです。

--エラー番号

以下の(怠惰な)引用は http://blog.sina.com.cn/s/blog_3cdfaea201008utf.html からです

UPLOAD_ERR_OK 値: 0; エラーは発生せず、ファイルは正常にアップロードされました。

UPLOAD_ERR_INI_SIZE 値: 1; アップロードされたファイルは、php.ini の Upload_max_filesize オプションの制限を超えています。

    UPLOAD_ERR_FORM_SIZE 値: 2; アップロードされたファイルのサイズが、HTML フォームの MAX_FILE_SIZE オプションで指定された値を超えています。
  • UPLOAD_ERR_PARTIAL 値: 3; ファイルの一部のみがアップロードされました。
  • UPLOAD_ERR_NO_FILE 値: 4; ファイルはアップロードされませんでした。
  • 注: このエラー メッセージは、最初の手順、つまり一時フォルダーにアップロードするときにアップロードされる情報であり、移動またはコピーするときではありません。
  • 2. アップロード関連の制限

2.1 クライアントの制限

リーリー

アップロードしたいファイルを選択してください:

リーリー

ここでは、アップロードされるファイルのサイズとタイプを制限するために input 属性が使用されていますが、私の個人的な感覚では、第一に HTML コードが「表示」され、第二に、機能しないことがよくあります (理由は見つかりませんでした)。しかし、最初のもののせいで、私もそれをあきらめて、ただ知りたいと思っています。
2.2 サーバー側の制限事項

主な制限はサイズと種類で、もう 1 つは方法です。

リーリー

2.3 梱包


機能

リーリー

電話する


リーリー

3. 複数ファイルのアップロードの実装

3.1 単一ファイルのパッケージ化を利用する

リーリー

ここでのアイデアは、print_r($_FILES) からそれを見つけることです。これを印刷すると、それをトラバースして使用するだけです。


上記の関数の定義を変更し、いくつかのデフォルト値を与えます

リーリー

このように、シンプルはシンプルですが、いくつか問題があります。


通常4枚の写真をアップロードする場合は問題ありませんが、途中で機能の終了が有効になるとすぐに停止してしまい、他の写真をアップロードできなくなります。

3.2アップグレード版パッケージ

複数または単一のファイルアップロードのためのカプセル化の実装を目的としています

まずこのような静的ファイルを作成します

リーリー

$_FILES を印刷


リーリー

可以得到一个三维数组。

复杂是复杂了,但复杂的有规律,各项数值都在一起了,很方便我们取值!!

所以先得到文件信息,变成单文件处理那种信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

function getFiles(){

  $i=0;

  foreach($_FILES as $file){

    if(is_string($file['name'])){ //单文件判定

      $files[$i]=$file;

      $i++;

    }elseif(is_array($file['name'])){

      foreach($file['name'] as $key=>$val){ //我的天,这个$key用的diao

        $files[$i]['name']=$file['name'][$key];

        $files[$i]['type']=$file['type'][$key];

        $files[$i]['tmp_name']=$file['tmp_name'][$key];

        $files[$i]['error']=$file['error'][$key];

        $files[$i]['size']=$file['size'][$key];

        $i++;

      }

    }

  }

  return $files;

   

}

ログイン後にコピー

然后之前的那种exit错误,就把exit改一下就好了,这里用res

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

function uploadFile($fileInfo,$path='./uploads',$flag=true,$maxSize=1048576,$allowExt=array('jpeg','jpg','png','gif')){

  //$flag=true;

  //$allowExt=array('jpeg','jpg','gif','png');

  //$maxSize=1048576;//1M

  //判断错误号

  $res=array();

  if($fileInfo['error']===UPLOAD_ERR_OK){

    //检测上传得到小

    if($fileInfo['size']>$maxSize){

      $res['mes']=$fileInfo['name'].'上传文件过大';

    }

    $ext=getExt($fileInfo['name']);

    //检测上传文件的文件类型

    if(!in_array($ext,$allowExt)){

      $res['mes']=$fileInfo['name'].'非法文件类型';

    }

    //检测是否是真实的图片类型

    if($flag){

      if(!getimagesize($fileInfo['tmp_name'])){

        $res['mes']=$fileInfo['name'].'不是真实图片类型';

      }

    }

    //检测文件是否是通过HTTP POST上传上来的

    if(!is_uploaded_file($fileInfo['tmp_name'])){

      $res['mes']=$fileInfo['name'].'文件不是通过HTTP POST方式上传上来的';

    }

    if($res) return $res;

    //$path='./uploads';

    if(!file_exists($path)){

      mkdir($path,0777,true);

      chmod($path,0777);

    }

    $uniName=getUniName();

    $destination=$path.'/'.$uniName.'.'.$ext;

    if(!move_uploaded_file($fileInfo['tmp_name'],$destination)){

      $res['mes']=$fileInfo['name'].'文件移动失败';

    }

    $res['mes']=$fileInfo['name'].'上传成功';

    $res['dest']=$destination;

    return $res;

     

  }else{

    //匹配错误信息

    switch ($fileInfo ['error']) {

      case 1 :

        $res['mes'] = '上传文件超过了PHP配置文件中upload_max_filesize选项的值';

        break;

      case 2 :

        $res['mes'] = '超过了表单MAX_FILE_SIZE限制的大小';

        break;

      case 3 :

        $res['mes'] = '文件部分被上传';

        break;

      case 4 :

        $res['mes'] = '没有选择上传文件';

        break;

      case 6 :

        $res['mes'] = '没有找到临时目录';

        break;

      case 7 :

      case 8 :

        $res['mes'] = '系统错误';

        break;

    }

    return $res;

  }

}

ログイン後にコピー

里面封装了两个小的

1

2

3

4

5

6

7

8

9

10

11

function getExt($filename){

  return strtolower(pathinfo($filename,PATHINFO_EXTENSION));

}

 

/**

 * 产生唯一字符串

 * @return string

 */

function getUniName(){

  return md5(uniqid(microtime(true),true));

}

ログイン後にコピー

然后静态中,用multiple属性实现多个文件的输入;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="doAction6.php" method="POST" enctype="multipart/form-data">

请选择您要上传的文件:<input type="file" name="myFile[]" multiple='multiple' /><br/>

<input type="submit" value="上传"/>

</form>

</body>

</html>

doAction6

<&#63;php

//print_r($_FILES);

header("content-type:text/html;charset=utf-8");

require_once 'upFunc2.php';

require_once 'common.func.php';

$files=getFiles();

// print_r($files);

foreach($files as $fileInfo){

  $res=uploadFile($fileInfo);

  echo $res['mes'],'<br/>';

  $uploadFiles[]=@$res['dest'];

}

$uploadFiles=array_values(array_filter($uploadFiles));

//print_r($uploadFiles);

ログイン後にコピー

这样子的几个文件,就实现比较强大的面向过程的上传文件的功能(学的叫一个心酸。。。);

四、面向对象的文件上传

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

<&#63;php

class upload{

  protected $fileName;

  protected $maxSize;

  protected $allowMime;

  protected $allowExt;

  protected $uploadPath;

  protected $imgFlag;

  protected $fileInfo;

  protected $error;

  protected $ext;

  /**

   * @param string $fileName

   * @param string $uploadPath

   * @param string $imgFlag

   * @param number $maxSize

   * @param array $allowExt

   * @param array $allowMime

   */

  public function __construct($fileName='myFile',$uploadPath='./uploads',$imgFlag=true,$maxSize=5242880,$allowExt=array('jpeg','jpg','png','gif'),$allowMime=array('image/jpeg','image/png','image/gif')){

    $this->fileName=$fileName;

    $this->maxSize=$maxSize;

    $this->allowMime=$allowMime;

    $this->allowExt=$allowExt;

    $this->uploadPath=$uploadPath;

    $this->imgFlag=$imgFlag;

    $this->fileInfo=$_FILES[$this->fileName];

  }

  /**

   * 检测上传文件是否出错

   * @return boolean

   */

  protected function checkError(){

    if(!is_null($this->fileInfo)){

      if($this->fileInfo['error']>0){

        switch($this->fileInfo['error']){

          case 1:

            $this->error='超过了PHP配置文件中upload_max_filesize选项的值';

            break;

          case 2:

            $this->error='超过了表单中MAX_FILE_SIZE设置的值';

            break;

          case 3:

            $this->error='文件部分被上传';

            break;

          case 4:

            $this->error='没有选择上传文件';

            break;

          case 6:

            $this->error='没有找到临时目录';

            break;

          case 7:

            $this->error='文件不可写';

            break;

          case 8:

            $this->error='由于PHP的扩展程序中断文件上传';

            break;

             

        }

        return false;

      }else{

        return true;

      }

    }else{

      $this->error='文件上传出错';

      return false;

    }

  }

  /**

   * 检测上传文件的大小

   * @return boolean

   */

  protected function checkSize(){

    if($this->fileInfo['size']>$this->maxSize){

      $this->error='上传文件过大';

      return false;

    }

    return true;

  }

  /**

   * 检测扩展名

   * @return boolean

   */

  protected function checkExt(){

    $this->ext=strtolower(pathinfo($this->fileInfo['name'],PATHINFO_EXTENSION));

    if(!in_array($this->ext,$this->allowExt)){

      $this->error='不允许的扩展名';

      return false;

    }

    return true;

  }

  /**

   * 检测文件的类型

   * @return boolean

   */

  protected function checkMime(){

    if(!in_array($this->fileInfo['type'],$this->allowMime)){

      $this->error='不允许的文件类型';

      return false;

    }

    return true;

  }

  /**

   * 检测是否是真实图片

   * @return boolean

   */

  protected function checkTrueImg(){

    if($this->imgFlag){

      if(!@getimagesize($this->fileInfo['tmp_name'])){

        $this->error='不是真实图片';

        return false;

      }

      return true;

    }

  }

  /**

   * 检测是否通过HTTP POST方式上传上来的

   * @return boolean

   */

  protected function checkHTTPPost(){

    if(!is_uploaded_file($this->fileInfo['tmp_name'])){

      $this->error='文件不是通过HTTP POST方式上传上来的';

      return false;

    }

    return true;

  }

  /**

   *显示错误

   */

  protected function showError(){

    exit('<span style="color:red">'.$this->error.'</span>');

  }

  /**

   * 检测目录不存在则创建

   */

  protected function checkUploadPath(){

    if(!file_exists($this->uploadPath)){

      mkdir($this->uploadPath,0777,true);

    }

  }

  /**

   * 产生唯一字符串

   * @return string

   */

  protected function getUniName(){

    return md5(uniqid(microtime(true),true));

  }

  /**

   * 上传文件

   * @return string

   */

  public function uploadFile(){

    if($this->checkError()&&$this->checkSize()&&$this->checkExt()&&$this->checkMime()&&$this->checkTrueImg()&&$this->checkHTTPPost()){

      $this->checkUploadPath();

      $this->uniName=$this->getUniName();

      $this->destination=$this->uploadPath.'/'.$this->uniName.'.'.$this->ext;

      if(@move_uploaded_file($this->fileInfo['tmp_name'], $this->destination)){

        return $this->destination;

      }else{

        $this->error='文件移动失败';

        $this->showError();

      }

    }else{

      $this->showError();

    }

  }

}

<&#63;php

header('content-type:text/html;charset=utf-8');

require_once 'upload.class.php';

$upload=new upload('myFile1','imooc');

$dest=$upload->uploadFile();

echo $dest;

ログイン後にコピー

四、下载

对于浏览器不识别的,可以直接下载,但对于能识别的,需要多一两步

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Insert title here</title>

</head>

<body>

<a href="1.rar">下载1.rar</a>

<br />

<a href="1.jpg">下载1.jpg</a>

<br />

<a href="doDownload.php&#63;filename=1.jpg">通过程序下载1.jpg</a>

<br />

<a href="doDownload.php&#63;filename=../upload/nv.jpg">下载nv.jpg</a>

<&#63;php

 

&#63;>

</body>

</html>

<&#63;php

$filename=$_GET['filename'];

header('content-disposition:attachment;filename='.basename($filename));

header('content-length:'.filesize($filename));

readfile($filename);

ログイン後にコピー

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート