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, и я даже пошёл на дополнительный шаг для его apache: apache для хорошей оценки. Тем не менее, когда script переходит к открытию файла, он дает мне предупреждение о том, что файл не существует и бомбит. Файл не создается.

Нужно ли мне подавлять предупреждение fopen(), чтобы заставить его создать файл?

Ответ 1

Когда вы работаете с путями в PHP, контекст может иметь большое значение. Если вы работаете с URL-адресами в контексте перенаправления, то корневой каталог ('/') относится к вашему корню домена. То же самое касается путей для связывания файлов или изображений, а также для включения и использования директив.

Однако, когда вы имеете дело с командами файловой системы, такими как fopen, корневой каталог ('/') является системным корнем. Не ваш корень домена.

Чтобы исправить это, попробуйте указать полный путь к файлу журнала, который вы хотите открыть из корня системы. Например: /var/www/phpapplication/logs/myLogFile.txt

Или вы можете использовать $_SERVER['DOCUMENT_ROOT'], как предложено в других ответах, для доступа к хранимому значению вашего сервера для пути к корню документа. Часть /var/www.

Отредактировано для уточнения.

Ответ 2

Вы пробовали это?

$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 и его подкаталогах.

Ответ 3

Один из способов, которым я столкнулся с этой проблемой в UBUNTU 14.04, - это щелкнуть правой кнопкой мыши по каталогу, в котором находится файл, и изменить разрешения "других" на "создание и удаление файлов".

Ответ 4

Вы всегда можете открыть свой файл только с помощью "a", он также создаст новый файл.
Нет необходимости делать условие.

Однако основная проблема с вашим кодом заключается в понимании разницы между физической файловой системой и виртуальным веб-сервером, которые были полностью объяснены.

Обратите внимание, что вы должны указать свой вопрос с точной копией сообщения об ошибке. Он содержит тонну чрезвычайно полезной информации, это не похоже на клятву "Я не буду создавать ваш файл, уходи!" но это объяснение того, что и почему происходит неправильно. Если вы не заботитесь о такой полезной информации, вы должны предоставить ее тем, кто просит о помощи.

Ответ 5

Путь к файлу должен быть с корнем сервера. Я мог бы достичь этого, используя  phpinfo() метод внутри документа, который я хотел знать. Поэтому, когда вы используете phpinfo(), вы увидите информационный документ. Если вы найдете   _SERVER [ "SCRIPT_FILENAME" ] вы увидите абсолютный путь к вашему файлу.

Я надеюсь, что это поможет кому-то.

Ответ 6

Не забудьте убедиться, что SELinux не блокирует вас.

[root @yourbox] # audit2allow </var/log/audit/audit.log
# ============= httpd_t ==============
#!!!! Этот avc можно разрешить с помощью логического 'httpd_unified' разрешить httpd_t httpd_sys_content_t: dir {написать add_name};
#!!!! Этот avc можно разрешить с помощью логического 'httpd_unified' разрешить httpd_t httpd_sys_content_t: файл {написать create}; [root @yourbox] # audit2allow -a -M my_httpd

Примечание:

Чтобы сделать этот пакет политики активным, выполните:

semodule -i my_httpd.pp

[root @yourbox] # semodule -i my_httpd.pp
[root @yourbox] # systemctl restart httpd