PHP開発基本チュートリアルファイルのアップロード

1. PHP ファイルのアップロード

私たちは日常的に次のような状況によく遭遇します:

  • QQ スペースに写真をアップロードする

  • WeChat Moments に写真をアップロードする

  • メールデータをアップロードするメールに添付ファイル

  • 認証の際、写真またはIDカードをアップロードする必要があります

  • また、ニーズを分析してさまざまなものをアップロードするためのさまざまな製品gou(ゴウ)もあります。

  • そして私たちは、Wang という製品によって提示されたニーズを実現する必要があります。

  • ファイルのアップロードの実装は、PHP プログラマーに必要なスキルの 1 つです。

ファイルアップロードを学ぶことで、使用現象を通してファイルアップロードの本質が見えてきます!


2. ファイルをアップロードするときは、php.ini ファイルに注意する必要があります

この章でアップロードについて正式に説明する前に、最初に行う必要があるのは、php.ini ファイルに注意を払うことです。 iniファイル。

php.ini ファイルの変更方法を初めて紹介します。設定項目が説明と矛盾している場合は、変更に注意してください。

各設定項目を理解しましょう。

php.iniを変更する方法を見てみましょう。

phpstudyでphp.ini設定ファイルを開きます。

52.png

php.ini ファイルが多すぎて見つからない場合は、ctrl+f を使用して関連する構成項目を検索できます。


53.png


推奨サイズ: file_size (ファイルサイズ)

また、スクリプトの実行時間にも注意する必要があります。

max_execution_time、このパラメータの単位は秒です。

このパラメータは、スクリプトの最大実行時間を設定します。
必要に応じて適切な変更を行うこともできます。通常は変更する必要はなく、システムのデフォルト値で十分です。非常に大きなファイルをアップロードする場合、このパラメータが変更される可能性があります。

アップロード時間が長すぎるため、タイムアウトになります。このパラメータを 0 に設定すると、タイムアウト期間は制限されないため、お勧めできません。

php.ini の関連構成が完了したら、最初のファイルのアップロードを完了することを開始できます。


3. ファイルアップロードのステップ

PHPをより良く学ぶために、非常に複雑なPHPファイルのアップロードを6つのステップにまとめました。

実際の使用では、次の 6 つの手順に従って PHP ファイルのアップロードを正常に完了できます:

1. エラー コードがあるかどうかを確認します

システムによって返されるエラー コードの詳細な説明:


54.png


注: エラーコードには 5

はありません

2.アップロード機能を開発する際に、ファイルサイズが

の範囲を超えるかどうかをカスタマイズします。開発者として、php.ini で指定された最大アップロード値に加えて、

通常、企業が指定したアップロード サイズ制限である値も設定します。

例:
Sina Weibo または QQ Zone では、2M の単一のアバター写真のみが許可されます。アルバムをアップロードする場合は、2M を超えてアップロードできます。

そのため、そのシステムはより大きなファイルのアップロードをサポートしています。

ここでの判定ファイルサイズは、実際の業務で指定したいアップロードファイルサイズを制限するために使用されます。

3. サフィックス名と MIME タイプが一致するかどうかを確認します

オンラインの世界にも悪い人がいます。画像にウイルスを挿入したり、添付ファイルにウイルスをアップロードしたり、Web ページにウイルスやポルノ画像を挿入したりします。

アップロードされたファイルのサフィックスとMIMEタイプを判断する必要があります。

MIME (MultiPurpose Internet Mail Extensions) は、多目的インターネット メール拡張機能のタイプです。特定の拡張子を持つファイルをアプリケーションで開くように設定するメソッドの一種で、その拡張子のファイルにアクセスすると、ブラウザは指定されたアプリケーションを使用して自動的にそのファイルを開きます。これは主に、クライアント定義のファイル名とメディア ファイルを開く方法を指定するために使用されます。

サフィックスと MIME タイプを決定するときは、2 つのパラメーターを渡す PHP 関数 in_array() を使用します。
最初のパラメータは判定する値です。
2 番目のパラメータは範囲配列です。

この関数を使用して、ファイル拡張子と MIME タイプが許可された範囲内であるかどうかを判断します。

4. ファイル名の生成

