스크립트를 실행할 때 다음과 같은 몇 가지 오류가 발생합니다.
경고 : 헤더 정보를 수정할 수 없습니다 – 이미 (가 보낸 헤더 /some/file.php:12에서 시작 출력 에) /some/file.php 에 라인 (23)
오류 메시지에 언급 된 행은 header()
및 setcookie()
호출을 포함 합니다.
그 이유는 무엇입니까? 그리고 그것을 고치는 방법?
답변
헤더를 보내기 전에 출력이 없습니다!
HTTP 헤더를 전송 / 수정하는 기능은 출력하기 전에 호출해야합니다 .
summary ⇊
그렇지 않으면 호출이 실패합니다.
경고 : 헤더 정보를 수정할 수 없습니다-헤더가 이미 전송되었습니다 ( 스크립트 에서 출력이 시작되었습니다 : line )
HTTP 헤더를 수정하는 일부 기능은 다음과 같습니다.
출력은 다음과 같습니다.
-
의도하지 않은 :
- 공백 전
<?php
또는 후?>
- UTF-8 바이트 순서 표시 특별히
- 이전 오류 메시지 또는주의 사항
- 공백 전
-
의도적 :
print
,echo
및 기타 기능의 제조 출력- 원시
<html>
섹션 이전<?php
코드.
왜 그런가요?
출력 전에 헤더를 보내야하는 이유를 이해하려면 일반적인 HTTP
응답 을 살펴 봐야 합니다. PHP 스크립트는 주로 HTML 컨텐츠를 생성하지만 HTTP / CGI 헤더 세트를 웹 서버에 전달합니다.
HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>
페이지 / 출력은 항상 헤더를 따릅니다 . PHP는 먼저 헤더를 웹 서버에 전달해야합니다. 한 번만 할 수 있습니다. 이중 줄 바꿈 후에는 더 이상 수정할 수 없습니다.
PHP가 제 1 출력을 수신하면 ( print
, echo
, <html>
)는 것이다
플러시 모든 수집 헤더. 나중에 원하는 모든 출력을 보낼 수 있습니다. 그러나 추가 HTTP 헤더를 보내는 것은 불가능합니다.
조기 출력이 발생한 위치를 어떻게 알 수 있습니까?
header()
경고는 문제의 원인을 찾기 위해 모든 관련 정보를 포함합니다 :
경고 : 헤더 정보를 수정할 수 없습니다 – 헤더가 이미 의해 전송
(에서 시작 출력 / www /에서 usr2345 / htdocs에 / auth.php : 52 ) 라인 (100)에 /www/usr2345/htdocs/index.php에서
여기서 “라인 100″은 header()
호출이 실패한 스크립트를 나타냅니다 .
괄호 안에 있는 ” 시작에서 ” 출력 이 더 중요합니다. 이전 출력의 소스를 나타냅니다. 이 예는의 auth.php
와 선52
. 여기서 조기 출력을 찾아야했습니다.
일반적인 원인 :
-
인쇄, 에코
의도적 인 출력
print
및echo
명령문은 HTTP 헤더 전송 기회를 종료합니다. 이를 방지하려면 애플리케이션 플로우를 재구성해야합니다. 함수
와 템플릿 구성표를 사용하십시오 . 메시지가 작성 되기 전에header()
통화가 발생 하는지 확인하십시오 .출력을 생성하는 기능은 다음과 같습니다.
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
무엇보다도 사용자 정의 함수.
-
원시 HTML 영역
.php
파일의 구문 분석되지 않은 HTML 섹션 도 직접 출력됩니다. 트리거됩니다 스크립트 조건을header()
호출하기 전에주의해야 어떤 원시<html>
블록.<!DOCTYPE html> <?php // Too late for headers already.
템플릿 구성표를 사용하여 처리를 출력 논리와 분리하십시오.
- 스크립트 위에 양식 처리 코드를 배치하십시오.
- 임시 문자열 변수를 사용하여 메시지를 연기하십시오.
- 실제 출력 로직과 혼합 된 HTML 출력이 마지막에옵니다.
-
<?php
“script.php line 1 “경고 앞의 공백경고가 행의 출력을 나타내는 경우 여는 토큰
1
앞의 공백 , 텍스트 또는 HTML 이 주로 선행<?php
합니다.<?php # There's a SINGLE space/newline before <? - Which already seals it.
마찬가지로 추가 된 스크립트 또는 스크립트 섹션에서도 발생할 수 있습니다.
?> <?php
PHP는 실제로 태그를 닫은 후 단일 줄 바꿈을 사용합니다. 그러나 여러 줄 바꿈이나 탭 또는 공백이 이러한 간격으로 이동하면 보상되지 않습니다.
-
UTF-8 BOM
줄 바꿈과 공백 만 문제가 될 수 있습니다. 그러나 이로 인해 “보이지 않는”문자 시퀀스도 있습니다. 대부분의
텍스트 편집기에서 표시되지 않는 UTF-8 BOM (Byte-Order-Mark) 이 가장 유명합니다
.EF BB BF
UTF-8로 인코딩 된 문서에는 옵션이며 중복되는 바이트 시퀀스 입니다. 그러나 PHP는이를 원시 출력으로 취급해야합니다.
출력 에서 문자 (클라이언트가 문서를 Latin-1로 해석하는 경우) 또는 유사한 “쓰레기”로 표시 될 수 있습니다.특히 그래픽 편집기와 Java 기반 IDE는 존재하지 않습니다. 그들은 그것을 시각화하지 않습니다 (유니 코드 표준에 의해 의무화 됨). 그러나 대부분의 프로그래머와 콘솔 편집기는 다음을 수행합니다.
초기에 문제를 쉽게 식별 할 수 있습니다. 다른 편집기는 파일 / 설정 메뉴에서 해당 존재를 식별 할 수 있습니다 (Windows의 메모장 ++에서 문제점을 식별하고 해결할 수 있음
). BOM 존재를 검사하는 또 다른 옵션은 hexeditor 를 사용하는 것 입니다. * nix 시스템hexdump
은 일반적으로 이러한 변형 및 기타 문제 감사를 단순화하는 그래픽 변형이 아닌 경우에 사용 가능합니다.쉬운 수정 방법은 파일을 “UTF-8 (BOM 없음)”또는 이와 유사한 명명법으로 저장하도록 텍스트 편집기를 설정하는 것입니다. 그렇지 않은 경우 종종 새로운 이민자가 새 파일을 만들고 이전 코드를 복사하여 붙여 넣는 것에 의존합니다.
수정 유틸리티
텍스트 파일 (
sed
/awk
또는recode
) 을 검사하고 다시 쓰는 자동화 된 도구도 있습니다 . PHP의 경우 구체적으로phptags
태그 tidier가 있습니다. 닫고 열린 태그를 길고 짧은 형식으로 다시 작성하지만 선행 및 후행 공백, 유니 코드 및 UTF-x BOM 문제를 쉽게 수정합니다.phptags --whitespace *.php
전체 include 또는 프로젝트 디렉토리에서 사용하는 것이 좋습니다.
-
공백
?>
오류 소스가 닫힘
?>
뒤에 언급 된 경우공백 또는 원시 텍스트가 작성된 위치입니다. 이 시점에서 PHP 종료 마커는 스크립트 실행을 종료하지 않습니다. 그 이후의 모든 텍스트 / 공백 문자는 여전히 페이지 내용으로 기록됩니다.
일반적으로, 특히 새로운 이민자들에게, 후행
?>
PHP 닫기 태그는 생략해야합니다. 이것은 이러한 경우의 작은 부분을 피 합니다. (일반적으로include()d
스크립트는 범인입니다.) -
“0 행에서 알 수 없음”으로 언급 된 오류 소스
오류 소스가 구체화되지 않은 경우 일반적으로 PHP 확장 또는 php.ini 설정입니다.
- 때때로
gzip
스트림 인코딩 설정
또는ob_gzhandler
입니다. - 그러나 또한
extension=
암시 적 PHP 시작 / 경고 메시지를 생성하는 이중로드 모듈 일 수도 있습니다 .
- 때때로
-
선행 오류 메시지
다른 PHP 문장이나 표현으로 경고 메시지 나 통지가 출력되면 조기 출력으로 계산됩니다.
이 경우 나중에 디버깅을 방해하지 않는 경우 오류를 피하거나 명령문 실행을 지연 시키거나 예를 들어
isset()
또는@()
-를 사용 하여 메시지를 억제해야합니다
.
오류 메시지가 없습니다
를 사용 error_reporting
하거나 display_errors
사용 중지 php.ini
한 경우 경고가 표시되지 않습니다. 그러나 오류를 무시해도 문제가 해결되지는 않습니다. 조기 출력 후에도 헤더를 보낼 수 없습니다.
따라서 header("Location: ...")
리디렉션이 자동으로 실패하면 경고를 조사하는 것이 좋습니다. 호출 스크립트 위에 두 가지 간단한 명령으로 다시 활성화하십시오.
error_reporting(E_ALL);
ini_set("display_errors", 1);
또는 set_error_handler("var_dump");
다른 모든 것이 실패하면.
리디렉션 헤더에 관해서는 최종 코드 경로에 다음과 같은 관용구를 사용해야합니다.
exit(header("Location: /finished.html"));
header()
오류 발생시 사용자 메시지를 인쇄하는 유틸리티 기능이 바람직합니다 .
해결 방법으로 출력 버퍼링
PHP 출력 버퍼링
은이 문제를 완화하는 해결 방법입니다. 종종 안정적으로 작동하지만 제어 논리에서 출력을 구성하고 분리하는 적절한 응용 프로그램을 대신해서는 안됩니다. 실제 목적은 웹 서버로의 청크 전송을 최소화하는 것입니다.
-
output_buffering=
설정은 그럼에도 불구하고 도움이 될 수 있습니다. 최신 FPM / FastCGI 설정 에서 php.ini
또는 .htaccess
또는 .user.ini 를 통해 구성하십시오 .
이를 사용하면 PHP가 출력을 웹 서버에 즉시 전달하는 대신 출력을 버퍼링 할 수 있습니다. 따라서 PHP는 HTTP 헤더를 집계 할 수 있습니다. -
마찬가지로
ob_start();
호출 스크립트를 호출하기위한 호출에 참여할 수 있습니다 . 그러나 여러 가지 이유로 신뢰성이 떨어집니다.-
<?php ob_start(); ?>
첫 번째 스크립트를 시작 하더라도 공백이나 BOM이 전에 섞여서 비효율적 일 수 있습니다. -
HTML 출력을위한 공백을 숨길 수 있습니다. 그러나 응용 프로그램 논리가 이진 콘텐츠 (예 : 생성 된 이미지)를 보내려고하면 버퍼 외부 출력이 문제가됩니다. (
ob_clean()
추가 해결 방법이 필요합니다.) -
버퍼는 크기가 제한되어 있으며 기본값으로두면 쉽게 오버런 될 수 있습니다. 그리고 그것은 드문 일이 아니며,
일어날 때 추적하기가 어렵습니다 .
-
따라서 특히 개발 설정 및 / 또는 프로덕션 서버 간을 전환 할 때 두 방법 모두 신뢰할 수 없게 될 수 있습니다. 출력 버퍼링이 목발 / 엄격히 해결 방법으로 널리 간주되는 이유입니다.
매뉴얼 의 기본 사용법 예제 와 더 많은 장단점을 참조하십시오.
- 출력 버퍼링이란 무엇입니까?
- PHP에서 출력 버퍼링을 사용하는 이유는 무엇입니까?
- 출력 버퍼링을 사용하는 것이 나쁜 습관으로 간주됩니까?
- “이미 전송 된 헤더”에 대한 올바른 솔루션으로 출력 버퍼링 사용 사례
그러나 다른 서버에서 작동했습니다!?
이전에 헤더 경고를받지 못한 경우 출력 버퍼링 php.ini 설정
이 변경되었습니다. 현재 / 새 서버에서 구성 해제되었을 수 있습니다.
확인 headers_sent()
headers_sent()
헤더를 보낼 수있는 경우 항상 프로브에 사용할 수 있습니다 . 조건부로 정보를 인쇄하거나 다른 대체 논리를 적용하는 데 유용합니다.
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
유용한 대체 해결 방법은 다음과 같습니다.
-
HTML
<meta>
태그응용 프로그램이 구조적으로 수정하기 어려운 경우 리디렉션을 허용하는 쉬운 방법이지만 다소 비전문적 인 방법으로 HTML
<meta>
태그를 삽입하는 것
입니다. 다음을 통해 리디렉션을 수행 할 수 있습니다.<meta http-equiv="Location" content="http://example.com/">
또는 짧은 지연 시간 :
<meta http-equiv="Refresh" content="2; url=../target.html">
이는
<head>
섹션을 지나서 사용할 때 유효하지 않은 HTML로 이어집니다 . 대부분의 브라우저는 여전히이를 수락합니다. -
자바 스크립트 리디렉션
대안으로
페이지 리디렉션에 JavaScript 리디렉션을 사용할 수 있습니다.<script> location.replace("target.html"); </script>
이는
<meta>
대안 보다 HTML과 호환되는 경우가 많지만 JavaScript 가능 클라이언트에 의존합니다.
그러나 두 가지 방법 모두 진정한 HTTP header () 호출이 실패 할 때 허용 가능한 폴백을 만듭니다. 이상적으로는 항상 최후의 수단으로이 메시지를 사용자 친화적 인 메시지 및 클릭 가능한 링크와 결합해야합니다. (예를 들어 http_redirect ()
PECL 확장 은 무엇입니까 ?)
왜 setcookie()
그리고 session_start()
영향을 받는가
모두 setcookie()
와 session_start()
필요 보낼 Set-Cookie:
HTTP 헤더를. 따라서 동일한 조건이 적용되며 조기 출력 상황에서 유사한 오류 메시지가 생성됩니다.
(물론 브라우저에서 비활성화 된 쿠키 또는 프록시 문제의 영향을받습니다. 세션 기능은 디스크 여유 공간 및 기타 php.ini 설정 등에 따라 달라집니다)
추가 링크
- Google은 유사한 토론 의 긴 목록을 제공합니다 .
- 물론 많은 특정 사례 가 스택 오버플로에서도 다루어졌습니다.
- WordPress FAQ는 이미 보낸 경고 문제를 해결하는 방법을 설명합니다 . 일반적인 방식으로.
- Adobe Community : PHP 개발 : 리디렉션이 작동하지 않는 이유 (헤더가 이미 전송 됨)
- Nucleus FAQ : “이미 전송 된 페이지 헤더”란 무엇입니까?
- 더 자세한 설명 중 하나는 HTTP 헤더와 PHP header () 함수-NicholasSolutions (인터넷 아카이브 링크) 의 튜토리얼 입니다. HTTP에 대해 자세히 다루고 스크립트를 다시 작성하기위한 몇 가지 지침을 제공합니다.
답변
이 오류 메시지가 트리거됩니다 어떤이 (당신이 HTTP 헤더를 보내기 전에 전송 setcookie
또는 header
). HTTP 헤더 전에 무언가를 출력하는 일반적인 이유는 다음과 같습니다.
-
다음과 같이 파일의 시작 또는 끝에 실수로 발생하는 공백 :
<?php // Note the space before "<?php" ?>
이를 피하려면 간단히 닫는 것을 생략하십시오 ?>
. 어쨌든 필요하지 않습니다.
- PHP 파일의 시작 부분에 바이트 순서 표시 . 16 진 편집기로 PHP 파일을 검사하여 해당 여부를 찾으십시오. 바이트로 시작해야합니다
3F 3C
.EF BB BF
파일 시작 부분에서 BOM 을 안전하게 제거 할 수 있습니다 . - 이러한 호출에 대한 명시적인 출력,
echo
,printf
,readfile
,passthru
, 코드 앞에<?
등 display_errors
php.ini 속성이 설정 되면 php에 의해 경고가 출력됩니다 . php는 프로그래머의 실수로 충돌하는 대신 오류를 자동으로 수정하고 경고를 표시합니다.display_errors
or error_reporting 구성을 수정할 수는 있지만 문제를 해결해야합니다.
일반적인 원인 (예 : 배열의 정의 요소에 액세스되어$_POST['input']
사용하지 않고,empty
또는isset
입력이 세트가 있는지 여부를 테스트하는) 또는 (같이 정의되지 않은 정수가 아닌 문자열 상수 값을 이용하여$_POST[input]
손실 된 인용 참고).
출력 버퍼링을 켜면 문제가 해결됩니다. 를 호출 한 후의 모든 출력 ob_start
은 버퍼를 해제 할 때까지 (예 : with) 버퍼링됩니다 ob_end_flush
.
그러나 출력 버퍼링으로 문제를 피할 수 있지만 애플리케이션이 HTTP 헤더 전에 HTTP 본문을 출력하는 이유를 실제로 판별해야합니다. 전화를 걸고 하루와 날씨를 논의하여 발신자에게 전화 번호가 잘못되었다고 알리는 것과 같습니다.
답변
이 오류가 여러 번 발생했으며 모든 PHP 프로그래머가 적어도 한 번은이 오류가 발생했다고 확신합니다.
가능한 해결책 1
이 오류는 파일 시작 전 또는 파일 끝 이후 의 공백으로 인해 발생했을 수 있습니다. 이러한 공백은 여기에 없어야합니다.
예) 공백이 없어야합니다
echo "your code here";
?>
THERE SHOULD BE NO BLANK SPACES HERE
이 오류의 원인이되는 파일과 관련된 모든 파일을 확인하십시오.
참고 : 때때로 gedit (기본 Linux 편집기)와 같은 EDITOR (IDE)는 저장 파일에 빈 줄을 하나 추가합니다. 이런 일은 일어나지 않아야합니다. Linux를 사용중인 경우 VI 편집기를 사용하여 페이지 끝에서?> 뒤에 공백 / 줄을 제거 할 수 있습니다.
가능한 해결 방법 2 :이
경우가 아니면 ob_start 를 사용하여 버퍼링 을 출력하십시오.
<?php
ob_start();
// code
ob_end_flush();
?>
출력 버퍼링이 켜지고 페이지가 버퍼링 된 후 헤더가 생성됩니다.
답변
아래 줄 대신
//header("Location:".ADMIN_URL."/index.php");
쓰다
echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");
또는
?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php
확실히 문제를 해결할 것입니다. 나는 같은 문제에 직면했지만 위의 방법으로 헤더 위치를 작성하여 해결했습니다.
답변
당신은
printf ("Hi %s,</br />", $name);
쿠키를 설정하기 전에 허용되지 않습니다. 빈 줄이 아니라 헤더 앞에 출력을 보낼 수 없습니다.
답변
이 줄 때문입니다.
printf ("Hi %s,</br />", $name);
헤더를 보내기 전에 어떤 것도 인쇄 / 에코 하지 않아야합니다 .
답변
일반적인 문제 :
====================
1) 명령 echo..
이전에 출력 (예 : HTML 코드 ) 이 없어야합니다 header(.......);
.
2) 어떤 제거 공백 (또는 줄 바꿈을 하기 전에) <?php
후에 ?>
태그입니다.
3) 골든 룰! -해당 PHP 파일 (및 include
다른 파일도)에 BOM 인코딩이 없는 UTF8이 있는지 확인하십시오 ( UTF-8 뿐만 아니라 ). UTF8로 인코딩 된 파일은 텍스트 파일 편집기에 표시되지 않는 PHP 파일의 시작 부분에 특별한 문자가 있기 때문에 많은 경우에 문제가 있습니다 !!!!!!!!!!!
4) 후 header(...);
사용한다exit;
5) 항상 301 또는 302 참조를 사용하십시오.
header("location: http://example.com", true, 301 ); exit;
6) 오류보고를 켜고 오류를 찾으십시오. 작동하지 않는 기능으로 인해 오류가 발생했을 수 있습니다. 오류보고를 설정하면 항상 최상위 오류를 먼저 수정해야합니다. 예를 들어, “경고 : date_default_timezone_get () : 시스템의 시간대 설정에 의존하는 것은 안전하지 않습니다.” -아래로 내려 갈수록 “헤더가 전송되지 않음”오류가 표시 될 수 있습니다. 최상위 (1 차) 오류를 수정 한 후 페이지를 다시로드하십시오. 여전히 오류가 발생하면 최상위 오류를 다시 수정하십시오.
7) 위의 방법 중 어느 것도 도움이되지 않으면 JAVSCRIPT 리디렉션을 사용하십시오 (그러나 강력하게 권장하지 않는 방법). 맞춤 경우에는 마지막 기회 일 수 있습니다 … :
echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;