2014-11-21 77 views
3

這讓我瘋狂。我有一個標準的例程來編寫運行良好的日誌文件,以至於我幾乎忘記了代碼中的內容。將它轉化爲一個新項目,做出了一個改變,它的表現真的很奇怪。錯誤消息指出fopen()無法打開日誌文件,但是這些條目仍在寫入日誌文件中。我不喜歡有任何描述的錯誤或警告,所以我不打算忽略這個錯誤,僅僅因爲它看起來在儘管出現錯誤仍在工作。PHP fopen無法打開文件,但仍然寫入它

我所做的更改是以$ _SESSION ['base_dir_prefix']的方式設置的。在之前的項目中,這些項目是在主頁上下文中設置的,並設置爲該目錄的絕對路徑。這有一個弱點,你不能不經過index.php直接進入一個頁面。我無法在這個項目中做到這一點,所以我將它設置爲相對路徑 - 例如, $ _SESSION ['base_dir_prefix'] =「../」;據我所見,前綴設置正確。事實上,據我所知,一切都設置正確,但顯然有一針在那裏,需要另一雙眼睛看!

我最大的問題之一是,如果fopen()無法打開文件,那麼爲什麼會被寫入?

附件1 - 實際寫入功能的源代碼。請注意,echo語句純粹用於調試目的,不屬於正常執行。

function writelog($str=" ") 
{ 
    if (isset($_SESSION['base_dir_prefix'])) 
    { 
     $prepend = $_SESSION['base_dir_prefix'] ; 
    } 
    else 
    { 
     $prepend = $_SERVER['DOCUMENT_ROOT'] ; 
    } 

    if (substr($prepend, -1, 1) <> DIRECTORY_SEPARATOR) 
    { 
     $prepend .= DIRECTORY_SEPARATOR ; 
    } 
    $fname = $prepend."log/log.txt" ; 
    $mode = "a" ; 

    echo getcwd(). "\n" ;   // debug code 
    echo $fname." Files exists?:".file_exists($fname) ."\n"; 
    echo $str."\n" ; 

    $fp = fopen($fname, $mode) ; 

    fwrite($fp, date("Y-m-d H:i:s").": ") ; 
    fwrite($fp, $str."\n") ; 
    fclose($fp) ; 
} 

圖表2 - 日誌文件本身 - 調用該函數

$u->writelog ("SA OLU entering Option List Users function") ; 
    $u->writelog ("Current dir:".getcwd()." ") ; 

    $usr_list = array(array("None", "None")); 
    $sc->user_list($usr_list) ; 
    $i = 0 ; 
    $res = "" ; 
    $actv_flag = strtoupper($active) ; 

    if ($usr_list[0][0] != "None") 
    { 
     while ($i < count($usr_list)) 
     { 
      if ((bool)$usr_list[$i][2] == true && $actv_flag == "YES") //only active users 
      { 
       $i++ ; 
       continue ; 
      } 
      $res .= sprintf("<option value=\"%s\"> %s (%s) </option> \n", 
          $usr_list[$i][0], 
          $usr_list[$i][1], 
          $usr_list[$i][0] 
          ); 
      $i++ ; 
     } 
    } else 
    { 
      $res = sprintf("<option value=\"no_recs\"> No Program Records </option> \n") ; 
    } 
    $u->writelog ("SA OLU leaving Option List Users function") ; 

圖表3的代碼。由展覽創建的條目1.請注意,此文件上的時間戳比實際時間晚1個小時。不知道爲什麼,因爲我是唯一看這個文件的人,所以我一直沒有太在意。

2014-11-21 16:29:58: SA OLU entering Option List Users function 
2014-11-21 16:29:58: Current dir:/srv/www/dev/gillies/security 
2014-11-21 16:29:58: SA OLU leaving Option List Users function 
2014-11-21 16:29:58: SA OLU entering Option List Users function 
2014-11-21 16:29:58: Current dir:/srv/www/dev/gillies/security 
2014-11-21 16:29:58: SA OLU leaving Option List Users function 
2014-11-21 16:29:58: SA OLU entering Option List Users function 
2014-11-21 16:29:58: Current dir:/srv/www/dev/gillies/security 
2014-11-21 16:29:58: SA OLU leaving Option List Users function 

表4 - Apache的錯誤日誌文件

