PHPにファイルをアップロードするときに$ _FILESが空になるのはなぜですか?


145

Windows 7コンピューターにWampServer 2がインストールされています。私はApache 2.2.11とPHP 5.2.11を使用しています。フォームからファイルをアップロードしようとすると、アップロードのように見えますが、PHPでは$_FILES配列が空です。c:\wamp\tmpフォルダにファイルがありません。php.iniファイルのアップロードなどを許可するように設定しました。tmpフォルダには、現在のユーザーの読み取り/書き込み権限を持っています。私は困惑しています。

HTML:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" action="vanilla-upload.php" method="POST">
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <input type="submit" value="Upload File" />
    </form>
</body>
</html>

PHP:

<?php
echo 'file count=', count($_FILES),"\n";
var_dump($_FILES);
echo "\n";
?>

2
エラーログを確認しましたか?
バイロンウィットロック

きっと見落としている何かおかしいと思います。たとえば、あなたは間違いなくコードを持っていますvanilla-upload.phpか?
Luca Matteis、2010

私は同じ問題を抱えていました。エラーログを確認したところ、最大許容サイズを超えるファイルがアップロードされているとのことでした。
BrightIntelDusk 2014年

回答:


493

PHPでファイルをアップロードするためのチェックリストを次に示します。

  1. php.iniを確認します。
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • を使用する必要がある.htaccess.user.ini、共有ホスティングを使用していて、にアクセスできない場合php.ini
    • 正しいiniファイルを編集していることを確認してください。phpinfo()関数を使用して、設定が実際に適用されていることを確認してください。
    • また、必ずサイズスペルを間違えない作る-それがあるべき100M ではありません 100MB
  2. <form>タグにenctype="multipart/form-data"属性があることを確認してください。他のタグは機能しません。FORMタグでなければなりません。スペルが正しいことを再確認してください。multipart / form-dataが、WordまたはWebサイトのブログから貼り付けられたスマートクォートではなく、ストレートクォートで囲まれていることを再確認します(WordPressはストレートクォートをアングルクォートに変換します!)。ページに複数のフォームがある場合は、両方にこの属性があることを確認してください。それらを手動で入力するか、手動で入力した直線の単一引用符を試してください。

  3. 同じname属性を持つ2つの入力ファイルフィールドがないことを確認してください。複数をサポートする必要がある場合は、名前の最後に角括弧を置きます。

    <input type="file" name="files[]">
    <input type="file" name="files[]">
  4. tmpディレクトリとアップロードディレクトリに正しい読み取りと書き込みの権限が設定されていることを確認してください。一時アップロードフォルダは、PHP設定でとして指定されていますupload_tmp_dir

  5. ファイルの宛先とtmp / uploadディレクトリにスペースが含まれていないことを確認してください。

  6. <form>ページ上のすべてのに</form>終了タグがあることを確認してください。

  7. FORMタグにがあることを確認してくださいmethod="POST"。GETリクエストは、マルチパート/フォームデータのアップロードをサポートしていません。

  8. ファイル入力タグにNAME属性があることを確認してください。ID属性では不十分です!ID属性は、POSTペイロードではなく、DOMで使用するためのものです。

  9. 送信時に<input type="file">フィールドを無効にするためにJavaScriptを使用していないことを確認してください

  10. あなたがのようなフォームをネストしていないことを確認してください <form><form></form></form>

  11. 次のような無効/重複タグがないかHTML構造を確認してください <div><form></div></form>

  12. また、アップロードするファイルに英数字以外の文字が含まれていないことを確認してください。

  13. 一度、私は何時間も費やして、なぜこれが突然起こったのかを理解しようとしました。でPHP設定の一部を変更したことがわかりました.htaccess。そのうちの1つ(まだ不明です)が原因でアップロードが失敗し、$_FILES空になっていました。

  14. タグの属性でアンダースコア(_)を使用しないようにすることができname=""ます<input>

  15. 非常に小さいファイルをアップロードして、ファイルサイズの問題かどうかを絞り込みます。

  16. 使用可能なディスク容量を確認してください。非常にまれですが、このPHPマニュアルページのコメントに記載されています

    $ _FILES配列が突然奇妙に空になった場合、フォームが正しいように見えても、一時フォルダーパーティションに使用可能なディスク領域を確認する必要があります。私のインストールでは、警告なしにすべてのファイルのアップロードが失敗しました。歯を食いしばった後、私は追加のスペースを解放しようとしましたが、その後、ファイルのアップロードが突然再び機能しました。

  17. ページをリロードさせる通常のPOSTリクエストではなく、AJAX POSTリクエストを通じてフォームを送信しないようにしてください。上記のリストのすべてのポイントを調べたところ、$ _ FILES変数が空である原因は、AJAX POSTリクエストを使用してフォームを送信していることが原因であることがわかりました。ajaxを使用してファイルをアップロードする方法もあることは知っていますが、これが$ _FILES配列が空である正当な理由かもしれません。

