PHP 및 MySQL을 사용하여 크기 조정 이미지를 캐시하는 가장 좋은 방법

StackOverflow https://stackoverflow.com/questions/140734

  •  02-07-2019
  •  | 
  •  

문제

PHP를 사용하여 이미지 캐싱을 처리하는 모범 사례 방법은 무엇입니까?

Filename은 현재 MySQL 데이터베이스에 저장되어 있으며 원래 파일 이름 및 ALT 태그와 함께 업로드의 GUID로 이름이 바뀌 었습니다.

이미지를 HTML 페이지에 넣으면 PHP 스크립트에 다시 작성된 '/images/get/200x200/ {Guid }.jpg와 같은 URL을 사용하여 수행됩니다. 이를 통해 디자이너는 파일 크기를 (대략 소스 이미지를 더 작은) 지정할 수 있습니다.

그런 다음 PHP 스크립트는 크기의 해시 (URL에서 200x200)와 Guid Filename의 해시를 생성하고 파일이 이전에 생성 된 경우 (해시의 이름을 가진 파일이 TMP 디렉토리에 존재 함) 응용 프로그램 TMP 디렉토리에서 파일을 보냅니다. 해시 파일 이름이 존재하지 않으면 디스크에 작성되어 같은 방식으로 제공됩니다.

이것이 가능합니까? (또한 이미지의 워터 마킹을 지원하고 워터 마킹 설정은 해시에도 저장되어 있지만 이에 대한 범위는 없습니다.)

도움이 되었습니까?

해결책

Dan Udey의 재 작성 예제에는 두 개의 오타가 있습니다 (그리고 나는 그것에 대해 언급 할 수 없습니다).

RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]

문안 인사.

다른 팁

나는 다른 방식으로 그것을 할 것입니다.

문제 : 1. PHP를 제공하는 것은 파일을 제공하는 것이 가능한 것보다 덜 효율적입니다. 2. PHP는 이미지가 요청 될 때마다 파일의 존재를 점검해야합니다. 3. Apache는 PHP보다 훨씬 더 좋습니다.

여기에는 몇 가지 해결책이 있습니다.

당신이 사용할 수있는 mod_rewrite 아파치에서. mod_rewrite를 사용하여 파일이 존재하는지 테스트하고 그렇다면 해당 파일을 대신 제공 할 수 있습니다. 이것은 PHP를 완전히 우회하고 훨씬 더 빨리 만듭니다. 그러나이 작업을 수행하는 실제 방법은 항상 존재 해야하는 특정 URL 스키마를 생성 한 다음 그렇지 않은 경우 PHP로 리디렉션하는 것입니다.

예를 들어:

RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]

따라서 클라이언트가 요청하는 경우 /images/cached/<something> 그리고 해당 파일은 아직 존재하지 않으므로 Apache는 요청을 다음으로 리디렉션합니다. /images/generate.php?/images/cached/<something>. 이 스크립트는 이미지를 생성하고 캐시에 작성한 다음 클라이언트로 보낼 수 있습니다. 앞으로 새로운 이미지를 제외하고 PHP 스크립트는 호출되지 않습니다.

캐싱을 사용하십시오. 다른 포스터가 말했듯이, 같은 것을 사용하십시오 mod_expires, 조건부 GET 요청에 응답하기 위해 최종 수정 헤더 등. 클라이언트가 이미지를 다시 요청할 필요가 없으면 페이지로드가 급격히 빠르고 서버의로드가 줄어 듭니다.

PHP에서 이미지를 보내야하는 경우 사용할 수 있습니다. mod_xsendfile 덜 오버 헤드로 수행합니다. 보다 Arnold Daniels의 훌륭한 블로그 게시물 이 문제에 대해서는 그의 예는 다운로드를위한 것입니다. 이미지를 인라인으로 제공하려면 Content-Disposition 헤더 (The Third Header () 호출)를 꺼내십시오.

이것이 도움이되기를 바랍니다 - 내 편두통이 정리 된 후 더 많은 것이 도움이되기를 바랍니다.

추가 할 가치가있는 메모 중 하나는 코드가 이러한 이미지의 "무단"크기를 생성하지 않도록하는 것입니다.

따라서 다음 URL은 아직 존재하지 않으면 200x200 버전의 이미지 1234를 생성합니다. ID 고도로 요청 된 URL에 지원하는 이미지 크기가 포함되어 있는지 확인하십시오.

/images/get/200x200/1234.jpg

