Php не создает файл
Здравствуйте!
Пытаюсь создать файл с помощью fopen . Уж и на папки, вплоть до корневой папки проекта html/proj 3 7-ки поставил, и юзера с группой им на apache поменял, и абсолютный путь от корня указал - все равно получаю permission denied!
У меня 3-я Федора, а в ней Апач 2.0.52 и PHP 4.3.9.
> а апач в логах что пишет?Была такая же проблема, пол дня мучился, пока не вспомнил про selinux.
Отключил selinux - все заработало
>Здравствуйте!
>Пытаюсь создать файл с помощью fopen . Уж и на папки, вплоть
>до корневой папки проекта html/proj 3 7-ки поставил, и юзера с
>группой им на apache поменял, и абсолютный путь от корня указал
>- все равно получаю permission denied!
>У меня 3-я Федора, а в ней Апач 2.0.52 и PHP 4.3.9.
>php.ini:
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
;open_basedir =
>php.ini:
>
>; open_basedir, if set, limits all file operations to the defined directory
>
>; and below. This directive makes most sense if used in
>a per-directory
>; or per-virtualhost web server configuration file. This directive is
>; *NOT* affected by whether Safe Mode is turned On or Off.
>
>;open_basedir =Ну, у меня так и есть. Я так понимаю, что эта опция ограничивает каталоги, в которых могут стартовать скрипты. Они у меня прекрасно запускаются. Вот только файлы не создают.
>Ну, у меня так и есть. Я так понимаю, что эта опция
>ограничивает каталоги, в которых могут стартовать скрипты. Они у меня прекрасно
>запускаются. Вот только файлы не создают.Эта опция ограничивает _все_ файловые операции заданым каталогом. То есть, можно все что угодно делать с файлами. Но только в пределах заданного каталога.
В целом, проверить проще-простого. Если опция включена(раскоментирована), отключить ее и проверить, создаются ли файлы. Если создаются, то стало быть, проблема именно тут. Если же не создаются, то проверить права, может быть файловая система смонтирована в ro(ну, мало ли, всякое бывает).
Присоединяюсь, проблемы теже, Fedora14+Apache2+php5.3 только у меня и в темп тоже не пишет.
Права выданы коммандой chmod -R 777 /var/wwww/html(у меня это значение установлено в качестве DocumentRoot в httpd.conf)
Апач выдает вот такую ошибку
Warning: fopen(/var/www/html/file.txt) [function.fopen]: failed to open stream: Permission denied in /var/www/html/file.php on line 496
Error:Cannot create file '/var/www/html/file.txt'
скрипт -
$filename = "/var/www/html/file.txt"; ---- LINE 496
if(!($myfile = fopen($filename, "w")))
{
print("Error:");
print("Cannot create file '$filename' \n");
exit;
}
fputs($myfile,"Save this string");
fputs($myfile, "This string is to save too");
fclose($myfile);
if(!($myfile = fopen($filename, "r")))
{
print("Error:");print("Cannot open file '$filename'");
exit;
}
while(!feof($myfile))
{
$myline = fgets($myfile, 255);
print("$myline
\n");
}
fclose($myfile);Может быть дело в UID,GID ?
Пробую создать файл для sites-avalibe, использую для этого php для ввода данных и bash чтобы это все заработало, но я потерпел фиаско, правда я не понимаю в чем проблема, ведь если я попытаюсь исполнить скрипт из консоли все работает, а через веб-страницу нет
php файл с формой
1 ответ 1
если я попытаюсь исполнить скрипт из консоли все работает, а через веб-страницу нет
Первая причина - права на файлы.
выведет что-то похожее:
Получается, что права на запись только у владельца ( root ). Введите в консоли whoami - скорее всего вы и есть root.
А через вебсервер php-скрипт запускается от имени другого пользователя и группы, это устанавливается в настройках /etc/apache2/apache2.conf . Поищем эти настройки:
Поищем эти переменные:
Получается, что апач работает от имени www-data и группы www-data .
Чтобы разрешить доступ, нужно сменить владельца:
либо где-то в конце /etc/apache2/apache2.conf поменять
на другой каталог, доступный для записи www-data . Что делает a2ensite ? По сути, она делает симлинки из sites-available в sites-enabled , поэтому a2ensite после такой перенастройки (смена IncludeOptional ) не обязательно выполнять.
Опция open_basedir дополнительно ограничивает PHP какими-то каталогами. Поискать можно так:
Удалите open_basedir или добавьте каталог /etc/apache2/sites-available в эту настройку.
Пользователь www-data , от имени которого запускается скрипт, скорее всего не имеет прав на запуск административных команд с помощью sudo.
Как настроить запуск sudo . без ввода пароля я подробно описал тут
Вам нужно запускать две команды: a2ensite и systemctl . Выполните:
Затем необходимо вставить в конце следующее:
В данном случае спец. группу создавать не надо, мы просто даем доступ конкретному пользователю.
Делайте все поэтапно, смотря результат. Чтобы не запускать каждый раз php-скрипт и ломать голову, зайдите от имени апача и выполняйте аналогичные команды. Давайте зайдем под www-data :
вот так можно понять, что первый пункт работает:
Ага. Не настроено.
Ага. Требует пароль. Не настроено.
Ограничение open_basedir можно проверить только через браузер.
PS. По сути, вы делаете свою реализацию давно решенной задачи по добавлению виртуальных хостов через веб-панель. Насколько безопасно вы это сделаете - зависит от вас. Если что, есть уже готовые решения: cPanel , ISPmanager и другие.
в рамках ведения журнала приложение, которое я пытаюсь открыть локальный файл, и если файл еще не существует, создать новый. Вот что у меня есть:
Я дважды проверил, и /logs каталог chmod 0777, и я даже пошел дополнительный шаг chown'ING его apache:apache для хорошей меры. Тем не менее, когда скрипт открывает файл, он дает мне предупреждение о том, что файл не существует, и бомбит. Файл никогда не создается.
Я нужно подавить fopen() предупреждение, чтобы заставить его создать файл?
когда вы работаете с путями в PHP, контекст имеет большое значение. Если вы работаете с URL-адресами в контексте перенаправления , корневой каталог ( ' / ' ) ссылается на корневой каталог вашего домена. То же самое касается путей для связывания файлов или изображений и директив include и require.
однако, когда вы имеете дело с командами файловой системы, такими как fopen корневой каталог ('/') является корневая система. Не ваш домен root.
или вы можете использовать $_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.
вы пробовали это?
сервер, на котором вы работаете, мог бы посадить вас в тюрьму только для работы в каталоге phpapp и его подкаталогах.
один из способов обойти эту проблему в UBUNTU 14.04 - щелкнуть правой кнопкой мыши по каталогу, где находится файл, и изменить разрешения "другие" на "создание и удаление файлов".
вы всегда можете открыть файл с помощью just "a" , Он также создаст новый файл.
Не нужно ставить условие.
однако основной проблемой вашего кода является понимание разницы между физической файловой системой и виртуальным веб-сервером, что уже было прекрасно объяснено.
путь к файлу должен быть с корневым сервером. Я мог бы достичь этого, используя функцию phpinfo() метод внутри документа, который я хотел знать. Поэтому при использовании phpinfo () вы увидите информационный документ. Если вы найдете для _SERVER ["SCRIPT_FILENAME"] вы увидите абсолютный путь к вашему файлу.
Я надеюсь, что это поможет кому-то.
Не забудьте убедиться, что SELinux не блокирует вас.
Примечание:
чтобы сделать этот пакет активной политики, выполните:
В рамках ведения журнала приложения я пытаюсь открыть локальный файл и, если этот файл еще не существует, создать новый. Вот что у меня есть:
Я дважды проверил, что каталог /logs - это chmod 0777, и я даже пошел на дополнительный шаг, переместив его в apache: apache для хорошей меры. Тем не менее, когда сценарий открывает файл, он выдает предупреждение о том, что файл не существует, и вылетает из строя. Файл никогда не создается.
Нужно ли мне подавлять предупреждение fopen() , чтобы заставить его создать файл?
Когда вы работаете с путями в PHP, контекст может иметь большое значение. Если вы работаете с URL-адресами в контексте перенаправления, то корневой каталог ('/') относится к корню вашего домена. То же самое касается путей для связывания файлов или изображений и директив include и require.
Однако, когда вы имеете дело с командами файловой системы, такими как fopen , корневой каталог ('/') является системным корнем. Не корень вашего домена.
Или вы можете использовать $_SERVER['DOCUMENT_ROOT'] , как предлагается в других ответах, для доступа к сохраненному на вашем сервере значению для пути к корню документа. Часть /var/www .
В некоторых случаях вы также можете использовать магическую константу __DIR__ . Обратите внимание, что __DIR__ будет каталогом, в котором находится текущий файл, который не обязательно совпадает с корнем вашего приложения. Так, например, если корень вашего приложения - /var/www/application , а вы работаете в /var/www/application/src/controllers/my_controller.php , то __DIR__ будет /var/www/application/src/controllers . См. здесь, в документации PHP.
Вы пробовали это?
Сервер, на котором вы работаете, мог посадить вас в тюрьму, чтобы вы работали только в каталоге phpapp и его подкаталогах.
Один из способов обойти эту проблему в UBUNTU 14.04 - щелкнуть правой кнопкой мыши каталог, в котором находится файл, и изменить права доступа «других» на «создавать и удалять файлы».
Вы всегда можете открыть свой файл, просто используя "a" , он также создаст новый файл.
Не нужно ставить условие.
Однако основная проблема с вашим кодом - это понимание разницы между физической файловой системой и виртуальным веб-сервером, что уже было прекрасно объяснено.
Путь к файлу должен соответствовать корню сервера. Я мог добиться этого с помощью метода phpinfo () внутри документа, который я хотел знать. Итак, когда вы используете phpinfo (), вы увидите информационный документ. Если вы найдете для _SERVER ["SCRIPT_FILENAME"], вы увидите абсолютный путь к вашему файлу.
В настоящее время у меня есть скрипт php, который запускается, когда браузер переходит на веб-страницу. Я пытаюсь написать текстовый файл при запуске сценария, в котором хранится переменная. Владелец папки - apache, но у всех есть чтение и запись, строго в целях тестирования. (Я подумал, что это может быть проблема с разрешениями) SELINUX включен на сервере, и когда я запускаю сценарий с консоли, он создает текстовый файл просто отлично и в правильном каталоге.
Вероятно, ваша проблема связана с тем, что apache не имеет разрешений на запись в указанное вами расположение файла. Перейдите в этот каталог и проверьте разрешения и владение группой с помощью команды ls :
В выходных данных есть три столбца, в которых показаны разрешения, владелец и группа для каталога. Скорее всего, они принадлежат пользователю root и не имеют разрешений для apache на запись в каталог.
Я уверен, что мое решение действительно понятно, но оно сработало:
Вы пробовали изменить каталог с помощью chmodding на 777 ?
Возможно, что-то написано с ошибкой. ^
Что-то еще, что можно попробовать для людей, задающих аналогичный вопрос. Возможно, вы просто делаете простую ошибку, которая не требует от вас возиться с правами доступа к файлам - и если вы делаете эту ошибку, исправление прав доступа к файлам может не помочь.
Убедитесь, что вы используете локальный относительный путь к файлу в file_put_contents ().
Я тоже столкнулся с этой проблемой. В моем случае я обнаружил, что владелец каталога был неправильным. Для типичной установки Apache каталог должен принадлежать www-data: www-data, а не root: root.
Недавно у меня была такая же проблема, и я наткнулся на этот вопрос. К сожалению, choppyfireballs, OP сказал в комментарии, что он нашел свое собственное решение и просто принял ответ, который не помог никому из нас . Затем, после поиска и успеха, чтобы снова заставить file_put_contents работать, я решил поделиться своим решением.
Разрешения моих файлов и каталогов были в порядке, чтобы принимать любую запись (убедитесь, что ваши каталоги chmod 757 , это даст корню и остальным право на запись файлов в это местоположение). Если он по-прежнему не работает так, как у меня, это потому, что ваша система, вероятно, является системой SELinux (Security Enhanced Linux).
Если вы хотите убедиться, что напишите setenforce 0 , это переведет selinux в разрешающий режим, снова запустите ваш скрипт, если он работает, значит, проблема хорошо описана.
В этом случае включите selinux обратно setenforce 1 и попробуйте ls -Zl в каталоге, где находится каталог вашего проекта. это даст вам строку вроде
Сначала вам нужно принять любые контексты public_content_rw_t для записи файла. Тип
Теперь вы должны сказать SELinux, что каталог вашего проекта - public_content_rw_t , иначе вы все равно не сможете записывать файлы. Тип :
И restorecon -RvF /project , чтобы сообщить selinux о применении вышеуказанных спецификаций.
Теперь ваш каталог public_content_rw_t , и вы должны иметь возможность записывать файлы.
Читайте также: