2014-11-21 2 views
3

Это сводит меня с ума. У меня есть стандартная процедура для записи файлов журналов, которые работали так хорошо, что я почти забыл, что было в коде. Перенос его в новый проект сделал одно изменение, и он ведет себя действительно странно. Сообщения об ошибках говорят, что fopen() не может открыть файл журнала, однако записи все еще записываются в файл журнала. Мне не нравятся ошибки или предупреждения о любом описании, поэтому я не собираюсь игнорировать эту ошибку только потому, что она работает, несмотря на ошибку.PHP fopen не может открыть файл, но все равно пишет ему

Изменение, которое я сделал, было таким, как было установлено $ _SESSION ['base_dir_prefix']. В предыдущих проектах, которые были установлены в контексте домашней страницы, и установите абсолютный путь к этому каталогу. Это имело слабость, когда вы не могли перейти прямо к странице, не перейдя через index.php. Я не мог этого сделать в этом проекте, поэтому я установил его относительный путь - например, $ _SESSION ['base_dir_prefix'] = "../"; Насколько я вижу, префикс установлен правильно. На самом деле, насколько я вижу, все настроено правильно, но там, очевидно, есть иголка где-то, где понадобятся еще две пары глаз!

Один из моих самых больших вопросов: если fopen() не может открыть файл, то почему это написано?

Приложение 1 - исходный код фактической функции writelog. Обратите внимание, что инструкции 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 кода, показывающий результаты эхо. Записи, созданные Exhibit 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()'), чтобы увидеть, где это происходит, от строки до bool. – Darren

+0

Даррен, спасибо за идею, но я не думаю, что это происходит. Если вы посмотрите на экспонат 1, $ fname будет эхом, прежде чем fopen его использует. В Приложении 5 показано, что он не является логическим, а также проверяет, действительно ли существует файл $ fname. –

+0

Я удивлен, что относительный путь работает, я был под впечатлениями, что вам всегда нужен абсолютный путь для записи файлов? – Darren

ответ

1

Я нашел ответ, и он был в относительном пути, предоставленном fopen(). Я переписал код, чтобы создать префикс, который был абсолютным, а не относительным, и все ошибки исчезли. Мне нужно сделать некоторые манипуляции строки, чтобы получить правильный каталог, и новый код теперь выглядит следующим образом:

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

Спасибо за идеи, Даррен. Я собирался по кругу, пытаясь понять, что еще попробовать.

Новый код получает абсолютный путь к каталогу, который находится на втором уровне в иерархии, и обрезает путь назад на один уровень, чтобы он указывал на корень документа.

Для тех, кто может задаться вопросом, почему все эти проблемы возникают в каталоге, это делает код полностью перемещаемым. Нет никакой гарантии, что корень документа будет на том же уровне относительно корня документа веб-сервера, поскольку веб-сайт перемещается по этапам разработки, тестирования, принятия и производства. Это позволяет размещать веб-сайт в любом месте иерархии каталогов, не изменяя ссылки на файлы и т. Д.

+0

вы можете использовать dirname (\ _ \ _ FILE \ _ \ _) тоже – bksi