2009-08-19 2 views
1

많은 예제를 보았지만 현재 업로드 스크립트를 어떻게 묶을 수 있는지 잘 모르겠습니다. 누군가 w : h 비율을 유지하면서 ImageMagick 등을 사용하여 업로드 된 이미지의 크기를 고정 폭으로 조정할 수있는 방법을 설명해 주시겠습니까?PHP 이미지 크기 조정 및 내 업로드 스크립트

나는 인터넷 검색을하고 150 개가 넘는 웹 페이지를 보았지만 그 중 아무도 내 상황에 맞는 느낌을주는 사례는 제공하지 않았다. 어떤 도움을 주시면 감사하겠습니다. 여기 내 코드는 다음과 같습니다

// Include Extension finder function. 
include_once 'find_extension.php'; 

    // Function Gathers the Input Name, Store Number and Picture Number. The picture number is assigned by the loop that will be cycling through the images to be uploaded. The store Number and the Picure Number will make the file name. 
    function uploadImage($inputname, $storenum, $picturenum){ 

// A few parameters, to restrict file types and file size to 20kb. 
if ((($_FILES[$inputname]["type"] == "image/gif") 
|| ($_FILES[$inputname]["type"] == "image/png") 
|| ($_FILES[$inputname]["type"] == "image/jpeg") 
|| ($_FILES[$inputname]["type"] == "image/pjpeg")) 
&& ($_FILES[$inputname]["size"] < 200000)) 
    { 
     // If there is an error, echo the error, if not continue. 
    if ($_FILES[$inputname]["error"] > 0){ 
     echo "Error: " . $_FILES[$inputname]["error"] . "<br />"; 
    }else{ 
     // Echo out File information. 
/* echo "Upload: " . $_FILES[$inputname]["name"] . "<br />"; 
    echo "Type: " . $_FILES[$inputname]["type"] . "<br />"; 
    echo "Size: " . ($_FILES[$inputname]["size"]/1024) . " Kb<br />"; 
    echo "Stored in: " . $_FILES[$inputname]["tmp_name"]; */ 
    } 

    // Get the extension so we can rename using the previous function. 
    $ext = findexts($_FILES[$inputname]["name"]); 

    $newpicturename = $storenum . $picturenum . "." . $ext; 
    // Check to see if the file exists, if it does then tell the user. If not continue. 
    if (file_exists("userimages/" . $newpicturename)){ 

     echo "<br>" . $newpicturename . " already exists. "; 

     }else{ 

    // Uploads the file. 
     move_uploaded_file($_FILES[$inputname]["tmp_name"], "userimages/" . $newpicturename); 

    $picturefield = "picture" . $picturenum; 
    $picturepath = "userimages/" . $newpicturename; 
    //Inserts data into ad DB 
    mysql_query("UPDATE storead SET $picturefield='$picturepath' WHERE storenum='$storenum'"); 
    // Tells the User. 
    // echo "Stored in: " . "userimages/" . $newpicturename; 
     } 

    }else{ 
     // If the upload does not meet the parameters above, then tell the user and cancel. 
     echo "Error uploading " . $_FILES[$inputname]["name"] . ". File may be too large or of unnacepted format."; 
    } 

} 

당신을 :) 감사

답변

3

대신 인 move_uploaded_file(), 당신은 이미지 처리 라이브러리에 파일을로드 크기를 조정하고, 그것을 저장 것의.

예 : GD를 사용하여 imagecreatefromgif(), imagecreatefromjpeg() 또는 imagecreatefrompng() (원하는 형식에 따라 다름)로 시작한 다음 imagecreatetruecolor()를 사용하여 원하는 축소판 크기의 새 이미지를 만들고 imagecopyresampled(). 마지막으로 원하는 형식에 따라 imagegif()/imagejpeg()/imagepng()를 사용하여 결과를 저장하십시오.

가로 세로 비율을 유지하면서 고정 너비를 원하는 경우 대상 크기를 쉽게 결정할 수 있습니다. new_height = round_to_whole_pixels (new_width * original_height/original_width). 그러나 누군가가 1x2000 픽셀 이미지를 업로드한다고 가정 할 때 정당성 검사를 할 가치가 있습니다. 200 픽셀의 폭을 목표로하면 서버의 모든 메모리를 먹을 수있는 엄청난 이미지 인 200x400000까지 날려 버릴 것입니다! 따라서 max_height도 있습니다.

마지막으로, 스크립트에는 너무 많은 심각한 보안 허점이 포함되어 있습니다. 인터넷에 공개하기 전에 먼저 디렉토리 트래버스 공격, SQL 삽입, HTML 삽입 (XSS) 및 파일 업로드 유형 스니핑 취약점 (예 : HTML을 이미지 파일로 위장한 HTML에 삽입)에 대해 알아야합니다.

