PHP実現ファイルのアップロードとダウンロードの実例と総括

20899 ワード

一、アップロード原理と配置
1.1原理
クライアントファイルをサーバ側にアップロードし、サーバ側のファイル(一時ファイル)を指定したディレクトリに移動すればよい.
1.2クライアント構成
必要:フォームページ(ファイルのアップロードを選択);
具体的には、送信方式がPOSTで、enctype="multipart/form-data"属性を追加するには、両者が欠けてはいけない(ただし、メリットとデメリットが併存しており、ここではアップロード方式やアップロードされたファイルの後の呼び出しなども限定されており、後述する)





Insert title here


アップロードするファイルを選択してください:
まずフォームページ(フロントエンドの問題を自動的に無視してください...)肝心なのはformの属性です.またinputではtype=「file」という点(phpの強さの広がりなどに表れている)が用いられている.
そしてdoAction

 
 

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

Array
(
  [myFile] => Array
    (
      [name] =>   _  .doc
      [type] => application/msword
      [tmp_name] => D:\wamp\tmp\php1D78.tmp
      [error] => 0
      [size] => 75776
    )

)


だから得たのは2次元の配列で、どのように使うべきで、すべて基本的なものです(実は私は次元を下げて使うのが好きです);
基本は一目で分かるもので、くどくどしないで、肝心なのは2つあります:tmp_nameテンポラリファイル名;Errorエラーメッセージ(番号、後で利用可能);
次にdoActionの後ろの部分を見て、エラーメッセージを利用してユーザーにフィードバックして、なぜエラーを報告したのか、エラーメッセージが何なのかを説明する必要があります.
1.3エラーの報告について
--エラーの原因
基本的には、アップロードファイルに関するサーバの構成を超えたり、満たしていない場合がありますが、サーバ側の構成はどのようなものですか?
まずアップロードを考えてみましょう.私たちは何を使いましたか.POST,upload
だからphp.iniでは、次の項目を探しています.

file_upload:On

upload_tmp_dir=――        ;

upload_max_filesize=2M

max_file_uploads=20――             (          ,   size,   )

post_max_size=8M――post          


その他の関連構成
max_exectuion_time=-1――最大実行時間、プログラムがサーバー資源を占有しにくいことを避ける.
max_input_time=60
max_input_nesting_レベル=64――ネストされた深さを入力します.
memory_Limit=128 M――最大シングルスレッドの独立メモリ使用量
つまり、リソースに関する構成です.
--エラー番号
以下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;ファイルがアップロードされていません. 
注意:このエラーメッセージは、moveやcopyの場合ではなく、一時フォルダにアップロードされた情報です.
二、アップロードに関する制限
2.1クライアント制約

アップロードするファイルを選択してください:
ここでinputの属性でアップロードファイルのサイズとタイプを制限しましたが、個人的な感じ:一、htmlコードは“見えます”です;二、よく役に立たない(原因が見つからなかったが、最初に私もそれを放弃したいので、知っていればいい.
2.2サーバ側の制限
主に大きさとタイプを制限し、もう一つは方法です.

$maxsize) {
    exit("      !");
  }
  if (!in_array($ext, $allowExt)) {
    exit("      ");
  }
  if (!is_uploaded_file($tmp_name)) {
    exit("      ,   post  ");
  }
  if (@move_uploaded_file($tmp_name, $uniName)) {//@     ,        
    echo "  ".$filename."    !";
  }else{
    echo "  ".$filename."    !";
  }
  //         (             
  if (!getimagesize($tmp_name)) {//getimagesize      ,    false
    exit("         ");
  }

}else{
  switch ($error){
    case 1:
      echo "           ,   2M    ";
      break;
    case 2:
      echo "      ,     20      !";
      break;
    case 3:
      echo "        ,     !";
      break;
    case 4:
      echo "       !";
      break;
    case 7:
      echo "       ";
      break;
  }
}


ここで、具体的な実装にはコメントがありますが、一歩一歩自分でやってみることができて、面白いです.
2.3パッケージ
関数#カンスウ#

