ホームページ  >  記事  >  バックエンド開発  >  PHP ファイルのアップロードの検出と処理

PHP ファイルのアップロードの検出と処理

墨辰丷
墨辰丷オリジナル
2018-06-05 16:04:454134ブラウズ

この記事では主に PHP ファイルのアップロードの検出と処理について紹介します。興味のある方はぜひ参考にしてください。

アップロードの入力方法がそんなに悪いのでしょうか?もちろん違います。ファイルのアップロードが大きくない場合でも、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 の次の設定の影響を受けます:

  • upload_max_filesize

  • 最大実行時間

  • 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. Bind SelectFile
fr.addEventListener(Event.SELECT, onSelectFile);

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


var s = {
 size:0,
 name:&#39;&#39;,
 type:&#39;&#39;
}
4. SelectFileイベントが発生し、ファイル情報を渡す

5. Jsが呼び出すbrowseFileメソッドをpublicにする

6. 取得したファイル情報をJs

に渡す

ExternalInterface.call("onSelectFile",s);

现在我们已经可以通过Js获得由flash传递来的文件大小信息了,具体的实现可以参看Demo 。
结论
问题至此似乎已经得到解决了,我们已经成功的校验了文件大小不是么。但本文的最终结论是,基于Flash的文件大小校验,仍然不可行。
文件大小校验的唯一目的,是为了上传。在上面的Demo中可以看到校验成功的文件名会显示在一个输入框里。熟悉上传的同学不觉得少了什么吗?没错,通过 flash只能得到文件名,而无法得到文件的完整路径,而文件路径却是input方式上传的必要条件。所以虽然可以成功的通过Flash与Js交互校验文 件大小,但我们能做到的也仅仅只是校验而已,之后想要上传,唯有继续通过flash方式进行。
Flash开发出于安全考虑屏蔽了文件的完整路径这无可厚非,不过文件上传,尤其是PHP环境下的文件校验上传方案仍然没有得到最好的解决。
当然弥补的方法有很多:

基于Perl的项目 FileChucker , XUpload , Uber-Uploader基于Flash的项目 SWFUpload还有筒子用PHP直接 在服务器华丽的建立socket链接

但终究我希望有一天能看到仅基于HTML就能实现的严整健壮的上传方案,但愿这一天不会太远。
最后是本次的代码下载 。
php文件上传大小设置详解用php上传文件,问题最多的就是上传大体积文件时出现错误。 这就涉及到php的配置文件——php.ini
在此配置文件中,有这么几个值是跟文件上传有密切关系的:

  • file_uploads = on //是否允许系统支持文件上传

  • upload_tmp_dir //临时文件的存储路径,linux下为系统默认路径,win32下需要指定

  • upload_max_filesize = 2m //允许文件上传最大体积

  • post_max_size = 2m //通过post方法给php时,php所能接受的最大数据容量

如果你上传的文件体积在8m一下(通常情况),那修改以上设置就可以满足你的要求了。
但要>8m,那除了上面几个值,还要特别关注另外两个值了:

  • max_execution_time = 30 //每个script所执行的最大时间(php上传就时,体积大了,就是个时间问题)

  • memory_limit = 8m //每个script所能消耗的最大memory

试着把这两个值改大些。一般就可以解决大多数问题了。

就此推断,上传文件的体积是可以无穷大的。但还要考虑你的网络情况,等等。
在php.net上,有人说按照这个方法改了后,大于100m的文件还是会出错,不知道是不是PHP本身的问题了。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

PHP中基于sleep函数实现定时执行功能的方法

PHP 输出缓冲控制详解

php 输入输出流详解及实例分析

以上がPHP ファイルのアップロードの検出と処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。