악의적 인 사람은 임의의 URL을 요청하기 시작하여 항상 이미지의 높이와 너비를 변경합니다. 이로 인해 서버가 몇 가지 심각한 문제를 일으킬 수 있습니다.

/images/get/0x1/1234.jpg
/images/get/0x2/1234.jpg
...
/images/get/0x9999999/1234.jpg
/images/get/1x1/1234.jpg
...
etc

다음은 다음과 같은 임의의 코드입니다.

<?php

    $pathOnDisk = getImageDiskPath($_SERVER['REQUEST_URI']);

    if(file_exists($pathOnDisk)) {
        // send header with image mime type 
        echo file_get_contents($pathOnDisk);
        exit;
    } else {
        $matches = array();
        $ok = preg_match(
            '/\/images\/get\/(\d+)x(\d+)\/(\w+)\.jpg/', 
            $_SERVER['REQUEST_URI'], $matches);

        if(! $ok) {
            // invalid url
            handleInvalidRequest();
        } else {
            list(, $width, $height, $guid) = $matches;

            // you should do this!
            if(isSupportedSize($width, $height)) {
                // size is supported. all good
                // generate the resized image, save it & output it
            } else {
                // invalid size requested!!!
                handleInvalidRequest();
            }
        }
    }

    // snip
    function handleInvalidRequest() {
        // do something w/ invalid request          
        // show a default graphic, log it etc
    }
?>

좋은 게시물처럼 보이지만 내 문제는 여전히 해결되지 않은 채 남아 있습니다. 호스트 제공 업체에서 htaccess에 액세스 할 수 없으므로 Apache 조정에 대한 의문이 없습니다. 이미지에 대한 CACE-Control 헤더를 설정하는 방법이 있습니까?

귀하의 접근 방식은 상당히 합리적으로 보입니다. 캐시 된 버전이 생성 된 날짜가 원본 (출처) 이미지 파일의 마지막 수정 타임 스탬프 이후에 캐시 된/크기가 크기가 크기가 크게 재생되지 않은지 확인하기 위해 일부 메커니즘을 마련해야한다고 덧붙입니다. . 이렇게하면 디자이너가 이미지를 변경하면 캐시가 적절하게 업데이트됩니다.

그것은 확실한 방법처럼 들립니다. 다음 단계는 PHP/MySQL을 넘어서는 것입니다.

아마도, 헤더를 조정하십시오:

PHP를 사용하여 MIME 유형을 보내는 경우 'Keep-Alive'및 'Cache-Control'헤더를 사용하여 서버의 이미지 수명을 연장하고 PHP/MySQL의 일부로드를 제거 할 수도 있습니다.

또한 캐싱 용 Apache 플러그인도 고려하십시오. 처럼 mod_expires.

오, 한 가지 더, 서버를 통해 얼마나 많은 제어력이 있습니까? 이 대화를 제한해야합니다 단지 php/mysql?

PHP에서 리디렉션 헤더를 사용하여 단순히이 작업을 수행했습니다.

if (!file_exists($filename)) {  

    // *** Insert code that generates image ***

    // Content type
    header('Content-type: image/jpeg'); 

    // Output
    readfile($filename);    

} else {
    // Redirect
    $host  = $_SERVER['HTTP_HOST'];
    $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    $extra = $filename;
    header("Location: http://$host$uri/$extra");
}

DB에 파일 주소를 유지하는 대신 사용자가 로그인 할 때마다 파일 이름에 임의 번호를 추가하는 것이 좋습니다. 사용자 1234 : image/picture_1234.png? rnd = 6534122341

사용자가 세션 중에 새 사진을 제출하면 난수를 새로 고침합니다.

안내는 캐시 문제를 100%다루냅니다. 그러나 사진 파일을 추적하기가 더 어려워집니다. 이 방법을 사용하면 향후 로그인에서 사용자가 동일한 사진을 다시 볼 수 있습니다. 그러나 10 억 숫자에서 난수를 생성하면 확률이 낮습니다.

phpthumb 크기가 조정 된 이미지/썸네일을 즉시 생성하는 프레임 워크입니다. 또한 캐싱을 구현하고 구현하기가 매우 쉽습니다.

이미지 크기를 조정하는 코드는 다음과 같습니다.

<img src="/phpThumb.php?src=/path/to/image.jpg&w=200&amp;h=200" alt="thumbnail"/>

200 x 200의 축소판을 제공합니다.

또한 워터 마킹도 지원합니다.

다음에서 확인하십시오.http://phpthumb.sourceforge.net/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top