>백엔드 개발 >PHP 튜토리얼 >PHP 파일 업로드 원칙에 대한 심층 분석 및 이해

PHP 파일 업로드 원칙에 대한 심층 분석 및 이해

WBOY
WBOY원래의
2016-07-25 09:00:56969검색
PHP 파일 업로드 관련 원칙에 대해 심도있게 소개하겠습니다. 도움이 필요한 친구들이 참고할 수 있습니다.

많은 PHP 튜토리얼에서 파일 업로드를 소개합니다. 우리 모두 알고 있듯이 PHP 파일 업로드는 간단하고 효율적입니다.

//multipart/form-data 인코딩 형식 사용 $_FILES 시스템 기능; $_FILES['myFile']['name']파일 이름 $_FILES['myFile']['type'] 파일 형식, 서버에 의해 제한됨 영상/** 이미지/x-png 응용 프로그램/x-zip 압축 $_FILES['myFile']['size']업로드 파일 크기 $_FILES['myFile']['tmp_name'] 서비스 업로드 후 임시 파일 이름을 저장합니다. $_FILES['myFile']['error'] 오류 코드; 0 성공 1 php.ini 크기 초과 2 MAX_FILE_SIZE 옵션에 지정된 값 초과 3부분 업로드만 가능 5업로드된 파일 크기는 0입니다

move_uploaded_file(임시 파일, 대상 위치 및 파일 이름); 업로드 후 파일을 대상 위치로 이동하는 기능 is_uploaded_file(MIME);

업로드 MIME 유형 결정의 예: 1. HTML 부분

<form enctyoe="multipart/form-data" method="post" name="upload">
<input name="upfile" name="name">
</form>

2. 파일 업로드 코드

<?php
if(is_uploaded_file($_FILES['myFile']['tmp_name'])){
$upfile = $_FILES['upload'];
$name = $upfile['name'];
$type = $upfile['type'];
$size = $upfile['size'];
$tmp_name = $upfile['tmp_name'];
$error = $upfile['error'];
switch($type){
case 'image/pjpeg' : $ok=1;
break
}
if($ok){
move_uploaded_file($tmp_name,'up/'.$name);
}else{
echo "不允许的文件类型";
}
}
?>

---------------------------------- - PHP 파일 업로드의 원리와 구현 1. 양식 1. 파일 업로드 양식은 post 메소드를 사용합니다(get과의 차이점은 말할 필요도 없음). 또한 enctype='multipart/form-data'를 추가합니다. 2. 일반적으로 파일 필드 앞에 라는 숨겨진 필드를 추가해야 합니다. 값의 값은 파일 업로드를 위한 클라이언트 바이트 제한입니다. 파일이 기준치를 초과하면 클라이언트의 대기시간을 줄일 수 있다고 하는데 별 차이는 없는 것 같아요. 3. 보안상의 이유로 파일 필드에는 값 지정이 허용되지 않습니다. 파일 필드에 문자열을 입력하고 제출을 누르면 아무 일도 일어나지 않습니다. 제출은 두 번째 문자가 콜론인 경우에만 "서비스"에 동의해야 합니다(예를 들어 공백 뒤에 콜론이 오면 길이가 0바이트인 "파일"을 업로드할 수 있음). 그러나 이는 클라이언트 측 측정값이며 MAX_FILE_SIZE처럼 우회하기 쉽습니다.

2. 파일 업로드 오류 코드 먼저 단락을 복사하세요. 미리 정의된 변수 $_FILES 배열에는 5개의 내용이 있습니다. $_FILES['userfile']['name'] - 클라이언트 머신 파일의 원래 이름 $_FILES['userfile']['type'] - 파일의 MIME 유형 $_FILES['userfile']['size']——업로드된 파일의 크기(바이트) $_FILES['userfile']['tmp_name']——파일 업로드 후 서버에 저장되는 임시 파일 이름 $_FILES['userfile']['error']——파일 업로드 관련 오류 코드

그 중 $_FILES['userfile']['error']는 다음과 같은 값과 의미를 가질 수 있습니다. 0 - 오류가 발생하지 않았으며 파일이 성공적으로 업로드되었습니다. 1 - 업로드된 파일이 php.ini의 upload_max_filesize 옵션 제한을 초과합니다. 2 - 업로드된 파일의 크기가 HTML 형식의 MAX_FILE_SIZE 옵션에 지정된 값을 초과합니다. 3 - 파일의 일부만 업로드되었습니다. 4 - 업로드된 파일이 없습니다. 1~3은 말할 필요도 없습니다. "파일이 업로드되지 않았습니다"(4)는 양식의 파일 필드에 내용이 없고 빈 문자열임을 의미합니다. "파일이 성공적으로 업로드되었습니다"(0)가 반드시 파일이 실제로 업로드되었음을 의미하는 것은 아닙니다. 예를 들어, 파일 필드에 "c:"를 입력하면 "업로드 성공"이 표시됩니다. 오류 코드는 0이고, ['name']은 "c:"이고, ['type']은 "application/octet입니다. -stream" , ['size']는 0, ['tmp_name']은 "xxx.tmp"입니다(xxx는 서버에서 제공하는 이름입니다). 3. 파일 크기 제한 및 검사 업로드된 파일의 크기를 제한하는 요소는 다음과 같습니다. 1. 클라이언트의 숨겨진 필드 MAX_FILE_SIZE 값(우회 가능) 2. 서버측 upload_max_filesize, post_max_size 및 memory_limit. 이러한 항목은 스크립트를 사용하여 설정할 수 없습니다. 3. 파일 크기 제한 논리를 사용자 정의합니다. 서버의 한계를 스스로 결정할 수 있더라도 개별적인 고려가 필요한 상황이 있을 수 있습니다. 그래서 이 제한 방법이 필요한 경우가 많습니다. 제가 직면한 상황은 보편적이지 않을 수도 있습니다. 설명해 드리겠습니다. 파일이 서버측 제한(upload_max_filesize)보다 훨씬 크지만 post_max_size 또는 memory_limit에 도달하지 않았거나 이에 가까운 경우 $_FILES는 "축소"됩니다. 결과적으로 $_FILES['userfile']은 "정의되지 않은 인덱스"가 됩니다. "물론 할 수 있는 테스트는 없습니다.

