file_put_contents не создает текстовый файл

В настоящее время у меня есть php-скрипт, который запускается, когда браузер браузера просматривает веб-страницу. То, что я пытаюсь сделать, это написать текстовый файл при запуске скрипта, в котором хранится переменная. Владелец папки апач, но все читали пишут, строго в целях тестирования. (Я думал, что это может быть проблема с разрешениями) SELINUX включен на сервере, и когда я запускаю скрипт из консоли, он отлично создает текстовый файл и в правильном каталоге.

file_put_contents("My working file location", $myString);

Я использую эту строку, чтобы попытаться написать и создать текстовый файл, я знаю, что мое местоположение файла работает, потому что я могу запустить его и создать в автономном режиме, т.е. запускаю через консоль. Проблема в том, что переменная, которую я пытаюсь записать, заполняется через HTTP Post, и когда я запускаю скрипт через браузер или когда apache запускает скрипт, он не записывает и не создает файл. Что мне нужно сделать, чтобы разрешить доступ к синтаксису записи/изменения, чтобы заставить этот скрипт писать этот текстовый файл?


person choppyfireballs    schedule 15.02.2013    source источник
comment
ваш пользователь apache должен иметь права на каталог — просто попробуйте выполнить скрипт от имени пользователя apache из командной строки, чтобы увидеть, работает ли это   -  person user1914292    schedule 15.02.2013
comment
Проверьте свой журнал ошибок apache, он может дать вам некоторые сведения о том, где произошел сбой.   -  person Matt Clark    schedule 15.02.2013
comment
что такое значение $myString? это правильно ?   -  person Ali Akbar Azizi    schedule 15.02.2013
comment
Какое сообщение об ошибке вы получаете?   -  person Jocelyn    schedule 15.02.2013
comment
Я запускаю его из браузера, и он не помечает никаких ошибок, или, точнее сказать, я не знаю, где взять сообщения об ошибках в браузере. @user1914292 user1914292 Я пробовал несколько мест, включая веб-сайт, владельцем которого является apache, поэтому я не уверен, обязательно ли это проблема. @CooPer `$myString = strReplace(строки xml), так что это просто строковое значение   -  person choppyfireballs    schedule 15.02.2013
comment
Я ошибся, что мой веб-сайт не принадлежит apache, поэтому я создал папку и добавил разрешения и права собственности apache, спасибо @ user1914292   -  person choppyfireballs    schedule 15.02.2013
comment
Если у вас возникли проблемы с Windows, я разместил здесь полезный ответ: stackoverflow.com/questions/4577149/   -  person user2288580    schedule 20.08.2017


Ответы (6)


Ваша проблема, вероятно, связана с тем, что у apache нет прав на запись в указанное вами расположение файла. Перейдите в этот каталог и проверьте разрешения и принадлежность группы с помощью команды ls:

cd "My working file location"
ls -l .

В выходных данных есть три столбца, которые показывают разрешения, владельца и группу для каталога. Скорее всего, они принадлежат пользователю root и не имеют разрешений для apache на запись в каталог.

Если это так, то вы увидите сообщение об ошибке в журнале Apache при попытке создать файл. Попробуйте просмотреть журналы, запустив скрипт в браузере:

tail -f /var/log/apache2/error.log
person Cory Klein    schedule 15.02.2013
comment
Я исправил проблему, это была кульминация разрешений selinux и разрешений apache. - person choppyfireballs; 15.02.2013
comment
Было бы неплохо поделиться своим ответом. Google перенаправил меня сюда, и я все еще заблокирован. - person Vender Aeloth; 02.06.2015
comment
@VenderAeloth Похоже, изменчивые огненные шары здесь не очень активны, но если он не ответит, обязательно поделитесь с нами своим ответом, когда найдете его! - person Cory Klein; 03.06.2015
comment
Я не уверен, что это лучший способ исправить это, но я добавил это: setsebool -P allow_httpd_anon_write true в каталоге, когда мне нужно записать файлы. - person Vender Aeloth; 04.06.2015
comment
@VenderAeloth просто добавьте ответ, чтобы подробно объяснить шаги, которые необходимо выполнить. - person vdegenne; 14.01.2017

Недавно у меня была такая же проблема, и я наткнулся на этот вопрос. К сожалению, прерывистые огненные шары, ОП сказал в комментарии, что нашел свое собственное решение и просто принял ответ, который никому из нас не помог ... Затем, после поиска и успеха, чтобы заставить file_put_contents снова работать, я решил поделиться своим решением.

Права доступа к моим файлам и каталогам были в порядке, чтобы принимать любые записи (убедитесь, что ваши каталоги chmod 757, это даст root и другим разрешение на запись файлов в этом месте). Если это все еще не работает, как у меня, это потому, что ваша система, вероятно, является системой SELinux (Security Enhanced Linux).

Если вы хотите убедиться, что напишите setenforce 0, это переведет selinux в разрешающий режим, снова запустите ваш скрипт, если он работает, значит, проблема хорошо описана.

В этом случае включите selinux обратно setenforce 1 и попробуйте ls -Zl в каталоге, где находится каталог вашего проекта. это даст вам строку вроде

drwx---r-x.  9  root   root  system_u:object_r:httpd_sys_content_t:s0  4096  Dec  8  00:25  project

или что-то другое, но httpd_sys_content_t, если вы использовали chcon для переноса контекста из одного каталога в этот. но если у вас нет httpd_sys_content_t, это нормально, потому что нам все равно нужно изменить контекст этого каталога.

сначала вам нужно принять любые public_content_rw_t контексты для записи файла. Тип

setsebool -P httpd_anon_write on

Это установит (P)постоянно логическое значение SELinux httpd_anon_write в значение true, и любой контекст, дублированный как public_content_rw_t, будет иметь права на запись любых файлов в свое собственное местоположение.

Теперь вы должны сказать SELinux, что каталог вашего проекта public_content_rw_t, иначе вы все равно не сможете записывать файлы. Тип :

semanage fcontext --add --type public_content_rw_t "/project(/.*)?"

и restorecon -RvF /project, чтобы сообщить selinux о необходимости применения указанных выше спецификаций.

Теперь ваш каталог называется public_content_rw_t, и вы должны иметь возможность записывать файлы.

person vdegenne    schedule 14.01.2017
comment
Почему SELinux делает это? Это кажется глупым, поскольку в моем случае это процесс FPM, полностью отделенный от веб-сайта, записывающего на него, строго охраняемый, без пользовательского ввода пути. Мне пришлось добавить 777/667 в папку, что хуже, чем позволить злоумышленнику записать папку. Честно говоря, я чувствую, что эти люди, должно быть, нюхали краски, когда разрабатывали SELinux, он не более безопасен, он просто принимает совершенно неверные решения обо всем без уважительной причины. - person MrMesees; 22.05.2019

Я тоже столкнулся с этой проблемой. В моем случае я обнаружил, что владелец каталога был неправильным. Для типичной установки Apache каталог должен принадлежать www-data:www-data, а не root:root.

person Bob Reite    schedule 13.08.2017

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

Убедитесь, что вы используете локальный, относительный путь к файлу в file_put_contents().

Например, используйте:

file_put_contents('short_local_path/my_working_file.txt', $myString);

Нет:

file_put_contents('http://example.com/remote_path/my_working_file.txt', $myString);

И не:

file_put_contents('/whole/root/file/path/to/my_working_file.txt', $myString);
person Lorien Brune    schedule 05.04.2020

Вы пробовали изменить каталог на 777?

Попробуй это:

if(file_put_contents('file.txt', 'text')){
    die('yes');
} else {
    die('no');
}

Может что-то неправильно написал. ^

person Vlad    schedule 15.02.2013

Я уверен, что мое решение действительно ясно, но оно сработало:

cd /mydir/
setsebool -P allow_httpd_anon_write true 

С наилучшими пожеланиями

person Vender Aeloth    schedule 16.01.2017