$maxSize) {
    exit("      !");
  }
  if (!in_array($ext, $allowExt)) {
    exit("      ");
  }
  if (!is_uploaded_file($tmp_name)) {
    exit("      ,   post  ");
  }
  //         (             
  if (!getimagesize($tmp_name)) {//getimagesize      ,    false
    exit("         ");
  }
  if (@move_uploaded_file($tmp_name, $destination)) {//@     ,        
    echo "  ".$filename."    !";
  }else{
    echo "  ".$filename."    !";
  }
}else{
  switch ($error){
    case 1:
      echo "           ,   2M    ";
      break;
    case 2:
      echo "      ,     20      !";
      break;
    case 3:
      echo "        ,     !";
      break;
    case 4:
      echo "       !";
      break;
    case 7:
      echo "       ";
      break;
  }
}
return $destination;
}



よびだし

 
 

三、マルチファイルのアップロード実現
3.1単一ファイルによるカプセル化





Insert title here


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

 
 

ここの考え方はprint_r($_FILES)の中で探して、印刷して2次元の配列を見て、とても簡単で、遍歴して使えばいいです!
上のfunctionの定義を変更して、いくつかのデフォルト値を与えます.
function uploadFile($fileInfo,$path="uploads",$allowExt=array('jpeg','jpg','png','tif'),$maxSize=10485760){
このように、簡単は簡単ですが、いくつかの問題に遭遇しました.
正常に4つの画像をアップロードするのは問題ありませんが、途中で関数のexitをアクティブにすると、すぐに停止し、他の画像もアップロードできません.
3.2アップグレード版パッケージ
複数または単一のファイルへのアップロードを目的としたパッケージ
まずこのように静的ファイルを書きます





Insert title here


アップロードするファイルを選択してください:
アップロードするファイルを選択してください:
アップロードするファイルを選択してください:
アップロードするファイルを選択してください:
$_を印刷FILES

Array
(
  [myFile] => Array
    (
      [name] => Array
        (
          [0] => test32.png
          [1] => test32.png
          [2] => 333.png
          [3] => test41.png
        )

      [type] => Array
        (
          [0] => image/png
          [1] => image/png
          [2] => image/png
          [3] => image/png
        )

      [tmp_name] => Array
        (
          [0] => D:\wamp\tmp\php831C.tmp
          [1] => D:\wamp\tmp\php834C.tmp
          [2] => D:\wamp\tmp\php837C.tmp
          [3] => D:\wamp\tmp\php83BB.tmp
        )

      [error] => Array
        (
          [0] => 0
          [1] => 0
          [2] => 0
          [3] => 0
        )

      [size] => Array
        (
          [0] => 46174
          [1] => 46174
          [2] => 34196
          [3] => 38514
        )

    )

)


3 D配列が得られます.
複雑は複雑ですが、複雑で規則的で、各数値が一緒になって、私たちが値を取るのに便利です!!
だからまずファイル情報を得て、単一ファイル処理のような情報になります

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を使います.

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

中には2つの小さな

function getExt($filename){
  return strtolower(pathinfo($filename,PATHINFO_EXTENSION));
}

/**
 *        
 * @return string
 */
function getUniName(){
  return md5(uniqid(microtime(true),true));
}


その後、静的ではmultiple属性で複数のファイルの入力を実現する.





Insert title here


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

';
  $uploadFiles[]=@$res['dest'];
}
$uploadFiles=array_values(array_filter($uploadFiles));
//print_r($uploadFiles);


このようないくつかのファイルは、比較的強力なプロセス向けのアップロードファイルの機能を実現します(学的には心酸と呼ばれています..).
四、オブジェクト向けのファイルアップロード
(あまり书かれていない动き...まずくっついてからにしましょう...

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(''.$this->error.'');
  }
  /**
   *           
   */
  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();
    }
  }
}

uploadFile();
echo $dest;

四、ダウンロード
ブラウザで認識されていない場合は、直接ダウンロードできますが、認識できる場合は、1、2歩多くかかります.





Insert title here


ダウンロード1.rar

ダウンロード1.jpg
プログラムを して1をダウンロードする.jpg
nvをダウンロードします。jpg

----------------------------------------------------
 
2 D配列の次元降下処理;
$_FILES変数
move_upload_file();copy();
tmp_nameテンポラリファイル;
拡張名の抽出;
真実の画像の検証;
ユニークなファイル名の生成;
関数のカプセル化と呼び出し;
単一のファイル関数を利用してマルチファイルアップロードを実現する.
小機能のパッケージ;
マルチファイルの遍歴;
オブジェクト向けの開発プロセス;