ファイルは正常にアップロードされましたが、元の名前は保存されません。
元の名前にデリケートなキーワードが含まれている一部の人々は、我が国の関連法規制に違反する可能性があるためです。

date()、mt_rand()、または unique() を使用して、ランダムなファイル名を生成できます。

5. アップロードされたファイルかどうかを確認します

ファイルが正常にアップロードされると、システムはアップロードされた一時ファイルをシステムの一時ディレクトリにアップロードします。一時ファイルを作成します。

同時に一時ファイル名も生成されます。必要なのは、一時ファイルをシステム上の指定されたディレクトリに移動することです。

動く前にやみくもに動かない、あるいは間違った動きをするのは非科学的です。移動する前に、関連する関数を使用して、アップロードされたファイルが一時ファイルであるかどうかを判断する必要があります。

is_uploaded_file() はパラメータ ($_FILES のキャッシュ ファイル名) を渡して、渡された名前がアップロードされたファイルかどうかを判断します

6. 一時ファイルを指定された場所に移動します

一時ファイルは実際のものです一時ファイルを Web サイトのディレクトリに移動する必要があります。

当社のウェブサイトディレクトリ内のデータに他の人がアクセスできるようにします。

move_uploaded_file() を使用します。
この関数は、アップロードされたファイルを指定された場所に移動し、名前を付けます。
2 つのパラメータを渡します:
最初のパラメータは、移動を指定するアップロードされたファイルです。
2 番目のパラメータは、指定されたフォルダとその名前を連結した文字列です


4. ファイルアップロードフォームに関する注意事項

正式な学習を開始し、ファイルをアップロードする方法を学びます。ファイルをアップロードするには、Webページ上にフォームを用意する必要があります。

これは単純な HTML ページ フォームです。このフォーム フォームは、type=file を入力すると、デフォルトでファイル コンテンツがアップロードされます。

フォームのコードと注意点を見てみましょう

<html>
    <head>
        <meta charset="utf-8" />
        <title>单文件上传</title>
    </head>
    <body>
        <form action="file.php" method="post" enctype="multipart/form-data">
            <input type="file" name="file">
            <input type="submit" value="上传">
        </form>
    </body>
</html>

注:

  • フォームform内のパラメータメソッドはpostである必要があります。 get の場合、ファイルのアップロードは実行できません。 enctype は multipart/form-data である必要があります。

    フォームによって送信されたファイルの内容は file.php を指しています。
  • アップロードされたファイルは、file.php の PHP コードを通じて処理されます。
  • アップロードする名前の付いた写真を選択します。画像の名前がhua.jpgであると仮定します。クリックしてアップロードします。

  • PHP はファイルデータ専用のシステム関数 $_FILES を用意しており、アップロードされたファイルの関連データはすべてこのシステム関数に保存されます。

PHP ファイルで $_FILES を出力して、この配列の構造を確認します。

<?php
//var_dump()或print_r()
//打印变量的相关信息,将变量的信息详细的展示出来
var_dump($_FILES);             
?>
出力された結果の配列構造は次のとおりです:

上記の配列構造が得られます。 ファイル処理プロセスを開始できます。


2. エラー コードを決定します

<?php
if($_FILES['file']['error'] > 0){
    switch ($_FILES['file']['error']) {    //错误码不为0,即文件上传过程中出现了错误
        case '1':
            echo '文件过大';
            break;
        case '2':
            echo '文件超出指定大小';
            break;
        case '3':
            echo '只有部分文件被上传';
            break;
        case '4':
            echo '文件没有被上传';
            break;
        case '6':
            echo '找不到指定文件夹';
            break;
        case '7':
            echo '文件写入失败';
            break;
        default:
            echo "上传出错<br/>";
    }
}else{
    //错误码为0,即上传成功,可以进行后续处理,处理流程见下文
}
?>

上記のコードは、エラー コードとそれに対応するエラーを詳細に示しています。

3. ファイルがサイズを超えているかどうかを確認します

実際のプロジェクトでは、システムのハードウェア制限とストレージデバイスの制限により、ユーザーが無制限にファイルをアップロードすることは不可能であるため、ファイルのサイズを確認する必要がありますユーザーによるアップロードの制限。適切な制限サイズを定義すると、アプリケーションをより安定して実行できます。

