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

하 같은 문제가 발생했습니다. 오류 로그를 확인한 결과 파일이 업로드 중이며 최대 허용 크기를 초과했다고합니다.
BrightIntelDusk

답변:


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 또는 웹 사이트 블로그에서 붙여 넣은 스마트 따옴표가 아닌 STRAIGHT QUOTES로 둘러싸여 있는지 다시 확인하십시오 (WordPress는 따옴표를 따옴표로 변환합니다!). 페이지에 여러 양식이있는 경우 둘 다이 속성이 있는지 확인하십시오. 수동으로 입력하거나 직접 입력 한 작은 따옴표를 사용해보십시오.

  3. 동일한 name속성을 가진 두 개의 입력 파일 필드가 없는지 확인하십시오 . 여러 개를 지원해야하는 경우 이름 끝에 대괄호를 넣으십시오.

    <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 속성은 POST 페이로드가 아닌 DOM에서 사용하기위한 것입니다.

  9. <input type="file">제출시 필드 를 비활성화하기 위해 Javascript를 사용하지 않아야 합니다.

  10. 다음과 같은 양식을 중첩하지 않아야합니다. <form><form></form></form>

  11. HTML 구조에서 유효하지 않거나 겹치는 태그가 있는지 확인하십시오. <div><form></div></form>

  12. 또한 업로드중인 파일에 영숫자가 아닌 문자가 없는지 확인하십시오.

  13. 한 번, 나는 이것이 왜 갑자기 이런 일이 일어나고 있는지 알아 내려고 몇 시간을 보냈습니다. 에서의 일부 PHP 설정을 수정했으며 그 .htaccess중 하나 (아직 확실하지 않음)로 인해 업로드가 실패하고 $_FILES비어있는 것으로 나타 났습니다 .

  14. 태그 속성 _에서 밑줄 ( )을 피할 수 있습니다.name=""<input>

  15. 매우 작은 파일을 업로드하여 파일 크기 문제인지 확인하십시오.

  16. 사용 가능한 디스크 공간을 확인하십시오. 매우 드물지만이 PHP 매뉴얼 페이지 주석에 언급되어 있습니다 .

    양식이 올바른 것처럼 보이지만 $ _FILES 배열이 갑자기 신비 로워지면 임시 폴더 파티션에 사용 가능한 디스크 공간을 확인해야합니다. 설치시 모든 파일 업로드가 경고없이 실패했습니다. 치아가 많이 찢어지면 추가 공간을 확보하려고 시도한 후 파일 업로드가 갑자기 다시 작동했습니다.

  17. 페이지를 다시로드하는 일반적인 POST 요청 대신 AJAX POST 요청을 통해 양식을 제출하지 않아야합니다. 위의 목록에서 각각의 모든 포인트를 살펴보고 $ _FILES 변수가 비어있는 이유는 AJAX POST 요청을 사용하여 양식을 제출했기 때문이라는 것을 알았습니다. 나는 아약스를 사용하여 파일을 업로드하는 방법이 있다는 것을 알고 있지만 이것이 $ _FILES 배열이 비어있는 유효한 이유 일 수 있습니다.

이러한 요점 중 일부에 대한 출처 :
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/


12
어쩌면 "허용 된"답변이 원래 게시물을 해결했을 수도 있지만이 답변은 내가 가장 도움이 된 답변입니다. 의심스러운 경우, 브라우저가 보는대로 소스를보십시오. 이 목록의 각 항목을 확인하고 뒤로 추적하면 가장 예기치 않은 위치에서 오류가 발견되었습니다. 비슷한 문제로 어려움을 겪고 있다면 아파치의 버그는 아닐 것입니다. ;)
quickthyme

3
또한 파일 입력을 포함하는 양식 요소가 다른 양식 요소의 하위 요소가 아닌지 확인하십시오. 예 :<form><form><input type="file"></form></form>
sudee

3
와! 이 목록에 감사드립니다. 내 문제는 # 2였습니다. $('#my-form')[0].reset();제출 핸들러를 호출 했습니다.
개빈

2
감사. 내 경우에는 번호 7입니다. enctype = "multipart / form-data"가 범인이었습니다.
up 텐

3
DUDE, 당신은 생명의 은인입니다. 나는 이것을 알아 내려고 노력하는 데 몇 시간을 보낸다.
Mike Q

74

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를 다시 시작한 것을 기억 하십니까?



4
+1 : Apache 서버 팁을 다시 시작합니다. 많은 Windows 사용자는 그것을 잊어 버립니다.
shamittomar

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
이러한 높은 가치는 우주 외 / 도스 공격에 대한 취약성입니다. 사람들이 솔루션을 복사하여 붙여 넣을 때 사람들이 너무 많이 인식하도록 이것을 추가하기 만하면됩니다. 어쨌든, 2 gigs에는 너무 긴 업로드 시간이 필요합니다.
Manuel Arwed Schmidt 2016