ETA :

는이 웹 사이트는 대부분의 기초를 다루고 생각하십니까?

아니지만 시작일뿐입니다. 이 조언 :

업로드 폴더에 업로드 된 파일을 배치 할 때 파일의 이름을 임의의 이름으로 바꾸고 데이터베이스에서 파일 이름을 추적하십시오.

은 매우 중요합니다. 사용자가 제출 한 파일 이름을 신뢰할 수 없습니다. 파일 이름은 당신이 생각하는 것보다 더 복잡하고, 그들이 악성하려고하지 않는 경우에도, 파일 이름이 잘못 될 수있는 많은 이상한 방법이 있습니다 :

  • 일부 브라우저 파일 leafnames, 일부 전체 경로를 제출, 그리고 당신 돈 클라이언트 시스템에서 파일 경로의 형식을 알지 못합니다 (다양한 플랫폼의 디렉토리 구분 기호에는 '/', '\', ':', '.'등이 포함될 수 있습니다).

  • 주어진 파일 이름에 허용되지 않는 문자가 포함되면 어떻게됩니까? 제어 문자? 유니 코드 문자?

  • Windows 서버를 사용하는 경우 'com'과 같이 무해한 이름이지만 예약 된 이름으로 파일을 만들어보십시오. 그러면 자국이 올 것입니다.또한 Windows는 자동으로 스크립트를 혼란스럽게 할 수있는 방식으로 후행 공백과 점을 버립니다.

후자는 연결된 스크립트의 잠재적 보안 허점입니다. 파일 이름 끝에 '.php'와 같은 '잘못된'파일 확장자가 있는지 확인합니다. 그러나 'x.php'라는 파일 (공백 포함)을 Windows 서버에 업로드하면 행복하게 받아 들여 'x.php'로 저장합니다. (스크립트에 버그가 있습니다. 정규 표현식에서 '.'을 사용하므로 어떤 문자도 의미하지 않으므로 'poo.potatophp'파일 이름은 .php 확장자로 사용됩니다.)

보통 화이트리스트는 블랙리스트에 올리는 것보다 낫습니다. 오직 예를 허용합니다. '.jpeg'확장 프로그램은 알려진 악성 프로그램을 허용하지 않는 것보다 더 잘 작동합니다. 그러나 제출 된 JPEG 파일의 실제 확장자가 '.jpeg'라는 보장이 없기 때문에 이는 여전히 충분하지 않습니다. Windows에서는 '.jpg'또는 '.pjpeg'또는 클라이언트 시스템에서 JPEG로 매핑되는 다른 확장자가있을 수 있습니다. Mac 또는 Linux에서는 파일 이름 확장자가 전혀 없을 수도 있습니다!

요약하면 파일 업로드 필드와 함께 제출 된 파일 이름/경로는 무시하는 것이 가장 좋습니다. 어쩌면 당신은 이미 알지 못했을 때 그 파일이 어떤 형식 일지 짐작할 수있을 것입니다. 그러나 그 것에 의지 할 수는 없으며, 사용자의 말을 결코 받아 들여서 실제로 그것을 저장해서는 안됩니다. 이름.

내가 언급 한 '이미지 파일로 위장 된 HTML'페이지도 포함되지 않습니다. 사이트의 모든 항목에 대한 완전한 액세스 권한으로 완전히 신뢰할 수없는 파일을 다른 사람이 업로드하도록 허용하는 경우이 문제에 대해 걱정할 필요가 있습니다. 그것에 대해 읽을 수 있습니다 here. PHP 파일 업로드 스크립트 위험에 대한 자세한 내용은 here을 참조하십시오.

, η2는 :

나는 웹 디렉토리 위의 업로드의 제안을 많이 보았다. 그러나 내 스크립트는 여전히 웹 사이트의 방문자에게 이러한 파일을 표시합니다.

네, 시작하기 좋은 곳입니다. 서빙 프로세스를 자신의 손에 맡김으로써 예상치 못한 방식으로 파일 형식을 처리하는 웹 서버의 문제를 피할 수 있으며, 자신의 안전한 파일 이름을 사용할 수 있으며 스크립트에 "Content-Disposition : attachment"헤더를 추가 할 수 있습니다. 대부분 브라우저가 사이트의 보안 컨텍스트에서 비롯된 JavaScript와 같은 액티브 컨텐트를 처리하지 못하게하여 사이트 간 스크립팅 문제를 일으킬 수 있습니다.

이 방법의 단점은 PHP를 통해 파일을 제공하는 것이 웹 서버에 허용하는 것보다 훨씬 느린 입니다. 파일 서핑 스크립트에 HTTP 캐시 헤더를로드하여 문제를 개선 할 수는 있지만 작업이 많으며 C로 작성된 일반적인 웹 서버와 커널 수준의 네트워크를 사용하는 것만 큼 빠른 속도는 아닙니다. 효율성 해킹. 때때로 제공하는 파일의 경우에는 아무런 문제가 없습니다. 바쁜 사이트에서 항상 인기있는 이미지를 보게되면 좋지 않습니다.

또한 Flash에서 Content-Disposition 헤더를 무시하는 문제가있었습니다.이 헤더는 여전히 해당 플러그인을 통해 XSS에 파일을 일으킬 수 있습니다. 이것들은 지금 고쳐졌지만 다른 플러그인과 이상한 브라우저 동작이 무엇인지 알 수 있습니다. 따라서 안전을 위해 신뢰할 수없는 사용자 업로드 파일을 다른 호스트 이름에서 제공하는 것이 가장 좋습니다 (예 : data.example.com과 같은 하위 도메인 이렇게하면 쿠키와 인증 정보가 두 보안 컨텍스트에서 누출됩니다. 파일을 뱉어내는 웹 서버 기반 방법을 찾으러 간다면 반드시이 예방 조치를 취해야합니다.

난 그냥이 작업이 완료 싶어,

그래 너무 복잡 그것의 방법, 그것은 현혹 간단한 작업처럼 보이지만 정말 아니에요. 신뢰할 수없는 업로드로 인해 보안 문제로 인해 매우 주목받는 웹 사이트가 있습니다. Microsoft와 Google의 웹 사용자가 항상 올바르게 할 수 없다면 아마도 입니다.

(PHP의 평소와 같이) 튜토리얼의 99 %는이 종류를 다루는 데 도움이되지 않습니다. 사물은 완전히 허튼 소리 야.

+0

감사합니다. bob, 보안 이미지 업로드에 대한 좋은 자료가 있으십니까? –

+0

당신은이 웹 사이트가 대부분의 기지를 다룰 것이라고 생각합니까? http://www.mysql-apache-php.com/fileupload-security.htm –

+0

Andrew, 나는 이것을하기위한 쉬운 방법을 찾고 있으며 웹 디렉토리 위에 업로드하는 것에 대한 많은 제안을 보았습니다. 그러나 내 스크립트는 여전히 웹 사이트의 방문자에게 이러한 파일을 표시합니다. 확실한 화이트리스트 작성과 결합하여 이것이 안전한 경로라고 생각합니까? 그런 종류의 화이트리스트 작성이 가능합니까? 나는이 일을 끝내기를 원한다. 너무 복잡하다. 고맙습니다!! –

1
list($originalWidth, $originalHeight) = getimagesize($originalFile); 
$width = 250; // whatever your fixed width is 
$height = ceil(($width/$originalWidth) * $originalHeight);

그런 다음 밥의 지시

1
// Get the image data. 
// This REALLY needs some form of security, doing it like in this example is *bad*. 
// There are other functions than "imagecreatefromjpeg" to handle other formats. 
$image = imagecreatefromjpeg($_FILES["userfile"]["tmp_name"]); 

// Get image dimensions. 
$imgX = imagesx($image); 
$imgY = imagesy($image); 

// Get aspect ratio. 
// Biggest dimension is what we will use to constrain the thumbnail. 
if($imgX > $imgY) { 
    $multiplier = 150/$imgX; 
} else { 
    $multiplier = 150/$imgY; 
} 

// Create a scaled down version of the uploaded image. 
$thumb = imagecreatetruecolor($imgX * $multiplier, $imgY * $multiplier); 
imagecopyresampled($thumb, $image, 0,0,0,0, $imgX * $multiplier, $imgY * $multiplier, $imgX, $imgY); 

댓글의 풍부한 맛을 따르십시오! 이 코드는 내 갤러리에서 미리보기 이미지를 만드는 데 사용하는 코드입니다. 내가 볼 수있는 유일한 문제는이 코드가 정사각형으로 제한되기 때문에 축소판을 최대 크기로 제곱 이외의 다른 것으로 사용해야하는 경우입니다.

+0

imagecopyresampled에서 무엇을합니까? 그것이 내가 잃어버린 곳입니다. 임시직으로 돌아 왔습니까? 평소와 같이 파일을 계속 업로드해야합니까? 감사! –

+0

http://php.net/imagecopyresampled 기본적으로 $ image의 크기 조정 된 내용을 $ thumb에 넣습니다. – grimman

관련 문제