//判断错误
if($_FILES['file']['error'] > 0){
        //有错误可停止执行
}else{
    //当前上传文件无误,运行本段代码
 
    //判断文件是否超出了指定的大小
    //单位为byte
    $MAX_FILE_SIZE = 100000;
    if($_FILES['file']['size'] > $MAX_FILE_SIZE){
    //判断,如果上传的文件,大小超出了我们给的限制范围,退上传并产生错误提示
        exit("文件超出指定大小");                           
    }
55.png $MAX_FILE_SIZE として指定するファイル サイズを定義します。この変数のカウント単位はバイトであり、アップロードされたファイルの $_FILES['file']['size'] のサイズに対応します。

サンプルコードでは、サイズが約100K以下のファイルが制限されています。

4. ファイルの MIME タイプが正しいかどうかを確認します

オンライン アプリケーションの場合、ファイル アップロード機能は、ユーザーがアップロードしたファイルが要件を満たしているかどうかを確認する必要があることがよくあります。効果が悪影響を及ぼします。したがって、MIME タイプとサフィックス名を使用して、ユーザーがアップロードしたファイルが要件を満たしているかどうかを判断する必要があります。

以下のサンプルコードでは、現在のプロジェクト要件がアップロードされた画像を指定し、サフィックスが GIF または jpg のファイルのアップロードを要求していると想定しています。ユーザーが要件を満たさないファイルをアップロードすると、次のようなエラー メッセージが表示されます。戻ってきた。

/*判断后缀名和MIME类型是否符合指定需求
例如:
当前项目指定上传后缀为.jpg或.gif的图片,则$allowSuffix = array('jpg','gif');
*/
//定义允许的后缀名数组
$myImg = explode('.', $_FILES['file']['name']);         
 
/*
explode() 将一个字符串用指定的字符切割,并返回一个数组,这里我们将文件名用'.''切割,结果存在$myImg中,文件的后缀名即为数组的最后一个值
*/
$myImgSuffix = array_pop($myImg);
/*
根据上传文件名获取文件的后缀名
使用in_array()函数,判断上传文件是否符合要求
当文件后缀名不在我们允许的范围内时退出上传并返回错误信息
*/ 
if(!in_array($myImgSuffix, $allowSuffix)){                             
        exit("文件后缀名不符");
}
/*
mime类型和文件后缀名的对应关系,我们可以通过很多途径查询到,为了避免用户自主修改文件后缀名造成文件无法使用。
mime类型也必须做出限制检查mime类型,是为了防止上传者直接修改文件后缀名
导致文件不可用或上传的文件不符合要求。
*/
//数组内容为允许上传的mime类型
$allowMime = array(
            "image/jpg",
            "image/jpeg",
            "image/pjpeg",
            "image/gif"
            );
if(!in_array($_FILES['file']['type'], $allowMime)){                      //判断上传文件的mime类型是否在允许的范围内
      exit('文件格式不正确,请检查');
    //如果不在允许范围内,退出上传并返回错误信息
}

5. 指定されたパスとファイル名を生成します

プロジェクトのファイル配置に従ってファイルの保存パスを生成します。ファイル名の重複によるエラーを避けるために、特定の形式に従ってランダムなファイル名が生成されます。

//指定上传文件夹
$path = "upload/images/";
/*
根据当前时间生成随机文件名,本行代码是使用当前时间 + 随机一个0-9的数字组合成文件名,后缀即为前面取到的文件后缀名
*/
$name = date('Y').date('m').date("d").date('H').date('i').date('s').rand(0,9).'.'.$myImgSuffix;

6. ファイルがアップロードされているかどうかを判定する

is_uploaded_file()関数は、対象のファイルがアップロードされたファイルであるかどうかを判定する専用の関数です。

<?php
//使用is_uploaded_file()判断是否是上传文件,函数介绍见上文
if(is_uploaded_file($_FILEs['file']['tmp_name'])){    
}
?>

7. ファイルを指定した場所に移動します

move_uploaded_file() 関数を使用して、ファイルを指定した場所に移動し、名前を付けます。 Linux システムにはターゲット ディレクトリに対するアクセス許可があり、ディスク容量が十分であるかどうかが考慮されることに注意してください。そうでない場合、アップロード操作は失敗します。

/*
使用move_uploaded_file()移动上传文件至指定位置,第一个参数为上传文件,第二个参数为我们在前面指定的上传路径和名称。
*/
 
if(move_uploaded_file($_FILEs['file']['tmp_name'], $path.$name)){
            //提示文件上传成功
            echo "上传成功";                                
        }else{
/*
文件移动失败,检查磁盘是否有足够的空间,或者linux类系统中文件夹是否有足够的操作权限
*/
            echo '上传失败';                                                
        }
    }else{
        echo '不是上传文件';
    }
}
?>

