현재 위치: > 최신 기사 목록> 사용 중에 메모리 오버 플로우 문제가 발생할 때 Fpassthru 기능을 어떻게 문제 해결하고 해결해야합니까?

사용 중에 메모리 오버 플로우 문제가 발생할 때 Fpassthru 기능을 어떻게 문제 해결하고 해결해야합니까?

gitbox 2025-06-27

PHP에서 fpassthru () 함수는 파일 포인터가 가리키는 파일 내용을 직접 출력하는 데 사용되며 일반적으로 파일 작업과 관련된 코드와 함께 사용됩니다. 이 기능을 사용할 때 특히 파일이 크거나 시스템이 구성되지 않은 경우 메모리가 너무 많은 메모리를 처리 할 수 ​​없기 때문에 프로그램이 충돌 할 수 있습니다. 이 기사는 메모리 오버 플로우 문제를 효과적으로 문제 해결하고 해결하는 방법을 소개합니다.

1. fpassthru () 함수가 어떻게 작동하는지 이해하십시오

fpassthru () 함수의 함수는 파일 포인터를 가리키는 현재 위치를 읽고 파일 컨텐츠를 브라우저 또는 터미널에 출력하는 것입니다. 일반적으로 fpassthru ()는 비디오 스트림, 이미지, 로그 등과 같은 큰 파일 콘텐츠가 PHP를 통해 출력되는 시나리오에 적합합니다. 기본 사용법은 다음과 같습니다.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">'example.txt'</span></span><span>, </span><span><span class="hljs-string">'rb'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$file</span></span><span>) {
    </span><span><span class="hljs-title function_ invoke__">fpassthru</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

위의 코드는 파일을 열고 fpassthru () 를 통해 파일의 내용을 출력합니다. 파일이 크거나 시스템이 부적절하게 구성된 경우 출력 컨텐츠가 너무 많은 메모리를 차지하기 때문에 메모리 오버플로가 발생할 수 있습니다.

2. 메모리 오버플로의 원인

fpassthru () 함수를 사용하는 경우 메모리 오버플로는 일반적으로 다음과 같은 이유에 기인합니다.

2.1 큰 파일 작동

파일이 크면 PHP는 전체 파일의 내용을 읽고 출력해야합니다. 큰 파일 (예 : 1GB 이상의 파일)의 경우 직접 출력이 많은 메모리를 차지합니다. PHP로 구성된 메모리 제한 ( Memory_Limit )이 낮은 경우 파일의 읽기 및 출력이 허용 메모리 범위를 초과하여 메모리 오버플로를 초래합니다.

2.2 출력 버퍼 제한

PHP에는 기본 출력 버퍼가 있습니다. 파일의 내용이 너무 크면 시스템은 전체 컨텐츠를 버퍼에로드 한 다음 출력하려고 시도 할 수 있습니다. 이 프로세스 동안 버퍼가 이러한 많은 양의 데이터를 처리 할 수 ​​없으면 메모리 오버플로를 유발할 수 있습니다.

2.3 파일 스트림 및 PHP 메모리 관리 문제

PHP는 큰 파일을 처리하기 위해 특별히 설계되지 않았습니다. 특히 파일이 fpassthru () 를 통해 직접 출력 할 때 PHP는 파일 컨텐츠를 읽고 출력 버퍼로 넘겨 주려고합니다. 시스템 리소스 또는 구성이 이러한 고 부하 작업을 지원할 수없는 경우 메모리 문제를 쉽게 일으킬 수 있습니다.

3. 메모리 오버플로 문제를 해결하는 방법 문제

3.1 PHP 메모리 제한을 늘립니다

먼저 PHP의 메모리 제한이 큰 파일의 출력을 처리하기에 충분한 지 확인하십시오. php.ini 파일을 수정하여 메모리 제한을 늘릴 수 있습니다.

 <span><span><span class="hljs-attr">memory_limit</span></span><span> = </span><span><span class="hljs-number">512</span></span><span>M
</span></span>

php.ini를 직접 수정할 수없는 경우 스크립트에서 동적으로 설정할 수 있습니다.

 <span><span><span class="hljs-title function_ invoke__">ini_set</span></span><span>(</span><span><span class="hljs-string">'memory_limit'</span></span><span>, </span><span><span class="hljs-string">'512M'</span></span><span>);
</span></span>

메모리 한계를 늘리면 메모리가 불충분 한 오버플로 문제를 피할 수 있습니다.

3.2 청크의 파일을 읽습니다

전체 파일을 한 번에 메모리에로드하지 않으려면 fpassthru () 함수에 대한 대안을 사용하여 청크에서 파일을 읽고 블록으로 블록으로 출력하여 메모리 사용을 줄일 수 있습니다. Fread ()를 사용하여 파일 내용을 단계별로 읽은 다음 Echo 출력을 사용할 수 있습니다. 예는 다음과 같습니다.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">'example.txt'</span></span><span>, </span><span><span class="hljs-string">'rb'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$file</span></span><span>) {
    </span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>); </span><span><span class="hljs-comment">// 각각 읽습니다 8KB</span></span><span>
    }
    </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

