2013-02-27 2 views
0

나는 파일을 서버에 간단하게 저장하는 프로젝트를 가지고있다. 누군가 파일을 다운로드하려고 할 때 파일에 대한 보호 기능을 제공하기 위해 중간 컨트롤러 (Zend 프레임 워크)를 통해 요청을 전달해야합니다.왜이 PHP가 파일을 보내 데이터를 변조합니까?

누군가가 파일을 요청하면 파일은 클라이언트 브라우저로 다운로드됩니다. 모든 테스트에서 파일은 항상 손상되지만 (바이트에 맞는 크기 임에도 불구하고). 누군가 내가 여기서 잘못하고있는 것을 말해 줄 수 있습니까?

public function downloadAction() { 
    $this->_helper->layout->disableLayout(); 
    $this->_helper->viewRenderer->setNoRender(true); 

    $files = new Application_Model_DbTable_Files(); 

    $file = $files->getFileForDownload($this->_getParam('id'), Zend_Auth::getInstance()->getIdentity()->id); 

    $config = Zend_Registry::get('config'); 

    $this->_helper->layout->disableLayout(); 
    $this->_helper->viewRenderer->setNoRender(); 


    if (file_exists($config['mindful']['path'] . $file)) { 
     $this->getResponse()->setHeader('Content-type', 'application/octet-stream'); 
     $this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false); 
     $this->getResponse()->setBody(readfile($config['mindful']['path'] . $file)); 
    } 
} 

내가 알기로 표준 PHP뿐만 아니라 Zend 메소드를 사용해 보았습니다. 이 두 가지 모두 저에게 같은 결과를줍니다.

미리 도움을 청하십시오! 많은 프레임 워크에 파일 다운로드에 문제가 발생할 수 있습니다

+0

아마도 캐릭터 인코딩 문제일까요? – Babblo

+0

파일이 손상되었다고 어떻게 판단합니까? 파일의 종류는 무엇입니까? – datasage

+0

어떻게 손상 되었습니까? 두 파일의 바이트 단위 비교를 수행 했습니까? –

답변

2

한 가지는 이들은 후 일반적으로 발생하는 손실 \ n을 무엇입니까? PHP의 >을 실행하면 예상치 못한 \ n이 (가) 데이터로 전송됩니다. 이러한 \ n은 HTML을 보낼 때 전혀 해가 없지만 다른 파일은 손상됩니다.

PHP 스크립트는 PHP 태그를 닫을 필요가 없으며 닫지 않는 것이 좋습니다. PHP 템플릿 (보기에서)을 사용하는 경우 예외가 발생합니다. PHP 템플릿을 분명히 닫아야 만합니다.

  • ? 당신이 (컨트롤러 포함)에 액세스하는 컨트롤러에 의해 사용되는 모든 모델과 구성 요소의 > 태그
  • 것은 더
  • 당신이 레이아웃과 뷰 렌더링을 사용할 수 있는지 확인 동일한 파일의 <? php에 태그 전에 입력이 없는지 확인 이 작업에 대해 (올바르게 수행 된 것 같습니다)
+0

Nailed it! 한 클래스의 내 MediaGiantDesign

1

readfile은 파일 내용을 반환하지 않고 즉시 출력합니다. 반환 값은 바이트 수이므로 현재 응답 본문에 추가되고 있습니다. 이것은 아마도 부패를 일으키는 원인 일 것입니다.

먼저 헤더를 전송하고 바로 직접 호출하여 readfile을 계속 사용할 수 있습니다 :

$this->getResponse()->setHeader('Content-type', 'application/octet-stream'); 
$this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false); 
$this->getResponse()->sendHeaders(); 

readfile($config['mindful']['path'] . $file); 

또는 파일이 매우 작은 경우, 당신은 현재의 접근 방식을 고수하고 대신 file_get_contents을 사용할 수

$this->getResponse()->setBody(file_get_contents($config['mindful']['path'] . $file)); 

이러한 방식 중 어떤 것도 캐싱을 제공하지 않습니다 (예 : 헤더 이후 수정 된 경우 처리).

X-Sendfile을 사용하면 더 많은 메모리를 사용할 수 있으며 캐싱 헤더를 처리 할 수 ​​있습니다.

+0

확실히 file_get_contents가 좋습니다. 그것은 해결책이 아니었지만, 내가 겪었던 전송 한계 문제를 극복했습니다. – MediaGiantDesign

관련 문제