完全なコードは次のとおりです:

<?php
if ($_FILES['file']['error'] > 0) {
    switch ($_FILES['file']['error']) {
        //错误码不为0,即文件上传过程中出现了错误
        case '1':
            echo '文件过大';
            break;
        case '2':
            echo '文件超出指定大小';
            break;
        case '3':
            echo '只有部分文件被上传';
            break;
        case '4':
            echo '文件没有被上传';
            break;
        case '6':
            echo '找不到指定文件夹';
            break;
        case '7':
            echo '文件写入失败';
            break;
        default:
            echo "上传出错<br/>";
    }
} else {

    $MAX_FILE_SIZE = 100000;
    if ($_FILES['file']['size'] > $MAX_FILE_SIZE) {
        exit("文件超出指定大小");

    }

    $allowSuffix = array(
        'jpg',
        'gif',
    );

    $myImg = explode('.', $_FILES['file']['name']);

    $myImgSuffix = array_pop($myImg);

    if (!in_array($myImgSuffix, $allowSuffix)) {
        exit("文件后缀名不符");
    }

    $allowMime = array(
        "image/jpg",
        "image/jpeg",
        "image/pjpeg",
        "image/gif",
    );

    if (!in_array($_FILES['file']['type'], $allowMime)) {
        exit('文件格式不正确,请检查');
    }

    $path = "upload/images/";
    $name = date('Y') . date('m') . date("d") . date('H') . date('i') . date('s') . rand(0, 9) . '.' . $myImgSuffix;

    if (is_uploaded_file($_FILEs['file']['tmp_name'])) {

        if (move_uploaded_file($_FILEs['file']['tmp_name'], $path . $name)) {
            echo "上传成功";
        } else {
            echo '上传失败';
        }

    } else {
        echo '不是上传文件';
    }

}
?>

6. 複数のファイルのアップロード

PHP で単一のファイルをアップロードするプロセスを紹介します。ただし、便宜上、複数のファイルを同時にアップロードする必要がある場合があります。複数ファイルのアップロードの原理は同じですが、データを処理する場合、アップロードされたデータを特別に処理する必要があります。

<html>
    <head>
        <meta charset="utf-8" />
        <title>单文件上传</title>
    </head>
    <body>
        <form action="morefile.php" method="post" enctype="multipart/form-data">
         <input type="file" name="file[]">
         <input type="file" name="file[]">
         <input type="submit" value="上传">
     </form>
    </body>
</html>

これは簡単なアップロード ページで、フォームは 2 つのファイルを同時に送信します。このページからコンテンツを送信できます。

注:

  • input type="file" name="file[]" 以前と比較して、ファイルの後に余分な角括弧が追加されています

  • 2 つ以上の入力タイプを記述します =" file" name="file[]"
    $_FILES を使用してファイル情報を受け取り、配列を印刷および表示します:

<?php
var_dump($_FILES); //打印$_FILES查看数组结构
?>

配列構造は右側に表示されます

2 つのファイルが保存されていることがわかります配列の場合、キー名はアップロードされた単一ファイルと同じです。したがって、for() ループを使用して、2 つのファイルからそれぞれ必要なデータを取得する必要があります。

2 つのファイルのデータが $_FILES に同時に保存されます。単純なループを使用して、1 つのファイルの情報を読み取り、ファイルを配置したい場所に移動する必要があります。

