6

Web 開発者の人生の後半または初期に、ユーザーがアップロードしたファイルや画像を処理する必要があります。

よくある質問:

アップロード方法を教えてください。

最新の Web ブラウザーと技術により、ユーザーが提供したファイルをサーバーにアップロードする方法がいくつかあります。ベスト プラクティスとは何ですか? また、考慮すべきことは何ですか?

処理方法を教えてください。

アップロードが完了したら、セキュリティとファイルの処理について知っておくべきことは何ですか?

保管・発送方法は?

アップロードされたファイルの保存方法に関するベスト プラクティスはありますか?

免責事項: 次の回答に約 30 分を費やしました。最初の質問は削除されたため、ユーザー提供のファイルを扱うときにユーザーが直面する可能性のある一般的な質問をすることにしました。私の答えを見てください。あなたは自由に貢献し、あなたのアイデアや経験を追加してください

4

1 に答える 1

28

これらの各ステップに「最善」の方法はありませんが、ユーザー フレンドリーなアップロード、セキュリティ、および速度を達成するのに役立つさまざまな手法とライブラリの中で、確立された方法とベスト プラクティスが多数あります。

残念ながら削除された別の質問については、この小さなガイドを書きました。

ユーザーが投稿したファイルまたは画像は、その存続期間中にいくつかの段階を経ます。

  1. アップロード自体
  2. 検証
  3. 保存のための処理 (例: 型変換、サイズ変更、サムネイル生成、...)
  4. 収納
  5. フロントエンド側の配信

これにより、すべての手順が説明され、可能な限り例が提供されます。

1. アップロード

最新の Web ブラウザーには、ファイルをアップロードする方法がいくつか用意されています。

最も簡単な方法は、単純な<input type="file" name="userFile" />タグを使用してフォームを作成することです。フォームが送信されると、ファイルは POST を使用して送信され、PHPの$_FILES スーパーグローバルでアクセスできます。

1.1。HTML のシンプルなフォーム

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="userFile1" />
    <input type="file" name="userFile2" />
    <input type="submit" value="upload files" />
</form>

フォームが送信されると、upload.php に POST リクエストが送信されます。この種のアップロードはあまりユーザーフレンドリーではありません。ユーザーはアップロードの進行状況を確認できず、複数のファイルをアップロードするのは面倒です

1.2. Javascript ajax アップロード

このソリューションでは、POST は JavaScript を使用して非同期的に実行されます

http://www.saaraan.com/2012/05/ajax-image-upload-with-progressbar-with-jquery-and-php

1.3。HTML5アップロード

最新のブラウザーは HTML5 をサポートしており、プログレス バーとプレビューを備えた非常に使いやすいアップロード マスクを使用できます - 境界線はあなた自身の創造性です

たとえば、私はこのデモが本当に好きです: http://html5demos.com/dnd-upload

サーバー側

これらのアップロード手法のいずれを使用するかに関係なく、アップロードは最終的にスクリプトに送信される HTTP POST になります。以降のすべての処理はサーバー上で行われます。

PHP はファイルを一時パス ( upload_tmp_dir )にコピーします。

php.ini またはini_setでオンザフライで微調整できるアップロード関連の設定がいくつかあります: http://php.net/manual/en/ini.core.php#ini.sect.file-アップロード

アップロード.php

<pre>
<?php
print_r( $_FILES );

これは、$_FILESアップロードが成功した後のスーパーグローバルの外観です。

  • 名前:元の名前
  • type: ブラウザが提供する MIME タイプ
  • size: バイト単位のサイズ
  • tmp_name: サーバー上の一時ファイル名
  • エラー:ここで説明されているエラー コード、すべてがファイルに保存された場合は 0

各ファイルには独自のインデックスがあります

Array
( 
    [userFile1] => Array
    (
         [name] => i_love_ponies.png
         [type] => image/png
         [size] => 42233
         [tmp_name] => /tmp/_x123tfsdayx134
         [error] => 0
    )
    [userFile2] => Array
    (
         [name] => ponies_run_my_server.png
         [type] => image/png
         [size] => 12325
         [tmp_name] => /tmp/_x3123asdad3ssy
         [error] => 0
    )
)

いくつかの追加のヒント

大きなファイルが予想される場合は、Web サーバーと PHP の実行タイムアウトを考慮してください。アップロードに 10 分かかる場合、ユーザーにエラーが発生することは望ましくありません。

