web-dev-qa-db-ja.com

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

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";
?>
125
elmonty

さまざまな包括的な回答をありがとう。これらはすべて非常に役立ちます。答えは非常に奇妙なものであることが判明しました。 PHP 5.2.11は以下を好まないことがわかりました。

post_max_size = 2G

または

post_max_size = 2048M

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

14
elmonty

PHPでファイルをアップロードするためのチェックリストは次のとおりです:

  1. Php.iniをチェックしてください:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

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

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

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

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

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

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

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

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

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

  11. <div><form></div></form>のような無効/重複タグのHTML構造を確認します

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

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

  14. _タグのname=""属性でアンダースコア(<input>)を避けてみてください。

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

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

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

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

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

431
shamittomar

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

php.iniの設定に関しては、システム上に複数のphp.iniファイルが存在する場合があります。正しいものを編集していることを確認してください。 php.iniファイルをアップロードするように設定したと言っていましたが、アップロードしようとしているファイルよりも大きくなるようにupload_max_filesizepost_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を再起動することを覚えていましたか?


72
Brian

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>
30
meda

ここで私が見つけた別の原因:JQuery Mobileを使用し、フォーム属性data-ajaxをtrueに設定すると、FILES配列は空になります。したがって、data-ajaxをfalseに設定します。

6
dutchman711

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

例:

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

任意の種類のファイルサイズは:20mbですが、upload_max_size20mbより上ですが、配列はnullです。答えは、post_max_sizeupload_max_filesizeより大きくなければなりません

post_max_size = 750M  
upload_max_filesize = 750M
5
shashik493

私は同じ問題に苦労し、すべてをテストしましたが、エラー報告は得られず、何も間違っているようには見えませんでした。 error_reporting(E_ALL)がありましたが、突然、Apacheのログをチェックしていないことに気付きました!スクリプトに構文エラーがありました...! (欠落している「}」)

そのため、これは確認するべき明らかなことですが、忘れられてしまう可能性があります...私の場合(Linux)では:

/var/log/Apache2/error.log
3
Luis Rosety

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

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

3
Adrian Parr

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

2
user2723315

ファイルの配列をアップロードしようとしている場合、デフォルトでmax_file_uploadsに設定されているphp.ini20 を増やす必要がある場合があります。

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

2
Tahir Yasin

Php.iniでenable_post_data_reading = Onを確認してください。理由は次のとおりです。

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

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

2
jmng

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

Php.iniで次のキーが設定されていることを確認してください。

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

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

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

2
AaronP

私は同じ問題に遭遇し、それが私の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
Marc M.

私は同様の問題を抱えていましたが、shamittomarが述べたように、問題はhtaccessで間違った値にありました。

php_value post_max_size 10MBphp_value post_max_size 10Mに変更します

0
Johnny Vietnam

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
Rajan

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

まだ言及されていない確認事項がもう1つあります...

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

アップロードされたファイルが実際に/tmpフォルダーに短時間表示されることを確認するために、スクリプトにsleep(30);ステートメントを追加し(推奨 here )、cPanelファイルマネージャーの/tmpフォルダーに移動してファイルを見つけました。ただし、何があっても、アップロードされたファイルはどこにも見つかりませんでした。

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

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

それで、なぜsys_get_temp_dir関数は不正確な情報を返すのですか?

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

SystemdにPrivateTmp = trueが設定されているLinuxシステム(CentOS 7およびその他の新しいディストリビューションのデフォルト)で実行している場合、この関数は単純に「/ tmp」を返します。

このSO投稿でも問題を詳しく調べています。

0
Crickets

$_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
Andris

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

0
Murolack

メインスクリプトがhttp://Some_long_URL/index.phpである場合は、actionフィールドに完全なURL(明示的なindex.phpおよびnotのみhttp://Some_long_URL)を指定するよう注意してください。驚くべきことに、そうでない場合、正しいスクリプトが実行されますが、空の$ _FILESが使用されます!

0
Gibbie

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

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

0
gerteb