for ($i=0; $i < count($_FILE['file']['name']); $i++) {  
/*
用is_uploaded_file()函数判断是上传文件
并且没有出现错
*/
    if(is_uploaded_file($_FILEs['file']['tmp_name'][$i]) && $_FILEs['file']['error'][$i] == 0){     
        if(move_uploaded_file($_FILEs['file']['tmp_name'][$i],'upload/'.$_FILE['file']['name'][$i])){
    //用move_uploaded_file()函数移动文件到指定的位置并使用文件原名
    echo "上传成功";
        }else{
            echo '上传失败';
        }
    }else{
       echo '上传失败';
    }
}

詳細な判定プロセスについては、単一ファイルのアップロードを参照してください。ここでは基本的な判定のみが行われ、ファイル サイズや形式についての注意事項はありません。
ファイルサイズや形式は業務に応じてご自身で判断し、エラー通知を提供してください。


7. ファイルアップロードの進行処理

ファイルが大きすぎる場合、またはユーザーのネットワーク状態が平均的な場合、この時点でユーザーが空白の画面で待機している場合、通常、アップロードプロセスに時間がかかります。 , ほとんどのユーザーはアプリケーションを直接削除する必要があると思います。そのため、アップロードの進行状況を監視し、リアルタイムでユーザーに報告する必要性は、Wang という製品によって考慮されます。高品質のアップロード進行状況プロンプトにより、アプリケーションはすぐに注目されるようになります。
PHP 5.4 より前は、ファイルのアップロードの進行状況を監視するために、常に追加の拡張機能をインストールする必要がありました。 5.4 からは、session.upload_progress の新機能が導入されています。セッションを通じてファイルのアップロードの進行状況を監視するには、php.ini の設定を有効にするだけです。 php.ini内。

注: この章を学習するには、セッション、JavaScript、および Ajax の基本的な知識が必要です。

php.ini ファイルを設定し、チェックして変更するように注意する必要があります。

56.png

設定を有効にすると、セッションを通じて完全なファイル アップロードの進行状況を記録できます。セッションでは、次の結果を含む配列が表示されます:

 $_SESSION["upload_progress_test"] = array(
    //请求时间
     "start_time" => 1234567890,
     // 上传文件总大小
     "content_length" => 57343257,
     //已经处理的大小
     "bytes_processed" => 453489,
     //当所有上传处理完成后为TRUE,未完成为false
     "done" => false,
 
     "files" => array(
      0 => array(
        //表单中上传框的名字
 
       "field_name" => "file1",
 
       //上传文件的名称
       "name" => "test1.avi",
 
       //缓存文件,上传的文件即保存在这里
       "tmp_name" => "/tmp/phpxxxxxx",
 
       //文件上传的错误信息
       "error" => 0,
 
       //是否上传完成,当这个文件处理完成后会变成TRUE
       "done" => true,
 
       //这个文件开始处理时间
       "start_time" => 1234567890,
 
       //这个文件已经处理的大小
       "bytes_processed" => 57343250,     
      ),
 
      1 => array(
       "field_name" => "file2",
       "name" => "test2.avi",
       "tmp_name" => NULL,
       "error" => 0,
       "done" => false,                    
       "start_time" => 1234567899,
       "bytes_processed" => 54554,
      ),
     )
    );

この配列は、ファイルのアップロードの進行状況を詳細に記録し、処理されたファイルのステータスは true です。次に、jQuery AJAX の例を使用して、ファイルのアップロードの進行プロセスを学習します。

まず、フォームに type=hidden の input タグを追加する必要があります。タグの値はカスタマイズされます (この値はバックグラウンドで使用されるため、意味のある値を使用することをお勧めします)

<form id="upload-form" action="upload.php" method="POST" enctype="multipart/form-data" style="margin:15px 0" target="hidden_iframe">
    <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="test" />
    <p><input type="file" name="file1" /></p>
    <p><input type="submit" value="Upload" /></p>
</form>
<div id="progress" style="margin-bottom:15px;display:none;">
    <div>0%</div>
</div>

こちら、ID が追加されます。これは、アップロードの進行状況を表示するコンテナとして使用される進行状況 div です。 js の setTimeout() を使用して ajax を定期的に実行し、ファイルのアップロードの進行状況を取得します。バックグラウンド ファイルはファイル アップロードの進行状況のパーセンテージを返します。