これらのポイントの一部のソース:http :
//getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/


12
多分「受け入れられた」答えは元の投稿を解決しましたが、この答えは私が最も役に立ったと思ったものです。疑問がある場合は、ブラウザで表示されるソースを確認してください。このリストの各項目をチェックして逆方向にたどると、予期しない場所でエラーが見つかりました。同様の問題で苦労しているなら、私を信じてください、それはおそらくApacheのバグではありません。;)
quickthyme 2012年

3
また、ファイル入力を含むフォーム要素が別のフォーム要素の子ではないことを確認してください。例<form><form><input type="file"></form></form>
sudee 2013

3
うわー!このリストをありがとう。私の問題は#2でした。$('#my-form')[0].reset();送信ハンドラを呼び出していました。
Gavin

2
ありがとう。私の場合は7番です。犯人はenctype = "multipart / form-data"でした。
2014

3
おい、あなたは命の恩人です。私はこれを理解しようと何時間も費やしました(2)が私の問題でした...ありがとう!
Mike Q

74

あなたがその部分を正しく設定したように見えるHTMLに関しては。あなたはすでにenctype="multipart/form-data"フォーム上に持つことが非常に重要なものを持っています。

あなた限りphp.ini、時にはシステムのセットアップ、複数のphp.iniファイルが存在します。正しいものを編集していることを確認してください。私はあなたがあなたの設定したと知ってphp.ini、ファイルのアップロードを持っているファイルを、しかし、あなたはまたあなたを設定しなかったupload_max_filesizeし、post_max_sizeアップロードしようとしているファイルよりも大きくなるように?だからあなたは持っているべきです:

file_uploads = On; sounds like you already did this
post_max_size = 8M; change this higher if needed
upload_max_filesize = 8M; change this higher if needed

ディレクトリに"c:\wamp\tmp"読み取りと書き込みの両方の権限がありますか?php.ini変更後、Apacheを再起動することを覚えていますか?



4
+1:Apacheサーバーのヒントを再起動します。多くのWindowsユーザーはそれを忘れています。
shamittomar 2010

36

enctype="multipart/form-data"フォームに追加することが重要です、例

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

14

さまざまな包括的な返信をありがとうございました。それらはすべて非常に役に立ちます。答えは非常に奇妙なものであることがわかりました。PHP 5.2.11は次のものが好きではないことがわかりました。

post_max_size = 2G

または

post_max_size = 2048M

に変更すると2047M、アップロードは機能します。


17
このような高い値は、スペース不足/ ddos​​攻撃に対する脆弱性であることに注意してください。これを追加するだけで、ソリューションをコピーして貼り付けようとするときに、多くの人が気づきすぎます。とにかく、2ギグではアップロード時間が長すぎます。
Manuel Arwed Schmidt 2014