[Fri Nov 21 15:29:25.047732 2014] [:error] [pid 20588] [client 192.168.0.19:62116] PHP Warning: fwrite() expects parameter 1 to be resource, boolean given in /srv/www/dev/gillies/php/utilities.php on line 72 
[Fri Nov 21 15:29:25.047746 2014] [:error] [pid 20588] [client 192.168.0.19:62116] PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /srv/www/dev/gillies/php/utilities.php on line 73 
[Fri Nov 21 15:29:58.721627 2014] [:error] [pid 17084] [client 192.168.0.19:62141] PHP Warning: fopen(../log/log.txt): failed to open stream: No such file or directory in /srv/www/dev/gillies/php/utilities.php on line 69 
[Fri Nov 21 15:29:58.721698 2014] [:error] [pid 17084] [client 192.168.0.19:62141] PHP Warning: fwrite() expects parameter 1 to be resource, boolean given in /srv/www/dev/gillies/php/utilities.php on line 71 
[Fri Nov 21 15:29:58.721711 2014] [:error] [pid 17084] [client 192.168.0.19:62141] PHP Warning: fwrite() expects parameter 1 to be resource, boolean given in /srv/www/dev/gillies/php/utilities.php on line 72 
[Fri Nov 21 15:29:58.721720 2014] [:error] [pid 17084] [client 192.168.0.19:62141] PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /srv/www/dev/gillies/php/utilities.php on line 73 

圖表5 - 表示回波的結果所生成的HTML代碼的一個片斷。附件2創建的條目。再次,這僅用於診斷目的,不是生產文件的一部分。

    </h4><select name="users" size="5"> 
         /srv/www/dev/gillies/security 
../log/log.txt Files exists?:1 
SA OLU entering Option List Users function 
/srv/www/dev/gillies/security 
../log/log.txt Files exists?:1 
Current dir:/srv/www/dev/gillies/security 
/srv/www/dev/gillies/security 
../log/log.txt Files exists?:1 
SA OLU leaving Option List Users function 
     <option value="loginid"> name (loginid) </option> 

圖表6 - 日誌文件

[email protected]:/srv/www/dev/gillies/log$ pwd 
/srv/www/dev/gillies/log 
[email protected]:/srv/www/dev/gillies/log$ ls -l 
total 8 
-rw-rw-rw- 1 www-data www-data 4743 Nov 21 15:33 log.txt 

任何線索的人的目錄結構? 謝謝。

+0

代碼中的某處,您將'$ fname'設置爲'boolean'。您需要調試(通過'var_dump()')來查看它從字符串到布爾的位置。 – Darren 2014-11-21 06:33:55

+0

達倫,謝謝你的想法,但我不認爲這是發生。如果你看展覽1,在fopen使用它之前立即回顯$ fname。圖表5顯示它不是布爾值,並且還驗證文件$ fname確實存在。 – 2014-11-21 07:05:01

+0

我很驚訝,相對路徑正在工作,我的印象是,你總是需要一個絕對路徑來寫文件? – Darren 2014-11-21 07:08:41

回答

1

我找到了答案,它是在提供給fopen()的相對路徑中。我重寫了代碼以創建一個絕對而不是相對的前綴,所有的錯誤都消失了。我需要做一些字符串操作才能找到正確的目錄,新代碼現在看起來像這樣:

$here = getcwd() ; 
$posn = strrpos($here, "/") ; 
if($posn === false) { 
    $_SESSION['base_dir_prefix'] = "../" ; 
} 
else { 
    $_SESSION['base_dir_prefix'] = substr($here, 0, $posn) ; 
} 

謝謝你的想法,Darren。我正在圍繞着試圖解決還有什麼其他問題。

新代碼獲取位於層次結構中第二級目錄的絕對路徑,並將該路徑修剪回一級以便它指向文檔根目錄。

對於那些可能想知道爲什麼所有這些麻煩來獲取目錄,這使得代碼完全可重定位。當網站在開發,測試,驗收和生產階段移動時,不能保證文檔根目錄與Web服務器文檔根目錄相同。這使網站可以放在目錄層次結構中的任何位置,而無需更改對文件的引用等。

+0

您也可以使用dirname(\ _ \ _ FILE \ _ \ _) – bksi 2014-11-21 08:33:55

相關問題