PHP 출력 캐시 함수 ob_start, 플러시, ob_flush 사용법에 대한 자세한 설명

伊谢尔伦
풀어 주다: 2023-03-11 10:16:02
원래의
1470명이 탐색했습니다.

php.ini를 수정한 후에는 Apache 서비스 라인을 다시 시작해야 한다는 점에 유의하세요!

for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  flush();
  sleep(1);
}
로그인 후 복사

PHP 캐시 출력 제어 기능을 배운 친구들은 위의 코드에 익숙할 것입니다. 달성하려는 효과는 전체 출력을 완료하는 데 10초가 걸립니다. 실제 실행을 해보면 이상한 현상을 발견하게 되는데 어떤 사람은 어떤 사람은 기대한 대로 동작하는데 어떤 사람은 어떤 사람은 10초 후에 10개의 숫자가 한꺼번에 출력되기도 합니다. 나는 이것에 대해 미쳤다. IE의 캐시가 출력되기 전에 256 자에 도달해야하기 때문에 이런 상황이 자주 발생한다고 친구가 메시지를 남겼습니다. 그러나 실제로 IE의 상황도 이전에 고려했지만 여전히 작동합니다. 작동하지 않습니다. 오늘 설명서를 자세히 읽어보니 이런 예측할 수 없는 현상에는 이유가 있다는 것을 깨달았습니다.

php.ini에는 php의 캐시 출력 제어에 영향을 미치는 두 가지 주요 매개변수가 있는 것으로 나타났습니다.

매개변수 1: 출력_버퍼링: on/off 또는 정수. on으로 설정하면 캐시 크기를 제한하지 않고 모든 스크립트에서 출력 캐시 제어가 사용됩니다. output_buffering=4096과 같은 정수로 설정하면 캐시 데이터가 4096바이트에 도달하면 캐시가 자동으로 출력되고 새로 고쳐집니다. 이 매개변수의 차이는 위의 코드가 시점에 따라 실행 결과가 달라지는 이유입니다. output_buffering을 끄면 스크립트의 모든 출력(echo)이 즉시 클라이언트로 전송됩니다. 위 코드가 실행되면 1초마다 숫자가 출력됩니다. output_buffering이 켜진 후 출력 콘텐츠는 먼저 서버에 캐시되고 스크립트가 끝날 때까지 클라이언트로 전송되지 않습니다.

매개변수 2: implicit_flush: 켜기/끄기. ON으로 설정하면 스크립트에 출력이 있을 때 자동으로 클라이언트에 즉시 전송됩니다. 이는 echo 뒤에 자동으로 플러시()를 추가하는 것과 동일합니다.

PHP 캐시 출력 제어 관련 함수:

ob_start()

첫 번째 매개변수: 콜백 함수, 선택 사항. 출력은 캐시되기 전에 필터링되거나 처리될 수 있습니다. 가장 일반적인 사용법은 캐시된 데이터를 클라이언트에 보내기 전에 gzip으로 압축하는 ob_start('ob_gzhandler')입니다.

두 번째 매개변수: 캐시 블록의 크기, 선택사항. 캐시된 콘텐츠가 캐시 블록 크기에 도달하거나 이를 조작하는 경우 캐시가 자동으로 제거됩니다. 기본값은 0으로, 크기에 제한이 없으며 캐시가 끝까지 캐시된다는 의미입니다. 또한 Chunk_size=4096을 나타내는 특수 값 1도 있습니다.

세 번째 매개변수: 캐시를 지울지 여부, 선택 사항, 기본값은 true입니다. false로 설정하면 스크립트 실행이 끝나기 전에 캐시가 지워지지 않습니다.

ob_get_contents()를 사용하여 서버측 캐시 데이터를 문자열 형식으로 가져올 수 있고, ob_end_flush()를 사용하여 캐시된 데이터를 출력하고 캐시를 닫을 수 있습니다.

ob_end_clean()을 사용하면 데이터나 다른 작업 없이 서버에 캐시된 데이터가 자동으로 지워집니다.