大きすぎません。1-3Gの範囲のファイルを非常に定期的にアップロードするクライアントがいます。彼らは自分のサーバーにファイルをアップロードしており、IPホワイトリストに登録されたサーバーであるため、交換はごく普通のことであり、クライアントが自分の使いたい方法で機器を使用できるようにする方法にすぎません。彼らは費用を支払い、セキュリティ上のリスクはなく、問題はありません。
TheSatinKnight 2017

8

2時間見て同じ問題がありますが、サーバー構成を最初に確認するのは非常に簡単です。

例:

echo $upload_max_size = ini_get('upload_max_filesize');  
echo $post_max_size=ini_get('post_max_size');   

ファイルサイズのタイプはですが:20mb、配列はupload_max_sizeより大きい20mbですnull。答えは、私たちがpost_max_sizeより大きくなければなりません upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M

6

ここで別の原因が見つかりました。JQueryMobileを使用していて、フォーム属性data-ajaxがtrueに設定されている場合、FILES配列は空になります。したがって、data-ajaxをfalseに設定します。


5

入力要素に 'name'属性があることを確認してください。 <input type="file" name="uploadedfile" />

これがない場合、$ _ FILESは空になります。


4

私は同じ問題に取り組み、すべてをテストしていましたが、エラー報告は得られず、何も問題がないように見えました。error_reporting(E_ALL)がありましたが、突然、Apacheログを確認していないことに気付きました。スクリプトに構文エラーがありました...!(「}」がありません)

したがって、これは確認する必要があることは明らかですが、忘れられる可能性があります...私の場合(Linux)は次の場所にあります。

/var/log/apache2/error.log

3

誰もこれについて言及しませんでしたが、それは私を助け、ネット上の多くの場所がそれについて言及しませんでした。

php.iniが次のキーを設定していることを確認してください:

    upload_tmp_dir="/path/to/some/tmp/folder"

絶対サーバーファイルパスを使用するかどうかをウェブホストに確認する必要があります。これを確認するには、php.iniファイルで他のディレクトリの例を確認できるはずです。設定するとすぐに、_FILESオブジェクトの値を取得しました。

最後に、tmpフォルダーと、ファイルを移動する場所に正しいアクセス許可を設定して、読み取りと書き込みができるようにします。


2

あなたはファイルの配列をアップロードしようとしているなら、あなたは増やす必要があるかもしれませんmax_file_uploadsphp.iniに、デフォルトのセットであります20

max_file_uploadsphp.iniの外では変更できません。参照してくださいPHP "バグ" #50684


2

別の考えられる原因は、Apacheリダイレクトです。私の場合、Apacheのhttpd.confを設定して、サイトの特定のページをhttpバージョンにリダイレクトし、他のページをまだページのhttpsバージョンにリダイレクトしました(まだの場合)。ファイルを入力したフォームがあるページは、sslを強制するように構成されたページの1つでしたが、フォームのアクションとして指定されたページはhttpに構成されました。したがって、ページはアクションページのsslバージョンへのアップロードを送信しますが、Apacheはそれをページのhttpバージョンにリダイレクトし、アップロードされたファイルを含む投稿データは失われました。


2

次の理由により、php.iniでenable_post_data_reading = Onを確認してください。

このオプション無効にすると、$ _ POSTおよび$ _FILESが入力されなくなります。postdataを読み取る唯一の方法は、php:// inputストリームラッパーを使用することです。(...)

ではhttp://php.net/manual/en/ini.core.php#ini.enable-post-data-reading


1

あなたの主なスクリプトがある場合http://Some_long_URL/index.php(明示的に完全なURLを指定することで気をつけてindex.phpいないだけhttp://Some_long_URLで)actionフィールドが。意外なことに、そうでない場合、正しいスクリプトが実行されますが、空の$ _FILESが使用されます。


1

私は同じ問題に遭遇し、それは私のIDEが問題の一部であることがわかりました。ブラウザーを直接使用するのではなく、IDE(PHPStorm)から直接デバッガーを起動していました。IDEが生成したURLは次のとおりです。

"...localhost:63342/CB_Upload/index.php?_ijt=j2hcbacqepj87bvg66ncuohvne"