<script src="../jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
function fetch_progress(){
    $.get('progress.php',{ '<?php echo ini_get("session.upload_progress.name"); ?>' : 'test'}, function(data){
        var progress = parseInt(data);
        $('#progress .label').html(progress + '%');
        if(progress < 100){
            setTimeout('fetch_progress()', 100);    //当上传进度小于100%时,显示上传百分比
        }else{
            $('#progress .label').html('完成!'); //当上传进度等于100%时,显示上传完成
        }
    }, 'html');
}
 
$('#upload-form').submit(function(){
    $('#progress').show();
    setTimeout('fetch_progress()', 100);//每0.1秒执行一次fetch_progress(),查询文件上传进度
});
</script>

上記のコードは、JQ の ajax を使用して、ファイルのアップロードの進行状況を 0.1 秒ごとに返します。そして、divタグに進捗率を表示します。

バックグラウンド コードは 2 つの部分に分割する必要があります。upload.php はファイルのアップロードを処理します。 progress.php はセッション内のアップロードの進行状況を取得し、進行状況のパーセンテージを返します。

ここではファイルのアップロードについては詳しく説明しません。詳細な手順については、上記を参照してください。upload.php:

<?php
if(is_uploaded_file($_FILES['file1']['tmp_name'])){                                            //判断是否是上传文件
    //unlink($_FILES['file1']['tmp_name']);    
    move_uploaded_file($_FILES['file1']['tmp_name'], "./{$_FILES['file1']['name']}");     //将缓存文件移动到指定位置
}
?>
主要关注progress.php:
<?php
/*
开启session。请注意在session_start()之前,请不要有想浏览器输出内容的动作,否则可能引起错误。
*/
 
session_start();
 
//ini_get()获取php.ini中环境变量的值
$i = ini_get('session.upload_progress.name');
 
//ajax中我们使用的是get方法,变量名称为ini文件中定义的前缀 拼接 传过来的参数
$key = ini_get("session.upload_progress.prefix") . $_GET[$i];    
//判断 SESSION 中是否有上传文件的信息
if (!empty($_SESSION[$key])) {                                        
    //已上传大小
    $current = $_SESSION[$key]["bytes_processed"];
    //文件总大小
    $total = $_SESSION[$key]["content_length"];
 
    //向 ajax 返回当前的上传进度百分比。
    echo $current < $total ? ceil($current / $total * 100) : 100;
}else{
    echo 100;                                                       
}
?>

この時点で、フロントエンドでファイルの進行コードが完成しました。クールなファイルアップロード機能を作成してください。

学習体験: ファイルアップロードの 6 つのステップを覚えてください


学び続ける
||
<?php if ($_FILES['file']['error'] > 0) { switch ($_FILES['file']['error']) { //错误码不为0,即文件上传过程中出现了错误 case '1': echo '文件过大'; break; case '2': echo '文件超出指定大小'; break; case '3': echo '只有部分文件被上传'; break; case '4': echo '文件没有被上传'; break; case '6': echo '找不到指定文件夹'; break; case '7': echo '文件写入失败'; break; default: echo "上传出错<br/>"; } } else { $MAX_FILE_SIZE = 100000; if ($_FILES['file']['size'] > $MAX_FILE_SIZE) { exit("文件超出指定大小"); } $allowSuffix = array( 'jpg', 'gif', ); $myImg = explode('.', $_FILES['file']['name']); $myImgSuffix = array_pop($myImg); if (!in_array($myImgSuffix, $allowSuffix)) { exit("文件后缀名不符"); } $allowMime = array( "image/jpg", "image/jpeg", "image/pjpeg", "image/gif", ); if (!in_array($_FILES['file']['type'], $allowMime)) { exit('文件格式不正确,请检查'); } $path = "upload/images/"; $name = date('Y') . date('m') . date("d") . date('H') . date('i') . date('s') . rand(0, 9) . '.' . $myImgSuffix; if (is_uploaded_file($_FILEs['file']['tmp_name'])) { if (move_uploaded_file($_FILEs['file']['tmp_name'], $path . $name)) { echo "上传成功"; } else { echo '上传失败'; } } else { echo '不是上传文件'; } } ?>
  • おすすめコース
  • コースウェアのダウンロード
現時点ではコースウェアはダウンロードできません。現在スタッフが整理中です。今後もこのコースにもっと注目してください〜