今天遇到一個問題,運行下面代碼時報錯。
<?php session_start(); if(!isset($_SESSION['user']) || null === $_SESSION['user']) { header('location:login.php'); exit; } ?>
錯誤信息為:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at D:\PHPProjects\agilelite\index.php:1) in D:\PHPProjects\agilelite\index.php on line 2 Warning: Cannot modify header information - headers already sent by (output started at D:\PHPProjects\agilelite\index.php:1) in D:\PHPProjects\agilelite\index.php on line 6
為了解決這個問題,研究一下exit這個函數的用法。
return、break和contiue是語言結構,就如同if語句之類的,但是exit卻是個函數。exit函數的作用是輸出一則消息並且終止當前腳本。
如果一段文本中包括多個以<? ?>結束的腳本,則exit退出當前所在腳本。
比如一篇php文本包括一下代碼,則輸出為 NowaMagic。
<?php echo "Hello"; exit; ?> <?php echo "NowaMagic"; ?>
exit函數語法格式如下(void表示沒有返回值):
void exit ([ string $status ] ) void exit ( int $status )
如果status是一段字符串,這個函數在腳本退出前打印status。
如果status是一個整數,這個整數會被作為退出狀態。退出狀態應該從0到254,退出狀態255被PHP保留並禁止使用。狀態0被用來表示成功的終止程序。
PHP的header可以輸出http頭部信息,前提是,在header之前不能輸出任何內容,因為所有的內容都作為http的body輸出給客戶端了,一旦有body的內容,就不可能再添加任何head部分的信息。
header函數的一個常用的方式就是用來做轉向,redirect。
比如,我需要轉到某個地址,只要執行下述代碼:
<?php header('Location: http://www.bkjia.com/'); ?>
浏覽器會收到一個302的http狀態碼,告訴他這個內容已經被轉移了。
重要的是,php會在調用header函數後,繼續執行後面的代碼,你可以用我的代碼親自試驗一下:
<?php header('Location: http://www.bkjia.com/'); $fp = fopen('header.txt', 'w+'); fwrite($fp, date('Y-m-d H:i:s')); ?>
肯定會執行到fwrite函數的,打開header.txt文件,檢查時間!
對此,解決的辦法是,要在每一個header函數後面加上exit,保證當前頁面停止執行,進而轉向location指定的地址。
為了避免到處都是exit,可以寫一個專門用作轉向的函數,比如:
<?php function DoRedirect($strUrl) { header('Location: ' . $strUrl); exit; } ?>
另,為了避免在header之前輸出body的內容,許多php框架都采用了php頁面尾部不寫?>的方式,因為有些人總習慣在?>後面添加一個換行,這真的是個不好的習慣。