そしてただ使う:

"...localhost/CB_Upload/index.php"

うまくいきました。私のセットアップはPC / Windows 10 / WAMPSERVER 3.0.6 64ビットです


ここでも同じです。これまで1時間、輪になって走っていました。感謝
EKanadily

1

sys_get_temp_dir共有ホスティング環境にいる場合は、によって提供される一時フォルダーの場所を信頼しないでください。

ここでは、まだ言及されていないことを確認するためのもう1つの点を示します

当然のことながら、PHPスクリプトが一時ファイルのアップロードを格納するフォルダはであると想定していました/tmp。この信念は、echo sys_get_temp_dir() . PHP_EOL;戻るという事実によって強化されました/tmp。また、echo ini_get('upload_tmp_dir');何も返しません。

アップロードされたファイルが実際に一時的に私の/tmpフォルダーに表示されることを確認するためsleep(30);に、スクリプトにステートメントを追加し(ここで提案されているように/tmp、cPanelファイルマネージャーのフォルダーに移動してファイルを見つけました。ただし、アップロードされたファイルがどこにあるかは関係ありません。

私はこれの理由を決定するために何時間も費やし、ここに提供されているすべての提案を実行しました。

最後に、自分のWebサイトファイルでクエリを検索したところ、自分のサイトに別のディレクトリにある別tmpのフォルダが含まれていることがわかりましtmpた。PHPスクリプトが実際にアップロードされたファイルをに書き込んでいる.cagefs/tmpことに気付きました(このフォルダーを表示するには、cPanelで[ 隠しファイルを表示]設定を有効にする必要があります。)

では、なぜsys_get_temp_dir関数は不正確な情報を返すのでしょうか?

PHP.net Webページの説明sys_get_temp_dir(つまり、トップコメント)は次のとおりです。

systemdがPrivateTmp = true(CentOS 7およびおそらく他の新しいディストリビューションのデフォルト)であるLinuxシステムで実行している場合、この関数は単に「/ tmp」を返すだけで、真のはるかに長い、やや動的なパスではありません。

このSOの投稿では、この問題についても詳しく説明しています。


0

私は同じ問題を抱えており、どのテーマも私のエラーではありませんでした。「MultiViews」が有効になっている場合は、.htaccessファイルを入手してください。それらを無効にする必要がありました。


0

私は同様の問題を抱えており、shamittomarが言及したように、htaccessの問題は間違った値でした。

変更php_value post_max_size 10MBphp_value post_max_size 10M


0

置い$_FILESた後、私は空でした<form enctype="multipart/form-data" method="post">

</div>
<div style="clear:both"></div>

最初のコードは

<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>

変更して

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
</div>
<div style="clear:both"></div>
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>

だから結論は、後で<form enctype="multipart/form-data" method="post">なけれ<input name, type, idばならないか、<div>または他のいくつかのタグであってはならないということです

私の状況では正しいコードは

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
</div>
<div style="clear:both"></div>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>

0

私も$ _FILESが空で問題がありました。上記のチェックリストでは、.htaccess、httpd.conf、またはhttpd-vhost.confのMultiViewについて言及していません。

Webサイトを含むディレクトリのオプションディレクティブでMultiViewsを設定している場合、Content-Lengthヘッダーがアップロードしたファイルを示している場合でも、$ _ FILESは空になります。


0

JQuery Mobileを使用している場合

Ajaxでは、ファイル入力を伴うマルチパートフォームの使用はサポートされていません。この場合、親フォームをdata-ajax = "false"で装飾して、フォームがサーバーに適切に送信されるようにする必要があります。

<form action="upload.php" method="post" enctype="multipart/form-data"  data-ajax="false">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

0

使用しているページからフォームを切り離し、フォームとphpコードのみを持つ単純なphpページにして、そのようにテストします。

ブートストラップまたはJavaスクリプトは、_FILES []を消去する可能性があります。それは私のケースでした

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.