서버측 캐시는 스택되어 있습니다. 즉, ob_start()를 활성화한 후 이를 닫기 전에 그 안에 있는 또 다른 캐시 ob_start()를 열 수도 있다는 의미입니다. 그러나 캐시를 켜는 작업 수만큼 캐시를 끄는 작업도 있는지 확인해야 합니다.

ob_start()는 캐시된 데이터를 처리하는 콜백 함수를 지정할 수 있습니다. 하나의 ob_start()가 다른

ob_start() 내에 중첩된 경우 외부 ob_start()의 번호는 A이고 내부 레이어는 ob_start()의 개수는 B개입니다. 이들은 각각 functionA와 functionB라는 콜백 함수를 가지고 있습니다. B의 데이터가 캐시되어 출력되면 먼저 funcitonB 콜백 함수에 의해 처리된 후 외부 functionA 콜백으로 전달됩니다. 그런 다음 클라이언트에 출력할 수 있습니다.

또한 설명서에는 Apache와 같은 일부 웹 서버의 경우 콜백 함수를 사용하면 프로그램의 현재 작업 디렉터리가 변경될 수 있다고 나와 있습니다. 해결 방법은 콜백 함수에서 작업 디렉터리를 다시 수동으로 수정하고 사용하는 것입니다. chdir 함수는 자주 발생하지 않는 것 같으니, 이 함수를 만날 때 매뉴얼을 확인하는 것을 기억하세요.

flush() 및 ob_flush()

이 두 함수의 사용은 아마도 많은 사람들에게 가장 혼란스러운 문제일 것입니다. 매뉴얼에서 두 함수에 대한 설명도 불분명하고, 차이점이 명확하게 지적되지 않습니다. 두 가지 기능 모두 출력 캐시를 새로 고치는 것 같습니다. 그러나 기사 시작 부분의 코드에서, 만약 플러시()가 ob_flush()로 대체된다면, 프로그램은 더 이상 올바르게 실행되지 않을 것입니다. 분명히 둘 사이에는 차이가 있지만, 그 중 하나가 다른 기능의 별칭이라고 매뉴얼에 직접 명시하는 것만으로도 충분할 것입니다. 그렇다면 그들 사이의 차이점은 무엇입니까?

反复研究了手册的说明,参考了手册中一些人的留言,自己琢磨应该是这样的:

在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态,flush()可以将等待输出的内容立即发送到客户端。

开启缓存后,脚本输出的内容存入了输出缓存中,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端,这时你就需要先使用ob_flush()再使用flush(),客户端才能立即获得脚本的输出。

也就是说本文开头的脚本,可以根据缓存开启与否,有如下几种不同的写法:

注:以下代码都未考虑IE缓存必须大于256字节才输出的问题,如在IE下测试,请在代码开始加一句:“echo str_repeat('',256)”

写法1:

output_buffering = off
implicit_flush=off
 
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  flush();
  sleep(1);
}
로그인 후 복사

写法2:

output_buffering = on
implicit_flush=off
 
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  ob_flush();
  flush();
  sleep(1);
}
로그인 후 복사

写法3:

output_buffering = off
implicit_flush=off
 
ob_start();
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  ob_flush();
  flush();
  sleep(1);
}
로그인 후 복사

写法4:

output_buffering = on
implicit_flush=off
 
ob_end_flush();
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  flush();
  sleep(1);
}
로그인 후 복사

写法5:

output_buffering = on
implicit_flush=off
 
ob_end_clean();
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  flush();
  sleep(1);
}
로그인 후 복사

写法6:

output_buffering = on;
implicit_flush=on
 
ob_end_clean();
// 或者ob_end_flush();
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  sleep(1);
}
로그인 후 복사

写法7:

output_buffering = on;
implicit_flush=on
 
ob_end_clean();
// 或者ob_end_flush();
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  flush();
  sleep(1);
}
로그인 후 복사

写法8:

output_buffering = off
implicit_flush=on
 
for($i=0;$i<10;$i++) {
  echo $i.&#39;<br />&#39;;
  sleep(1);
}
로그인 후 복사

 

위 내용은 PHP 출력 캐시 함수 ob_start, 플러시, ob_flush 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