PHP fopen() не создает файл, если он еще не существует
в рамках ведения журнала приложение, которое я пытаюсь открыть локальный файл, и если файл еще не существует, создать новый. Вот что у меня есть:
$path = '/home/www/phpapp/logs/myawesome_logfile.txt';
$f = (file_exists($path))? fopen($path, "a+") : fopen($path, "w+");
fwrite($f, $msg);
fclose($f);
chmod($path, 0777);
Я дважды проверил, и /logs
каталог chmod 0777, и я даже пошел дополнительный шаг chown'ING его apache:apache для хорошей меры. Тем не менее, когда скрипт открывает файл, он дает мне предупреждение о том, что файл не существует, и бомбит. Файл никогда не создается.
Я нужно подавить fopen()
предупреждение, чтобы заставить его создать файл?
6 ответов
когда вы работаете с путями в PHP, контекст имеет большое значение. Если вы работаете с URL-адресами в контексте перенаправления , корневой каталог ( ' / ' ) ссылается на корневой каталог вашего домена. То же самое касается путей для связывания файлов или изображений и директив include и require.
однако, когда вы имеете дело с командами файловой системы, такими как fopen
корневой каталог ('/') является корневая система. Не ваш домен root.
чтобы исправить это, попробуйте предоставление полного пути к файлу журнала, который вы хотите открыть из системного корня. Например: /var/www/phpapplication/logs/myLogFile.txt
или вы можете использовать $_SERVER['DOCUMENT_ROOT']
как предложено в других ответах для доступа к сохраненному значению вашего сервера для пути к корню документа. The /var/www
часть.
вы также можете использовать __DIR__
магическая константа в некоторых случаях. Обратите внимание, что __DIR__
будет каталогом, в котором находится текущий файл, который не обязательно совпадает с корнем вашего приложения. Так, например, если корень вашего приложения /var/www/application
и вы работаете в /var/www/application/src/controllers/my_controller.php
, потом __DIR__
будет /var/www/application/src/controllers
. см. здесь, в документации по PHP.
вы пробовали это?
$msg = "I'm a line that is a message.\n";
$path = $_SERVER['DOCUMENT_ROOT'] . '/logs/myawesome_logfile.txt';
$f = fopen($path, "a+");
fwrite($f, $msg);
fclose($f);
chmod($path, 0777);
сервер, на котором вы работаете, мог бы посадить вас в тюрьму только для работы в каталоге phpapp и его подкаталогах.
один из способов обойти эту проблему в UBUNTU 14.04 - щелкнуть правой кнопкой мыши по каталогу, где находится файл, и изменить разрешения "другие" на "создание и удаление файлов".
вы всегда можете открыть файл с помощью just "a"
, Он также создаст новый файл.
Не нужно ставить условие.
однако основной проблемой вашего кода является понимание разницы между физической файловой системой и виртуальным веб-сервером, что уже было прекрасно объяснено.
обратите внимание, что вы должны предоставить свой вопрос с точной копией сообщения об ошибке. Он содержит тонну чрезвычайно полезной информации, это не похоже на клятву "я не буду создайте свой файл, уходите!"но это через объяснение того, что и почему происходит не так. Если вы сами не заботитесь о такой полезной информации, вы должны предоставить ее тем, кто просит о помощи.
путь к файлу должен быть с корневым сервером. Я мог бы достичь этого, используя функцию phpinfo() метод внутри документа, который я хотел знать. Поэтому при использовании phpinfo () вы увидите информационный документ. Если вы найдете для _SERVER ["SCRIPT_FILENAME"] вы увидите абсолютный путь к вашему файлу.
Я надеюсь, что это поможет кому-то.
Не забудьте убедиться, что SELinux не блокирует вас.
[root@yourbox]# audit2allow #============= httpd_t ==============
#!!!! Этот avc можно разрешить с помощью логического "httpd_unified" разрешить httpd_t httpd_sys_content_t: dir { написать add_name };
#!!!! Этот avc можно разрешить с помощью логического "httpd_unified" разрешить httpd_t httpd_sys_content_t: файл { написать создать }; [root@yourbox]# audit2allow - a-M my_httpd
Примечание:
чтобы сделать этот пакет активной политики, выполните:
semodule-i my_httpd.pp
[root@yourbox]# semodule-i my_httpd.стр
[root@yourbox]# systemctl перезапустить httpd