PHP ファイルサイズの検出と大きなファイルのアップロード処理

伊谢尔伦
リリース: 2023-03-02 19:42:01
オリジナル
3376 人が閲覧しました

ローカルとサーバーの両方の側面にセキュリティ上の問題が含まれるため、input type="file" に基づくページ ファイルのアップロードは常に厄介な状況にありました。一方で、ユーザーは自分のプライバシーが漏洩されることを望んでいないため、ブラウザはアップロード時にユーザーが選択したファイルについて有効な判断を行うことができません。一方、サーバー側のセキュリティと送信負荷の軽減のため、システムはユーザーがアップロードを開始する前に違法なファイルを拒否することを望んでいます。

元の入力方法に基づいたアップロードは、ネットワーク ストレージ Web サイトが回避するレガシーな問題となっており、あらゆる種類の奇妙なプラグインやアップロード クライアントも作成されています。

アップロードの入力方法がそんなに悪いのでしょうか?もちろん違います。ファイルのアップロードが大きくない場合でも、PHP では、複合フォーム:

<form enctype="multipart/form-data" action="__URL__" method="POST">
ログイン後にコピー

、入力ボックス:

<input name="userfile" type="file" />
ログイン後にコピー

、およびサーバー側のコード行:

move_uploaded_file($_FILES[&#39;userfile&#39;][&#39;tmp_name&#39;], &#39;/var/www/uploads/&#39;. basename($_FILES[&#39;userfile&#39;][&#39;name&#39;]));
ログイン後にコピー

のみが必要です。アップロードプロセス全体。

しかし、ファイルサイズが大きくなるにつれて、フォームアップロードの欠点が明らかになります。特に、大きすぎるファイルのアップロードを防ぐために最小ファイル サイズを取得するという単純な考えは、非常に困難になっています。 1 つずつ見てみましょう:

MAX_FILE_SIZE ごと

MAX_FILE_SIZE 隠しフィールド (単位はバイト) はファイル入力フィールドの前に配置する必要があり、その値は受信したファイルの最大サイズです。これはブラウザに対する推奨事項であり、PHP もこれをチェックします。この設定はブラウザ側で簡単にバイパスできるため、この機能を使用して大きなファイルをブロックすることは期待しないでください。実際、PHP 設定の最大アップロード ファイル サイズは期限切れになりません。ただし、この項目をフォームに追加することをお勧めします。これにより、ユーザーが大きなファイルのアップロードを待って時間を費やした後に、ファイルが大きすぎてアップロードに失敗したというトラブルを回避できます。

明らかに、PHP 開発者は大きなファイルのアップロードの問題も考慮していますが、マニュアルにあるように、MAX_FILE_SIZE はブラウザーに対する提案にすぎません。実際、すべての主流ブラウザーはこれまでのところこの提案を採用していないため、ファイル サイズを制限する MAX_FILE_SIZE を採用します。は単なる取り決めのようなものであり、実現可能ではありません。

サーバー側経由

MAX_FILE_SIZE が無効であるため、ユーザーはファイルをサーバーにアップロードできます。サーバー側は、ユーザーがアップロードしたファイルのサイズを $_FILES['userfile']['size'] を通じて決定します。そして、アップロードを受け入れて情報を返すかどうかを決定します。サーバーへの負荷と、当面の悪意のある妨害行為の可能性を除けば、このソリューションは帯域幅の無駄以外の何ものでもないように思えます。また、ユーザーによるファイルのアップロードも制限されます。

しかし、これも実行不可能です。PHP ファイルのアップロードは、php.ini の次の設定の影響を受けます。

post_max_size
upload_max_filesize
max_execution_time
memory_limit
ログイン後にコピー

設定方法はマニュアルに詳しく説明されていますが、この方法がまだ実行できない理由は次のとおりです。 PHP実行スクリプトがmemory_limitを超えると、すべてのPOSTデータが失われ、エラーは報告されません。

ユーザーが非常に長いフォームに記入し、memory_limit を超えるファイルとともにアップロードすると、待っているのは別の空白のフォームであることがわかります。これは非常に印象的なユーザー エクスペリエンスです。 。さらに、数十 MB のサーバー トラフィックはファイル サイズの検出にのみ使用されますが、現在のネットワーク環境では許可されていません。

Javascript を通して

Javascript はブラウザをベースとしていますが、JS は一見不可能に見える多くのタスクを実行できますが、ブラウザにできないことは JS では実行できません。固有の欠点により、この作業は Javascript のみで行うことが運命づけられています。ただし、一部の IE Only メソッドは参照用としてまだ存在します。

Flash を通じて

Flash の FileReference クラスは、比較的包括的なファイル処理メソッドのセットを提供するようになり、ほとんどの大規模ファイルのアップロードでも Flash ベースのソリューションが使用されます。 Flash を使用して Js と対話する場合、クライアントはファイル サイズを検出できますか?答えは「はい」です。

まず、フラッシュ ファイルで FileReference クラスをインスタンス化します。

var fr = new FileReference();
ログイン後にコピー

このクラスに基づいて、Flash が提供するファイル参照イベントと SelectFile イベントを使用してブラウザ イベントを置き換えることができます。必要なもの:

1. SelectFile をバインドする

fr.addEventListener(Event.SELECT, onSelectFile);
ログイン後にコピー

2. flash で取得したファイル情報を配置するためのオブジェクトを作成する

var s = {
    size:0,
    name:&#39;&#39;,
    type:&#39;&#39;
}
ログイン後にコピー

4. SelectFile イベントがトリガーされるとき, ファイル情報を渡します

function browseFile():void {<br>
    fr.browse();<br>
}
ログイン後にコピー

5. Jsが呼び出せるようにbrowseFileメソッドを公開します

function onSelectFile(e:Event):void {<br>
    s.size = fr.size;<br>
    s.name = fr.name;<br>
    s.type = fr.type;<br>
}
ログイン後にコピー

6. 取得したファイル情報をJsに渡します

ExternalInterface.addCallback("browseFile", browseFile);
ログイン後にコピー

これでJs経由でFlashで渡されたファイルサイズ情報を取得できるようになりました。特定の実装のためのデモへ。

結論

これでファイルサイズの確認は成功したようですね。しかし、この記事の最終的な結論は、Flash ベースのファイル サイズ検証は依然として実現可能ではないということです。

ファイルサイズ検証の唯一の目的はアップロードです。上のデモでは、検証に成功したファイル名が入力ボックスに表示されることがわかります。アップロードに慣れている学生は、何かが足りないと感じませんか?そう、Flashではファイル名しか取得できませんが、ファイルのフルパスは取得できず、入力によるアップロードにはファイルパスが必須条件となります。そのため、Flash と JS の対話を通じてファイル サイズを正常に検証できますが、後でアップロードする場合は、Flash を使用し続けることしかできません。

Flash 開発がセキュリティ上の理由からファイルのフル パスをブロックすることは理解できますが、ファイルのアップロード、特に PHP 環境でのファイル検証アップロード ソリューションにはまだ最適なソリューションがありません。

もちろん、それを補う方法はたくさんあります:

Perl ベースのプロジェクト FileChucker、

しかし、結局のところ、いつか HTML のみに基づいた厳密で堅牢なアップロード ソリューションが登場することを願っています。その日がそう遠くないことを願っています。

最後はこのコードのダウンロードです。

PHPファイルアップロードサイズ設定の詳しい説明

PHPでファイルをアップロードする際、最もよくある問題は大きなファイルをアップロードする際のエラーです。 これには、php 設定ファイル - php.ini が関係します

この設定ファイルには、ファイルのアップロードに密接に関連するいくつかの値があります:

file_uploads = on //システムがファイルのアップロードをサポートできるかどうか

Upload_tmp_dir //Linux ではシステムのデフォルトのパスである一時ファイルのストレージ パスは、win32 で指定する必要があります

upload_max_filesize = 2m //ファイルのアップロードに許可される最大サイズ

post_max_size = 2m //PHP が受け入れられるサイズpost メソッドを通じて PHP に送信する 最大データ容量

アップロードするファイル サイズが (通常) 8m 未満の場合は、上記の設定を変更することで要件を満たすことができます。

ただし、8 分を超える場合は、上記の値に加えて、他の 2 つの値に特別な注意を払う必要があります:

max_execution_time = 30 //各スクリプトの最大実行時間 (php がアップロードされるとき) 、サイズが大きい、それは時間の問題です)

memory_limit = 8m //各スクリプトが消費できる最大メモリ

これら 2 つの値をより大きくなるように変更してみてください。通常、これでほとんどの問題は解決できます。

このことから、アップロードされるファイルのサイズは無限である可能性があることが推測できます。ただし、ネットワーク状況なども考慮してください。


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