이 방법은 전체 파일의 내용을 한 번에로드하지 않으므로 큰 파일을 처리 할 때 메모리 사용량을 크게 줄일 수 있습니다.

3.3 출력 버퍼 크기를 조정하십시오

PHP의 출력 버퍼는 메모리 오버플로의 원인 중 하나 일 수 있습니다. 많은 양의 데이터를 출력 할 때 버퍼는 OB_CLEAN ()FLUSH () 를 통해 제어 할 수 있습니다. 예를 들어:

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-title function_ invoke__">ob_clean</span></span><span>();
</span><span><span class="hljs-title function_ invoke__">flush</span></span><span>();
</span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">'largefile.txt'</span></span><span>, </span><span><span class="hljs-string">'rb'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$file</span></span><span>) {
    </span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>);  </span><span><span class="hljs-comment">// 각각 읽습니다 8KB</span></span><span>
        </span><span><span class="hljs-title function_ invoke__">flush</span></span><span>();  </span><span><span class="hljs-comment">// 출력 버퍼를 지우십시오</span></span><span>
    }
    </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

Flush ()를 사용하면 데이터가 즉시 브라우저로 전송되고 버퍼에 과도한 컨텐츠가 축적되지 않도록합니다.

3.4 파일이 너무 큰지 확인하십시오

매우 큰 파일의 경우 파일 크기를 확인하고로드하기 전에 청킹 처리가 필요한지 여부를 결정할 수 있습니다. 예를 들어 Filesize () 함수를 사용하여 파일의 크기를 가져 와서 청크로 처리할지 여부를 결정할 수 있습니다.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$file_path</span></span><span> = </span><span><span class="hljs-string">'largefile.txt'</span></span><span>;
</span><span><span class="hljs-variable">$file_size</span></span><span> = </span><span><span class="hljs-title function_ invoke__">filesize</span></span><span>(</span><span><span class="hljs-variable">$file_path</span></span><span>);

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$file_size</span></span><span> &gt; </span><span><span class="hljs-number">1000000000</span></span><span>) {  </span><span><span class="hljs-comment">// 파일이보다 큰 경우 1GB</span></span><span>
    </span><span><span class="hljs-comment">// 청킹 처리를 수행하십시오</span></span><span>
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-comment">// 직접 사용하십시오 fpassthru()</span></span><span>
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

4. 기타 최적화 제안

4.1 스트리밍 사용

매우 큰 파일의 경우 PHP를 통해 전체 파일을 읽고 출력하는 대신 HTTP 헤더를 통해 파일을 직접 전송하는 것과 같은 스트리밍 기술이 권장됩니다. 적절한 HTTP 헤더는 다음 코드를 사용하여 설정할 수 있습니다.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-title function_ invoke__">header</span></span><span>(</span><span><span class="hljs-string">'Content-Type: application/octet-stream'</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">header</span></span><span>(</span><span><span class="hljs-string">'Content-Disposition: attachment; filename="largefile.txt"'</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">header</span></span><span>(</span><span><span class="hljs-string">'Content-Length: '</span></span><span> . </span><span><span class="hljs-title function_ invoke__">filesize</span></span><span>(</span><span><span class="hljs-string">'largefile.txt'</span></span><span>));
</span><span><span class="hljs-title function_ invoke__">readfile</span></span><span>(</span><span><span class="hljs-string">'largefile.txt'</span></span><span>);
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

이 방법은 파일 내용을 PHP 메모리에로드 할 필요가 없지만 하드 디스크에서 직접 스트리밍하여 메모리 소비가 크게 줄어 듭니다.

4.2 특수 도구를 사용하십시오

대규모 파일 처리의 경우 PHP 외에도 FFMPEG (비디오 파일 처리) 또는 ImageMagick (이미지 파일 처리)과 같은 큰 파일 처리를 전문으로하는 일부 도구 또는 라이브러리를 사용하는 것을 고려할 수도 있습니다. 이러한 도구는 메모리 오버플로를 피하기 위해 백그라운드에서 스트리밍 할 수 있습니다.

5. 요약

fpassthru () 함수가 편리하지만 큰 파일을 처리 할 때 메모리 오버플로 쉽게 유발할 수 있습니다. 이 문제를 피하기 위해 메모리 제한을 조정하고 블록별로 파일을 읽거나 출력 버퍼 제어 등을 조정하여 코드를 최적화 할 수 있습니다. 파일이 매우 크면 파일 스트리밍 또는 처리를 위해 특수 도구를 사용하는 것을 고려할 수도 있습니다. 이러한 방법을 통해 메모리 오버플로 문제를 효과적으로 피할 수 있으며 응용 프로그램의 안정성과 성능을 향상시킬 수 있습니다.