더 이상 크지 않습니다. 1-3G 범위의 파일을 정기적으로 업로드하는 클라이언트가 있습니다. 파일을 자체 서버에 업로드하고 IP 화이트리스트 서버이기 때문에 교환은 매우 일반적이며 클라이언트가 원하는 방식으로 장비를 사용할 수 있도록하는 방법입니다. 그들은 청구서를 지불하고, 보안 위험이 없으며, 문제가 없습니다.
TheSatinKnight

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

여기에 또 다른 원인이 있습니다. JQuery Mobile을 사용하고 data-ajax 양식 속성이 true로 설정되면 FILES 배열이 비어 있습니다. 따라서 data-ajax를 false로 설정하십시오.


5

입력 요소에 'name'속성이 있는지 확인하십시오. <input type="file" name="uploadedfile" />

이것이 없으면 $ _FILES는 비게됩니다.


4

나는 같은 문제로 어려움을 겪고 있었고 모든 것을 테스트했지만 오류보고를받지 못했습니다. 아무것도없는 것처럼 보였습니다. 나는 error_reporting (E_ALL)을 가졌지 만 갑자기 나는 아파치 로그를 확인하지 않았다는 것을 깨달았다! 스크립트에 구문 오류가 있습니다 ...! ( "}"누락)

따라서 이것이 확인되어야 할 것이 분명하지만 잊어 버릴 수 있습니다 ... 내 경우에는 (Linux) :

/var/log/apache2/error.log

3

아무도 이것을 언급하지 않았지만 그것은 나를 도왔고 그물에 많은 언급이 없었습니다.

php.ini가 다음 키를 설정했는지 확인하십시오 :

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

절대 서버 파일 경로를 사용하려면 웹 호스트를 확인해야합니다. 이것을 결정하기 위해 php.ini 파일에서 다른 디렉토리 예제를 볼 수 있어야합니다. 설정하자마자 _FILES 객체에 값이 있습니다.

마지막으로 tmp 폴더와 파일을 이동하는 모든 곳에서 파일을 읽고 쓸 수 있도록 올바른 권한을 갖도록하십시오.



2

또 다른 가능한 원인은 아파치 리디렉션입니다. 내 경우에는 아파치의 httpd.conf를 설정하여 사이트의 특정 페이지를 http 버전으로 리디렉션하고 다른 페이지는 https 버전으로 페이지를 리디렉션하지 않았습니다. 파일 입력이있는 양식이있는 페이지는 ssl을 강제 실행하도록 구성된 페이지 중 하나이지만 양식의 동작으로 지정된 페이지는 http로 구성되었습니다. 따라서 페이지가 업로드를 조치 페이지의 ssl 버전으로 제출했지만 아파치가 페이지를 http 버전의 페이지로 리디렉션하고 업로드 된 파일을 포함한 게시물 데이터가 손실되었습니다.



1

주 스크립트 인 경우 http://Some_long_URL/index.php(명시 적으로 전체 URL을 지정하는 자르 index.php하지http://Some_long_URL에서) action필드. 놀랍게도 그렇지 않은 경우 올바른 스크립트가 실행되지만 en _ $ _ 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 64bit입니다.


여기에서도 똑같이, 지금까지 한 시간 동안 서클에서 달리고있었습니다! 감사
EKanadily

1

sys_get_temp_dir공유 호스팅 환경에있는 경우 제공 한 임시 폴더 위치를 신뢰하지 마십시오 .

아직 언급되지 않은 사항이 하나 더 있습니다.

필자는 PHP 스크립트가 임시 파일 업로드를 저장 한 폴더가 자연 스럽다고 가정했다 /tmp. 이 믿음은 echo sys_get_temp_dir() . PHP_EOL;돌아 오는 사실에 의해 강화되었다 /tmp. 또한 echo ini_get('upload_tmp_dir');아무것도 반환하지 않습니다.

업로드 된 파일이 실제로 내 /tmp폴더에 잠깐 나타나는지 확인하기 위해 sleep(30);스크립트에 문장을 추가하고 ( 여기 에서 제안 된대로 ) /tmpcPanel File Manager에서 내 폴더로 이동하여 파일을 찾습니다. 그러나 무엇이든 업로드 된 파일을 찾을 수 없었습니다.

나는 그 이유를 파악하기 위해 몇 시간을 보냈고 여기에 제공된 모든 제안을 이행했습니다.

마지막으로 웹 사이트 파일에서 검색어를 검색 한 후 내 사이트 에 다른 디렉토리에 tmp이름이 지정된 다른 폴더가 포함되어 있음을 발견했습니다 tmp. 내 PHP 스크립트가 실제로 업로드 된 파일을에 쓰고.cagefs/tmp 있음을 깨달았습니다 . ( "숨겨진 파일 표시" 설정은이 폴더를보기 위해의 cPanel를 활성화해야합니다.)

그렇다면 왜 sys_get_temp_dir함수가 부정확 한 정보를 반환합니까?

다음은 PHP.net 웹 페이지에서 설명합니다 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를 언급하지 않습니다.

웹 사이트를 포함하는 디렉토리에 대한 옵션 지시문에 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.