서버측 제한 사항 확인은 클라이언트측 제한 사항 확인보다 우선합니다. 즉, 두 제한이 동일하고 파일이 너무 크면 $_FILES['userfile']['error'] 오류 코드 1이 발생합니다. 클라이언트 제한이 서버 제한보다 특정 "정도" 작고 파일 크기가 두 가지를 모두 초과하는 경우에만 오류 코드 2가 나타납니다(이것이 MAX_FILE_SIZE가 예상한 역할을 수행하지 않는다고 느끼는 이유일까요?). 내 컴퓨터에서 테스트한 위의 "레벨"은 3~4K입니다. 내 컴퓨터에 설정된 서버 제한은 2M입니다... 말이 안 되기 때문에 정확한 규칙이 없습니다.

오류 코드 1 또는 2가 발생하는 경우: $_FILES['userfile']['name']은 클라이언트 시스템 파일의 원래 이름입니다. $_FILES['userfile']['type']은 빈 문자열입니다. $_FILES['사용자파일']['크기']는 0입니다. $_FILES['userfile']['tmp_name']은 빈 문자열입니다

四,文件路径检验 file域无输入,错误代码为4(无文件上传) $_FILES['userfile']['name']为空字符串 $_FILES['userfile']['type']为空字符串 $_FILES['userfile']['size']为0 $_FILES['userfile']['tmp_name']为空字符串 file域是非文件路径的字符串(不考虑客户端的假“限制”了),错误代码是0(“上传成功”) $_FILES['userfile']['name']为原字符串 $_FILES['userfile']['type']为application/octet-stream $_FILES['userfile']['size']为0 $_FILES['userfile']['tmp_name']为一个暂时文件名

五,is_uploaded_file()的返回值 手册上面不很详细地说,用法是: bool is_uploaded_file( string filename) 实际上 is_uploaded_file($_FILES['userfile']['name']); 总是返回FALSE。后来看见别人是用: is_uploaded_file($_FILES['userfile']['tmp_name']);

比较一下: file域无输入——————返回FALSE——error=>4,name=>'', tmp_name=>'', type=>'', size=>0 file域为非路径字符串——返回 TRUE——error=>0,name=>'xxx',tmp_name=>'yyy',type=>'zzz',size=>0 文件上传成功——————返回 TRUE——error=>0,name=>'xxx',tmp_name=>'yyy',type=>'zzz',size=>sss 文件太大————————返回FALSE——error=>1,name=>'xxx',tmp_name=>'', type=>'', size=>0 文件太大————————返回FALSE——error=>2,name=>'xxx',tmp_name=>'', type=>'', size=>0 文件部分上传——————没机会试验 —error=>3

有点怀疑这个函数是怎么工作的,还是觉得用$_FILES['userfile']['size']检验好些。

六,检验顺序 if($_FILES['userfile']['error']!=4){//有文件上传 if($_FILES['userfile']['error']!=3){//全部上传了 if($_FILES['userfile']['error']!=1){//不超过服务器端文件大小限制 if($_FILES['userfile']['error']!=2){//不超过客户端文件大小限制 if($_FILES['userfile']['size']>0){//确实是文件 if(......){//自定义文件大小检验逻辑 if(......){//自定义文件类型检验逻辑 if(move_uploaded_file($_FILES['userfile']['tmp_name'],...))//移动文件 //.......... } else give_a_message(...); } else give_a_message(...); } else give_a_message(...); } else give_a_message(...); } else give_a_message(...); } else give_a_message(...); } else give_a_message(...); } 附代码: ------------------------------ 1)、test.php:

<html>
<body>
 <form enctype="multipart/form-data" action="upload.php" method="POST">
     <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
     Send this file: <input name="userfile" type="file" accept="image/x-png,image/gif,image/jpeg"/>
     <input type="submit" value="Send File" />
 </form>
</body>
</html>

2)、upload.php

<html>
<body>
 <?php
  $uploaddir = 'images/';
  $uploadfile = $uploaddir. $_FILES['userfile']['name'];
  print "<pre class="brush:php;toolbar:false">";
  if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
     print "File is valid, and was successfully uploaded.  Here's some more debugging info:\n";
     print_r($_FILES);
  } else {
     print "Possible file upload attack!  Here's some debugging info:\n";
     print_r($_FILES);
  }
  print "
"; ?>
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.