PHP では、max_execution_timeを増やすことができます

2.検証

よくある質問

特定のファイルのみを許可したいのですが、どのような種類のファイルを受け取りますか?

$_FILES配列で見つかったタイプは、ブラウザーによって設定されます。どのタイプがアップロードされたかを確認したい場合は、PHPのfileinfo 拡張機能を使用できます。

この例では、アップロード自体の成功を確認し、許可されたタイプのファイルを新しい配列に書き込んで、さらに処理します。

$allowedTypes = array(
   'image/png'
   'image/gif'
   'image/jpeg'
);

$useFiles = array();

$finfo = new finfo(FILEINFO_MIME_TYPE);
foreach ( $_FILES as $index => $file )
{
    if ( $file['error'] === UPLOAD_ERR_OK ) {
        $type = $finfo->file( $file['tmp_name'] );
        if ( in_array( $type, $allowedTypes ) ) {
             $useFiles[$index] = $file;
        }
    }
}

最大ファイルサイズを設定したいですか? サイズは?

$_FILES['key']['size']この場合、バイト単位のサイズである値に安全に依存できます。クライアント側で設定されたファイル サイズ制限だけに頼るべきではありません

画像について話している場合、サムネイルを拡大縮小または作成しますか? 画像の寸法はどのくらいですか?

画像のサイズを決定するには、 getimagesizeを見てください。

3. 加工

ファイルを最終的な場所に保存する前に、何らかの処理を行いたい場合があります。それができる時です。

画像処理に使用される一般的なライブラリはgd libimagickです。個人的には gd lib の方が好きです。手作業が少し増えますが、より高速で、ほとんどのインストールにデフォルトで付属しているか、追加で簡単にインストールできます。Imagemagick には、ネイティブに画像処理機能の非常に大きなプールがあります。

4. データの保存

今回は収納についてです。まず、一時ファイルを一時または最終的な場所にコピーする方法を保存します。

move_uploaded_fileを使用する必要があります

move_uploaded_file( $useFiles['tmp_name'], $destination );

繰り返しますが、保存するための「最善の方法」はありません。これは、環境、ファイル、および用途によって異なります。いくつかお話しします

4.1. サーバーファイルシステム

これはおそらく、ファイルを保存する最も簡単な方法です。すでに実行中の Web サーバーを使用して、ファイルを静的に提供するだけです。これは通常、ドキュメント ルート内の場所です。

あなたの人生を楽にするために、ファイル名をデータベースに保存することができます - できれば、ユーザーや場所などの接続されたデータを参照または参照します。

さまざまな理由から、すべてのファイルを同じフォルダーに保存しないでください。

ファイルごとに一意の名前を生成する必要があります。そうしないと、既存のファイルを新しいファイルで上書きしてしまいます。また、通常のファイルシステムは、ノード内のファイルの量が増えるとシークが遅くなります。これにより、ファイルの配信が要求されたときの応答時間が遅くなります。

ユーザーごとにフォルダに保存できます

/uploaded/user-id/file.jpg

ユーザーごとに多くのファイルが予想される場合は、ファイル名のチェックサムを分割して、より深いフォルダー構造を取得できます

例えば

$path =  $_SERVER['DOCUMENT_ROOT'] . '/uploaded/' . $userId . '/' . chunk_split( md5( $useFiles['index']['name'] ), 12, '/' );

結果として

/var/www/htdocs/uploaded/1/97e262286853/d52aa8c58eb7/f0431f03/

4.2. データベース

blob タイプを使用して、ファイルを MySQL データベースに保存できます。これは一般的にはお勧めしません

4.3. コンテンツ配信ネットワーク

世界中で大量のトラフィックが予想される場合は、Cloudfront を使用してAmazon S3などの CDN にファイルを保存することを検討してください。

S3 は、5 TB までのファイルを保存できる安価で信頼性の高いストレージです (私の知る限り)。

http://www.9lessons.info/2012/08/upload-files-to-amazon-s3-php.html

ファイルのバックアップ、利用可能なハードディスクのサイズ、配信速度などについて心配する必要はありません。Cloudfrontは、世界中のエッジ ロケーションを持つ S3 の上に CDN レイヤーを追加します。

于 2012-12-20T12:57:37.460 に答える