찾다

 >  Q&A  >  본문

PHP에서 "헤더가 이미 전송되었습니다" 오류를 수정하는 방법

스크립트를 실행할 때 다음과 같은 여러 오류가 발생합니다.

경고: 헤더 정보를 수정할 수 없습니다. 헤더는 이미 /some/file.php에서 전송되었습니다(출력은 /some/file.php:12에서 시작)

오류 메시지에 언급된 줄에는 header()setcookie() 호출이 포함되어 있습니다.

이유는 무엇일까요? 어떻게 해결하나요?

P粉210405394P粉210405394418일 전569

모든 응답(2)나는 대답할 것이다

  • P粉071602406

    P粉0716024062023-10-10 11:29:08

    HTTP 헤더를 보내기 전에 무엇이든 보내세요(setcookieheader 사용). HTTP 헤더 이전에 무언가를 출력하는 일반적인 이유는 다음과 같습니다.

    • 예기치 않은 공백은 일반적으로 파일의 시작이나 끝 부분에 다음과 같이 표시됩니다.

      으아악

               이를 피하려면 결말을 생략하세요 ?> - 어쨌든 필요하지 않습니다.

    ), 또는 문자열 리터럴 대신 정의되지 않은 상수를 사용합니다($_POST[input]에서와 같이 누락된 따옴표에 주의).

    출력 버퍼링ob_start 后的所有输出都缓冲在内存中,直到您释放缓冲区,例如与 ob_end_flush을 켜면 ob_start

    를 호출한 후의 모든 출력이 ob_end_flush

    .

    🎜그러나 출력 버퍼링을 사용하면 이러한 문제를 피할 수 있지만 애플리케이션이 HTTP 헤더보다 먼저 HTTP 본문을 출력하는 이유를 실제로 확인해야 합니다. 이는 전화를 받고 하루와 날씨에 대해 이야기한 다음 발신자에게 전화를 잘못 걸었다고 말하는 것과 같습니다. 🎜

    회신하다
    0
  • P粉087951442

    P粉0879514422023-10-10 09:54:05

    헤더를 보내기 전에는 출력이 없습니다!

    출력을 수행하기 전에 HTTP 헤더를 전송/수정하는 함수를 호출해야 합니다. 요약⇊ 그렇지 않으면 호출이 실패합니다:

    HTTP 헤더를 수정하는 일부 기능은 다음과 같습니다.

    출력은 다음과 같습니다:

    • 의도적으로:

      • printecho 및 출력을 생성하는 기타 함수
      • 代码之前的原始 부분.

    왜 이런 일이 발생하나요?

    출력하기 전에 헤더를 전송해야 하는 이유를 이해해야 합니다. 일반적인 HTTP 보기 회신하다. PHP 스크립트는 주로 HTML 콘텐츠를 생성하고 웹 서버로 전송된 HTTP/CGI 헤더 세트:

    으아악

    페이지/출력은 항상 제목을 따릅니다. PHP는 통과해야합니다 먼저 헤더가 웹 서버로 전송됩니다. 이 작업은 한 번만 수행할 수 있습니다. 이중 포장 후에는 더 이상 수정할 수 없습니다.

    PHP가 첫 번째 출력(

    , )을 수신하면 printechoRefresh수집된 모든 헤더. 그 후에는 모든 출력을 보낼 수 있습니다 그것은 원한다. 그러나 추가 HTTP 헤더를 보내는 것은 불가능합니다.

    조기 출력이 발생하는 위치를 어떻게 알 수 있나요?

    경고에는 모든 관련 정보가 포함되어 있습니다. 위치 문제의 원인: header()

    여기서 "라인 100"은

    header()호출 하고 실패하는 스크립트를 의미합니다.

    괄호 안의 "

    출력 시작 " 주석이 더 중요합니다. 이전 출력의 소스를 나타냅니다. 이 예에서는 그리고 auth.php번째 줄52. 여기서는 조기 출력을 찾아야 합니다.

    일반적인 이유:

    1. 인쇄 및 에코

      printecho 문의 의도적인 출력으로 인해 HTTP 헤더를 보낼 수 있는 기회가 종료됩니다. 이러한 상황을 방지하려면 신청 프로세스를 재구성해야 합니다. 기능 사용하기 및 템플릿 솔루션. header() 메시지 전에 통화가 발생하는지 확인하세요. 그것은 모두 기록되어 있습니다.

      출력을 생성하는 함수에는 다음이 포함됩니다

      • 打印echoprintfvprintf
      • trigger_errorob_flushob_end_flushvar_dumpprint_r
      • readfilepassthruflushimagepngimagejpeg


      기타 및 사용자 정의 기능.

    2. 원본 HTML 영역

      .php 파일의 구문 분석되지 않은 HTML 부분도 직접 출력됩니다. header() 호출을 트리거하는 스크립트 조건에 주의를 기울여야 합니다. 모든 원본 블록 이전.

      으아아아

      템플릿 체계를 사용하여 처리를 출력 논리와 분리합니다.

      • 스크립트 위에 양식 처리 코드를 배치하세요.
      • 임시 문자열 변수를 사용하여 메시지를 연기하세요.
      • 실제 출력 로직과 혼합 HTML 출력은 마지막에 와야 합니다.

    3. 앞의 공백은 "script.php Line 1" 경고

      를 의미합니다.

      경고가 인라인 출력을 언급하는 경우1, 주로 여는 태그, 텍스트 또는 HTML 앞에 공백 을 입력합니다.

      으아아아

      이는 추가 스크립트나 스크립트 섹션에서도 발생할 수 있습니다.

      으아아아

      PHP는 실제로 태그를 닫은 후 단일 줄 바꿈을 사용합니다. 하지만 그렇지 않을 거야 이러한 간격으로 이동된 여러 개행, 탭 또는 공백을 보상합니다.

    4. UTF-8 BOM

      줄바꿈과 공백만으로는 문제가 될 수 있습니다. 하지만 '보이지 않는' 것도 있다 이 조건을 유발할 수 있는 문자 시퀀스입니다. 가장 유명한 것은 UTF-8 BOM(바이트 순서 표시) 대부분의 텍스트 편집기에는 표시되지 않습니다. 일련의 바이트 EF BB BF,对于 UTF-8 编码的文档来说,它是可选且冗余的。然而 PHP 必须将其视为原始输出。它可能在输出中显示为字符 (클라이언트가 문서를 Latin-1로 해석하는 경우) 또는 이와 유사한 "쓰레기"입니다.

      특히 그래픽 편집기와 Java 기반 IDE에서는 이를 인식하지 못합니다. 참석하세요. (유니코드 표준에서 요구하는 대로) 시각화하지 않습니다. 그러나 대부분의 프로그래머와 콘솔 편집자는 다음을 수행합니다.

      이렇게 하면 문제를 조기에 쉽게 발견할 수 있습니다. 다른 편집자들은 알아볼 수도 있습니다. 파일/설정 메뉴에 있습니다(Windows의 Notepad++는 문제 해결), BOM의 존재를 확인하는 또 다른 옵션은 Hex Editor를 사용하는 것입니다. *nix 시스템에서 hexdump 일반적으로 사용 가능 이러한 질문과 기타 질문의 그래픽 변형 검토를 단순화하지 않는 경우:

      간단한 해결 방법은 파일을 "UTF-8(BOM 없음)"로 저장하도록 텍스트 편집기를 설정하는 것입니다. 또는 유사한 명명법. 초보자는 새 파일을 만든 다음 이전 코드를 다시 복사하여 붙여넣는 방법을 사용하는 경우가 많습니다.

      수정 유틸리티

      텍스트 파일을 확인하고 다시 작성하는 자동화된 도구도 있습니다. (sed/awksed/awk重新编码 또는 recode). PHP의 경우 특히 phptags 태그 tidier입니다. 닫는 태그와 여는 태그를 길고 짧은 형식으로 다시 작성하며 쉽습니다. 선행 및 후행 공백, 유니코드 및 UTF-x BOM 문제 수정:

      으아아아

      전체 포함 또는 프로젝트 디렉토리에 사용해도 안전합니다.

    5. 后有空格?>

      오류의 원인이 나중에 언급되는 경우 닫기 ?> 음, 이곳은 비어 있거나 원시 텍스트가 기록되는 곳입니다. 현재 PHP 닫는 태그는 스크립트 실행을 종료하지 않습니다. 그 뒤의 모든 텍스트/공백 문자는 페이지 콘텐츠로 기록됩니다. 아직.

      일반적으로 특히 초보자에게는 ?> PHP를 따르는 것이 좋습니다. 닫는 태그는 생략해야 합니다. 이렇게 하면 이러한 경우 중 일부를 피할 수 있습니다. (매우 일반적인 include()d 스크립트가 범인입니다.)

    6. 오류의 원인은 "알 수 없는 줄 0"입니다

      오류 소스가 없는 경우 일반적으로 PHP 확장 또는 php.ini 설정입니다. 콘크리트.

      • 가끔 gzip 스트림 인코딩 설정 또는 ob_gzhandler.
      • 그러나 이중 로드 extension= 모듈일 수도 있습니다. 암시적 PHP 시작/경고 메시지를 생성합니다.

    7. 이전 오류 메시지

      다른 PHP 문이나 표현식으로 인해 경고 메시지가 발생하거나 메모가 인쇄되며 이는 조기 출력으로 간주됩니다.

      이 경우에는 실수를 피해야 하며, 명령문 실행을 지연하거나 다음을 사용하여 메시지를 억제합니다. isset()isset()@() 또는 @() - 둘 중 하나가 나중에 디버깅을 방해하지 않는 경우.

    오류 메시지 없음

    php.ini 禁用了 error_reportingdisplay_errors을 기준으로 한다면, 그러면 경고가 나타나지 않습니다. 하지만 오류를 무시해도 문제가 해결되지는 않습니다. 떠나다. 조기 출력 후 헤더를 보낼 수 없습니다.

    따라서 header("Location: ...") 리디렉션이 자동으로 실패하면 매우 심각한 상황입니다. 프로브 경고를 권장합니다. 두 가지 간단한 명령으로 다시 활성화하십시오. 호출 스크립트 위에:

    으아아아

    또는 set_error_handler("var_dump"); 다른 모든 방법이 실패하는 경우.

    리디렉션 헤더에 관해 말하면 항상 이와 같은 관용어를 사용해야 합니다. 최종 코드 경로는 다음과 같습니다.

    으아아아

    사용자 메시지를 인쇄하는 실용적인 기능이 가장 좋습니다. header() 실패할 경우.

    해결 방법으로 출력 버퍼링

    PHP 출력 버퍼링 이 문제를 완화하기 위한 해결 방법입니다. 일반적으로 안정적으로 작동하지만 그렇게 해서는 안 됩니다. 올바른 애플리케이션 구조를 재정의하고 제어에서 출력을 분리합니다. 논리. 실제 목적은 웹 서버로의 청크 전송을 최소화하는 것입니다.

    1. output_buffering= 그래도 설정이 도움이 됩니다. php.ini에서 구성하세요. 또는 .htaccess를 통해 심지어 .user.ini 최신 FPM/FastCGI 설정.
      이 기능을 활성화하면 PHP가 출력을 웹 서버에 즉시 전달하는 대신 출력을 버퍼링할 수 있습니다. 따라서 PHP는 HTTP 헤더를 집계할 수 있습니다.

    2. 전화로도 통화 가능합니다ob_start(); 호출 스크립트 위에. 그러나 여러 가지 이유로 그다지 신뢰할 수는 없습니다:

      • 첫 번째 스크립트를 시작하더라도 공백 또는 렌더링 전에 BOM이 뒤섞여 무효화될 수 있습니다.

      • HTML 출력의 공백을 숨길 수 있습니다. 그러나 애플리케이션 로직이 바이너리 콘텐츠(예: 생성된 이미지)를 전송하려고 시도하면 버퍼링된 외부 출력이 문제가 됩니다. (ob_clean() 필요) 추가 해결 방법으로. )

      • 버퍼 크기는 제한되어 있으며 기본값으로 두면 쉽게 오버플로될 수 있습니다. 이러한 상황은 드문 일이 아니며 추적하기 어렵습니다 그것이 일어날 때.

    따라서 두 방법 모두 신뢰할 수 없게 될 수 있습니다. 특히 두 방법 사이를 전환할 때 더욱 그렇습니다. 개발 설정 및/또는 프로덕션 서버. 이것이 출력 버퍼링이 필요한 이유입니다. 단지 버팀목/엄격한 해결 방법으로 널리 간주됩니다.

    참조 기본 사용 예 매뉴얼 및 더 많은 장단점:

    하지만 다른 서버에서는 작동합니다! ?

    이전에 헤더 경고를 받지 못했다면 출력 버퍼링 php.ini 설정 이미 변경되었습니다. 현재/새 서버에서는 구성되지 않을 수 있습니다.

    사용 headers_sent()检查

    항상 headers_sent()을 사용하여 다음을 감지할 수 있습니다. 헤더를 보내는 것은 여전히 ​​가능합니다. 조건부 인쇄에 유용합니다. 정보를 제공하거나 다른 대체 논리를 적용합니다.

    으아아아

    유용한 대체 솔루션은 다음과 같습니다.

    • HTML 태그

      애플리케이션이 구조적으로 수정하기 어려운 경우에는 간단합니다(그러나 약간 비전문적임) 리디렉션을 허용하는 방법은 HTML을 삽입하는 것입니다. 태그. 다음을 통해 리디렉션할 수 있습니다.

      으아아아

      또는 짧은 지연:

      으아아아

      이로 인해 섹션을 넘어서 사용하면 HTML이 유효하지 않게 됩니다. 대부분의 브라우저는 여전히 이를 허용합니다.

    • 자바스크립트 리디렉션

      대안으로 JavaScript 리디렉션 페이지 리디렉션 가능:

      으아아아

      이 방법은 일반적으로 해결 방법보다 HTML에 더 적합하지만, 이로 인해 JavaScript 지원 클라이언트에 대한 종속성이 발생합니다.

    그러나 실제 HTTP 헤더()가 호출될 때 두 방법 모두 허용 가능한 폴백을 생성합니다. 통화가 실패했습니다. 이상적으로는 항상 이를 사용자 친화적인 메시지와 결합하여 최후의 수단으로 클릭 가능한 링크. (예를 들어 http_redirect() PECL 확장이 그렇습니다. )

    setcookie()session_start()또한 영향을 받나요

    setcookie()session_start() 都需要发送 Set-Cookie: HTTP 헤더. 따라서 동일한 조건이 적용되며 유사한 오류 메시지가 생성됩니다. 조기 출력되는 경우에 사용됩니다.

    (물론 브라우저에서 쿠키를 비활성화해도 영향을 받습니다. 심지어 대행사 문제도요. 세션 기능은 분명히 무료에도 의존합니다. 디스크 공간 및 기타 php.ini 설정 등)

    더 많은 링크

    회신하다
    0
  • 취소회신하다