Ошибка «No such file or directory» появляется, когда нужный файл отсутствует.
Давайте исключим самое банальное:
1. Файла нет на диске
user@pc1:~$ cat hello.cpp cat: hello.cpp: No such file or directory
Поскольку отсутствует файл hello.cpp , то выводится ошибка
2. Кириллица в названии
Проверьте, что в названии файла буква «с» не написана кириллицей. Например в расширении «.cpp».
3. Неправильный путь
Пример из Python
data_file= open ("../text.txt",'r')
«../» в общем случае говорит о том, что файл будет искаться на 1 директорию выше, чем файл с кодом.
Если файл лежит в директории с кодом, то следует писать:
data_file= open ("./text.txt",'r')
4. Неправильная битность
Вы можете увидеть ту же ошибку, если пытаетесь запустить например 64-битное приложение на 32-битной Windows
5. Более экзотические причины.
Причина ошибки может быть самой разной, в зависимости от приложения, которое вы используете.
Если это как раз тот случай, напишите о нем в комментариях, в будущем это очень поможет другим.
Нашли опечатку или ошибку? Выделите её и нажмите Ctrl+Enter
Помогла ли Вам эта статья?
There are many reasons why one might run into this error and thus a good checklist of what to check first helps considerably.
Let’s consider that we are troubleshooting the following line:
require "/path/to/file"
Checklist
1. Check the file path for typos
- either check manually (by visually checking the path)
-
or move whatever is called by
require*orinclude*to its own variable, echo it, copy it, and try accessing it from a terminal:$path = "/path/to/file"; echo "Path : $path"; require "$path";Then, in a terminal:
cat <file path pasted>
2. Check that the file path is correct regarding relative vs absolute path considerations
- if it is starting by a forward slash «/» then it is not referring to the root of your website’s folder (the document root), but to the root of your server.
- for example, your website’s directory might be
/users/tony/htdocs
- for example, your website’s directory might be
- if it is not starting by a forward slash then it is either relying on the include path (see below) or the path is relative. If it is relative, then PHP will calculate relatively to the path of the current working directory.
- thus, not relative to the path of your web site’s root, or to the file where you are typing
- for that reason, always use absolute file paths
Best practices :
In order to make your script robust in case you move things around, while still generating an absolute path at runtime, you have 2 options :
- use
require __DIR__ . "/relative/path/from/current/file". The__DIR__magic constant returns the directory of the current file. -
define a
SITE_ROOTconstant yourself :- at the root of your web site’s directory, create a file, e.g.
config.php -
in
config.php, writedefine('SITE_ROOT', __DIR__); -
in every file where you want to reference the site root folder, include
config.php, and then use theSITE_ROOTconstant wherever you like :require_once __DIR__."/../config.php"; ... require_once SITE_ROOT."/other/file.php";
- at the root of your web site’s directory, create a file, e.g.
These 2 practices also make your application more portable because it does not rely on ini settings like the include path.
3. Check your include path
Another way to include files, neither relatively nor purely absolutely, is to rely on the include path. This is often the case for libraries or frameworks such as the Zend framework.
Such an inclusion will look like this :
include "Zend/Mail/Protocol/Imap.php"
In that case, you will want to make sure that the folder where «Zend» is, is part of the include path.
You can check the include path with :
echo get_include_path();
You can add a folder to it with :
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Check that your server has access to that file
It might be that all together, the user running the server process (Apache or PHP) simply doesn’t have permission to read from or write to that file.
To check under what user the server is running you can use posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
To find out the permissions on the file, type the following command in the terminal:
ls -l <path/to/file>
and look at permission symbolic notation
5. Check PHP settings
If none of the above worked, then the issue is probably that some PHP settings forbid it to access that file.
Three settings could be relevant :
- open_basedir
- If this is set PHP won’t be able to access any file outside of the specified directory (not even through a symbolic link).
- However, the default behavior is for it not to be set in which case there is no restriction
- This can be checked by either calling
phpinfo()or by usingini_get("open_basedir") - You can change the setting either by editing your php.ini file or your httpd.conf file
- safe mode
- if this is turned on restrictions might apply. However, this has been removed in PHP 5.4. If you are still on a version that supports safe mode upgrade to a PHP version that is still being supported.
- allow_url_fopen and allow_url_include
- this applies only to including or opening files through a network process such as http:// not when trying to include files on the local file system
- this can be checked with
ini_get("allow_url_include")and set withini_set("allow_url_include", "1")
Corner cases
If none of the above enabled to diagnose the problem, here are some special situations that could happen :
1. The inclusion of library relying on the include path
It can happen that you include a library, for example, the Zend framework, using a relative or absolute path. For example :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
But then you still get the same kind of error.
This could happen because the file that you have (successfully) included, has itself an include statement for another file, and that second include statement assumes that you have added the path of that library to the include path.
For example, the Zend framework file mentioned before could have the following include :
include "Zend/Mail/Protocol/Exception.php"
which is neither an inclusion by relative path, nor by absolute path. It is assuming that the Zend framework directory has been added to the include path.
In such a case, the only practical solution is to add the directory to your include path.
2. SELinux
If you are running Security-Enhanced Linux, then it might be the reason for the problem, by denying access to the file from the server.
To check whether SELinux is enabled on your system, run the sestatus command in a terminal. If the command does not exist, then SELinux is not on your system. If it does exist, then it should tell you whether it is enforced or not.
To check whether SELinux policies are the reason for the problem, you can try turning it off temporarily. However be CAREFUL, since this will disable protection entirely. Do not do this on your production server.
setenforce 0
If you no longer have the problem with SELinux turned off, then this is the root cause.
To solve it, you will have to configure SELinux accordingly.
The following context types will be necessary :
httpd_sys_content_tfor files that you want your server to be able to readhttpd_sys_rw_content_tfor files on which you want read and write accesshttpd_log_tfor log fileshttpd_cache_tfor the cache directory
For example, to assign the httpd_sys_content_t context type to your website root directory, run :
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
If your file is in a home directory, you will also need to turn on the httpd_enable_homedirs boolean :
setsebool -P httpd_enable_homedirs 1
In any case, there could be a variety of reasons why SELinux would deny access to a file, depending on your policies. So you will need to enquire into that. Here is a tutorial specifically on configuring SELinux for a web server.
3. Symfony
If you are using Symfony, and experiencing this error when uploading to a server, then it can be that the app’s cache hasn’t been reset, either because app/cache has been uploaded, or that cache hasn’t been cleared.
You can test and fix this by running the following console command:
cache:clear
4. Non ACSII characters inside Zip file
Apparently, this error can happen also upon calling zip->close() when some files inside the zip have non-ASCII characters in their filename, such as «é».
A potential solution is to wrap the file name in utf8_decode() before creating the target file.
Credits to Fran Cano for identifying and suggesting a solution to this issue
|
Totoro 47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
||||||||
|
1 |
||||||||
|
10.10.2012, 13:27. Показов 17196. Ответов 16 Метки нет (Все метки)
Здравствуйте уважаемые обитатели форума при написании скрипта:
При проверке выходит ошибка: Warning: require_once(appvarsconnections.php) [function.require-once]: failed to open stream: No such file or directory in Z:hometest.mywwwtoolsemaillist_subscribers.p hp on line 3 Fatal error: require_once() [function.require]: Failed opening required ‘appvarsconnections.php’ (include_path=’.;C:phppear’) in Z:hometest.mywwwtoolsemaillist_subscribers.p hp on line 3 Содержание файла connections.php:
Я только учусь PHP поэтому не знаю причину возникновения ошибки пути до файла проверил(файлы тоже присутствуют). Если не сложно подскажите способы решения ошибки(На сколько я понял возникает ошибка открытия потока из за того что он не может найти файл)
__________________
0 |
|
alpex 603 / 578 / 103 Регистрация: 16.07.2012 Сообщений: 1,762 |
||||
|
10.10.2012, 13:31 |
2 |
|||
|
слеши не в ту сторону
Добавлено через 49 секунд Добавлено через 1 минуту
0 |
|
47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
|
|
10.10.2012, 13:45 [ТС] |
3 |
|
Только учусь Warning: require_once(app/vars/connections.php) [function.require-once]: failed to open stream: No such file or directory in Z:hometest.mywwwtoolsemaillist_subscribers.p hp on line 3 Fatal error: require_once() [function.require]: Failed opening required ‘app/vars/connections.php’ (include_path=’.;C:phppear’) in Z:hometest.mywwwtoolsemaillist_subscribers.p hp on line 3 Таблицы ещё просто не дописал.
0 |
|
Почетный модератор
16842 / 6720 / 880 Регистрация: 12.06.2012 Сообщений: 19,967 |
|
|
10.10.2012, 13:51 |
4 |
|
функция не находит его по этому пути. Проверьте, существует ли он там, и нет ли ошибки в названии (возможно даже буква где то русская вместо английской )
1 |
|
47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
|
|
10.10.2012, 14:13 [ТС] |
5 |
|
Пути переписал заново наличие проверил. Добавлено через 10 минут Если не сложно помогите разобраться с ошибкой. Заранее премного благодарен.
0 |
|
KOPOJI Почетный модератор
16842 / 6720 / 880 Регистрация: 12.06.2012 Сообщений: 19,967 |
||||
|
10.10.2012, 14:15 |
6 |
|||
|
а так?
0 |
|
115 / 115 / 39 Регистрация: 11.10.2011 Сообщений: 649 |
|
|
10.10.2012, 14:16 |
7 |
|
0 |
|
KOPOJI |
|
10.10.2012, 14:18
|
|
Не по теме: Heidel, здесь ошибка не в том, что константы уже где то декларировались или еще что то не так с функцией, а в неверном пути к файлу (или отсутствии прав на чтение)
0 |
|
psk-ru 3 / 3 / 2 Регистрация: 13.08.2012 Сообщений: 53 |
||||
|
10.10.2012, 15:59 |
9 |
|||
|
Запустите скрипт connections.php с таким кодом
проверьте путь к файлу
0 |
|
Totoro 47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
||||||||
|
10.10.2012, 21:26 [ТС] |
10 |
|||||||
|
Запустите скрипт connections.php с таким кодом
проверьте путь к файлу Проверил пути, символы на наличие латиницы.
результат:
Добавлено через 2 минуты
а так?
Результатов не принесло =(
0 |
|
3 / 3 / 1 Регистрация: 23.01.2012 Сообщений: 97 |
|
|
10.10.2012, 21:37 |
11 |
|
Warning: require_once(appvarsconnections.php) [function.require-once]: failed to open stream: No such file or directory in Z:hometest.mywwwtoolsemaillist_subscribers.p hp on line 3 а что это за файл list_subscribers.php ?
0 |
|
3 / 3 / 2 Регистрация: 13.08.2012 Сообщений: 53 |
|
|
10.10.2012, 21:52 |
12 |
|
Проверьте на всякий случай нет ли ошибки в имени файла
0 |
|
KOPOJI |
|
10.10.2012, 22:55
|
|
Не по теме:
а что это за файл list_subscribers.php Это файл, из которого пытаются подключить connections.php
0 |
|
47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
|
|
11.10.2012, 13:42 [ТС] |
14 |
|
Проектируя другое приложение заметил вот такую ошибку: и появилось подозрение что такая же ситуация возникает и в этом случае с подключением файла т.е путь указан верно но так как корень находится не в корне а в: C:WebServershometest.mywwwtoolsemail то он ищет в: C:WebServershometest.mywwwtoolsemailappvar sconnections.php и соответственно там этого файла нет потому он его и не находит. Поэтому хотелось бы узнать как устранить эту проблему. Буду благодарен за любую помощь. P.S проверка файла HEX редактором не выявила кириллицы или скрытых символов в указаном мной пути. Миниатюры
0 |
|
47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
|
|
11.10.2012, 14:00 [ТС] |
15 |
|
Подъем скрипта в корень т.е: Z:hometest.mywww устранил проблему и скрипт заработал. Но хотелось бы узнать как выполнять вызовы из внутренних каталогов или это невозможно??? Заранее благодарен за помощь.
0 |
|
Почетный модератор
16842 / 6720 / 880 Регистрация: 12.06.2012 Сообщений: 19,967 |
|
|
11.10.2012, 14:14 |
16 |
|
./ — путь от текущей директории
1 |
|
Totoro 47 / 23 / 3 Регистрация: 28.05.2012 Сообщений: 150 Записей в блоге: 1 |
||||
|
11.10.2012, 14:35 [ТС] |
17 |
|||
|
./ — путь от текущей директории Если не сложно не могли бы вы привести пример или статью где об этом можно прочитать а то не совсем понял мысль. Добавлено через 9 минут
0 |
За последние 24 часа нас посетили 9016 программистов и 810 роботов. Сейчас ищет 331 программист …
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Привет пхп.ру!
У меня проблема.
Я — владелец сайта. Сайт был написан для меня под заказ и для личных целей, то есть без авторизации там делать нечего совсем. И как следствие — мои познания в программировании сильно ограничены.Совершенно неожиданно сайт перестал функционировать как надо, вообще никаких изменений не делал — перестали выполняться задания в Cron.
Точнее, сам крон работает, и если руками пытаться выполнить задание — тоже успешно, но задание не выполняется в итоге, т.к. натыкается на следующую ошибку:-
[23-Jan-2014 22:06:30 Europe/Moscow] PHP Warning: include_once(./include/basePliginClass.php) [function.include-once]: failed to open stream: No such file or directory in /home/cp***/public_html/plugins/copypost.php on line 3
-
[23-Jan-2014 22:06:30 Europe/Moscow] PHP Warning: include_once() [function.include]: Failed opening ‘./include/basePliginClass.php’ for inclusion (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/cp***/public_html/plugins/copypost.php on line 3
-
[23-Jan-2014 22:06:30 Europe/Moscow] PHP Warning: include_once(./include/function.php) [function.include-once]: failed to open stream: No such file or directory in /home/cp***/public_html/plugins/copypost.php on line 4
-
[23-Jan-2014 22:06:30 Europe/Moscow] PHP Warning: include_once() [function.include]: Failed opening ‘./include/function.php’ for inclusion (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/cp***/public_html/plugins/copypost.php on line 4
-
[23-Jan-2014 22:06:30 Europe/Moscow] PHP Fatal error: Class ‘basePluginClass’ not found in /home/cp***/public_html/plugins/copypost.php on line 6
Звёздочками в /home/cp закрыл я, на всякий случай, дабы избежать лишнего внимания. Мало ли что.
Так вот, директорию эту я проверил — и ./include/basePliginClass.php и /home/cp***/public_html/plugins/copypost.php — файлы на месте, разрешения в порядке (стояли 644, попробовал 777 — никакого эффекта)
Попытался перезапустить апач, подключившись к хостингу через SSH (по данным, которые дал мне хостер), но там открывается jailshell и на этом я застреваю. Видимо, надо как-то подключиться через SSH серверу, установленному на хостинге, но я не представляю как это сделать.
Сейчас я в тупике, рассказал что знаю, надеюсь на вашу помощь.
Спасибо.
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
да. стать админом. например, расскажите, как именно вы проверили путь
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Открыл в файл-менеджере данный путь и проверил наличие этого файла, больше никак не могу.
Если ваш вопрос касается точки перед путём — то проверял я в той директории, из которой выполняется сам php-скрипт (у меня это /home/cp***/public_html/) -

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
А поиском этот файл найти можно? Он существует?
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Да, в файловом менеджере поиском находит в этой же директории
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
На папку разрешения тоже 777 попробуй
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
странно чо
давай ищи админа, давай ему доступ. так через форум это всё решать нереально. ну по крайней мере у меня фантазия кончилась. осталось только отключить selinux, если он у вас есть, и вопрос, почему он включился, если это он.
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Жаль.
Спасибо за проявленное внимание к проблеме, пошел на фриланс проект создавать.
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Дебиан, кажется. Но не могу быть уверен, где-то посмотреть можно?
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
я не помню. почитайте как отключить selinux, отключите и попробуйте снова.
-

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
если у вас проект комерческий — наймите админа и арендуйте VPS
Добавлено спустя 22 секунды:
php 5.5 на дворе, они только 5.3 поставили -

- С нами с:
- 28 янв 2014
- Сообщения:
- 10
- Симпатии:
- 0
Нет, не коммерческий, для личных целей просто работает.
-

Команда форума
Модератор- С нами с:
- 18 мар 2010
- Сообщения:
- 32.415
- Симпатии:
- 1.768
может хостинг сменить? это знакомые?
-

san4ez
Активный пользователь- С нами с:
- 13 авг 2016
- Сообщения:
- 331
- Симпатии:
- 47
возникла такая же ошибка, когда решил залить на хостинг… на локалке все работает. а там
Warning: include(/include/top.php): failed to open stream: No such file or directory in /home/u828830295/public_html/index.php on line 5Warning: include(): Failed opening ‘/include/top.php’ for inclusion (include_path=’.:/opt/php-7.0/pear’) in /home/u828830295/public_html/index.php on line 5
пробовал и полный путь, тогда еще дополнительно вылазила ошибка
Warning: include(): http:// wrapper is disabled in the server configuration by allow_url_include=0 in /home/u828830295/public_html/index.php on line 5 -

san4ez
Активный пользователь- С нами с:
- 13 авг 2016
- Сообщения:
- 331
- Симпатии:
- 47
мой косяк был… папка Include с большой буквы была создана
This blog post is all about how to handle errors from the PHP file_get_contents function, and others which work like it.
The file_get_contents function will read the contents of a file into a string. For example:
<?php
$text = file_get_contents("hello.txt");
echo $text;
You can try this out on the command-line like so:
$ echo "hello" > hello.txt
$ php test.php
hello
This function is widely used, but I’ve observed that error handling around it is often not quite right. I’ve fixed a few bugs involving incorrect I/O error handling recently, so here are my thoughts on how it should be done.
How file_get_contents fails
For legacy reasons, this function does not throw an exception when something goes wrong. Instead, it will both log a warning, and return false.
<?php
$filename = "not-a-real-file.txt";
$text = file_get_contents($filename);
echo $text;
Which looks like this when you run it:
$ php test.php
PHP Warning: file_get_contents(not-a-real-file.txt): failed to open stream: No such file or directory in test.php on line 3
PHP Stack trace:
PHP 1. {main}() test.php:0
PHP 2. file_get_contents() test.php:3
Warnings are not very useful on their own, because the code will continue on without the correct data.
Error handling in four steps
If anything goes wrong when you are reading a file, your code should be throwing some type of Exception which describes the problem. This allows developers to put a try {} catch {} around it, and avoids nasty surprises where invalid data is used later.
Step 1: Detect that the file was not read
Any call to file_get_contents should be immediately followed by a check for that false return value. This is how you know that there is a problem.
<?php
$filename = "not-a-real-file.txt";
$text = file_get_contents($filename);
if($text === false) {
throw new Exception("File was not loaded");
}
echo $text;
This now gives both a warning and an uncaught exception:
$ php test.php
PHP Warning: file_get_contents(not-a-real-file.txt): failed to open stream: No such file or directory in test.php on line 3
PHP Stack trace:
PHP 1. {main}() test.php:0
PHP 2. file_get_contents() test.php:3
PHP Fatal error: Uncaught Exception: File was not loaded in test.php:5
Stack trace:
#0 {main}
thrown in test.php on line 5
Step 2: Suppress the warning
Warnings are usually harmless, but there are several good reasons to suppress them:
- It ensures that you are not depending on a global error handler (or the absence of one) for correct behaviour.
- The warning might appear in the middle of the output, depending on
php.ini. - Warnings can produce a lot of noise in the logs
Use @ to silence any warnings from a function call.
<?php
$filename = "not-a-real-file.txt";
$text = @file_get_contents($filename);
if($text === false) {
throw new Exception("File was not loaded");
}
echo $text;
The output is now only the uncaught Exception:
$ php test.php
PHP Fatal error: Uncaught Exception: File was not loaded in test.php:5
Stack trace:
#0 {main}
thrown in test.php on line 5
Step 3: Get the reason for the failure
Unfortunately, we lost the “No such file or directory” message, which is pretty important information, which should go in the Exception. This information is retrieved from the old-style error_get_last method.
This function might just return empty data, so you should check that everything is set and non-empty before you try to use it.
<?php
$filename = "not-a-real-file.txt";
error_clear_last();
$text = @file_get_contents($filename);
if($text === false) {
$e = error_get_last();
$error = (isset($e) && isset($e['message']) && $e['message'] != "") ?
$e['message'] : "Check that the file exists and can be read.";
throw new Exception("File '$filename' was not loaded. $error");
}
echo $text;
This now embeds the failure reason directly in the message.
$ php test.php
PHP Fatal error: Uncaught Exception: File 'not-a-real-file.txt' was not loaded. file_get_contents(not-a-real-file.txt): failed to open stream: No such file or directory in test.php:9
Stack trace:
#0 {main}
thrown in test.php on line 9
Step 4: Add a fallback
The last time I introduced error_clear_last()/get_last_error() into a code-base, I learned out that HHVM does not have these functions.
Call to undefined function error_clear_last()
The fix for this is to write some wrapper code, to verify that each function exists.
<?php
$filename = 'not-a-real-file';
clearLastError();
$text = @file_get_contents($filename);
if ($text === false) {
$error = getLastErrorOrDefault("Check that the file exists and can be read.");
throw new Exception("Could not retrieve image data from '$filename'. $error");
}
echo $text;
/**
* Call error_clear_last() if it exists. This is dependent on which PHP runtime is used.
*/
function clearLastError()
{
if (function_exists('error_clear_last')) {
error_clear_last();
}
}
/**
* Retrieve the message from error_get_last() if possible. This is very useful for debugging, but it will not
* always exist or return anything useful.
*/
function getLastErrorOrDefault(string $default)
{
if (function_exists('error_clear_last')) {
$e = error_get_last();
if (isset($e) && isset($e['message']) && $e['message'] != "") {
return $e['message'];
}
}
return $default;
}
This does the same thing as before, but without breaking other PHP runtimes.
$ php test.php
PHP Fatal error: Uncaught Exception: Could not retrieve image data from 'not-a-real-file'. file_get_contents(not-a-real-file): failed to open stream: No such file or directory in test.php:7
Stack trace:
#0 {main}
thrown in test.php on line 7
Since HHVM is dropping support for PHP, I expect that this last step will soon become unnecessary.
How not to handle errors
Some applications put a series of checks before each I/O operation, and then simply perform the operation with no error checking. An example of this would be:
<?php
$filename = "not-a-real-file.txt";
// Check everything!
if(!file_exists($filename)) {
throw new Exception("$filename does not exist");
}
if(!is_file($filename)) {
throw new Exception("$filename is not a file");
}
if(!is_readable($filename)) {
throw new Exception("$filename cannot be read");
}
// Assume that nothing can possibly go wrong..
$text = @file_get_contents($filename);
echo $text;
You could probably make a reasonable-sounding argument that checks are a good idea, but I consider them to be misguided:
- If you skip any actual error handling, then your code is going to fail in more surprising ways when you encounter an I/O problem that could not be detected.
- If you do perform correct error handling as well, then the extra checks add nothing other than more branches to test.
Lastly, beware of false positives. For example, the above snippet will reject HTTP URL’s, which are perfectly valid for file_get_contents.
Conclusion
Most PHP code now uses try/catch/finally blocks to handle problems, but the ecosystem really values backwards compatibility, so existing functions are rarely changed.
The style of error reporting used in these I/O functions is by now a legacy quirk, and should be wrapped to consistently throw a useful Exception.
I believe the issue here is that localhost is not your database host. If that PHP script is running in the «www» docker container, localhost most likely does not have a listening MySQL server. IIRC, the «file not found» error from mysqli is due to not finding the MySQL socket on localhost. I also do not see that you are exposing any ports for the «db» image, so I am not sure how «www» is supposed to connect to a database running inside it.
You would want to find what the address to the «db» docker container is, and what port it is listening on, then reference that in your mysqli_connect() function. An easier method, if you have a recent version of docker, would be to add your containers to the same Docker network and reference them by name.
EDIT: Docker Networking
You should read up on the networking feature in the official documentation as it is very useful. You can probably use the following docker-compose.yml (not tested):
version: '3.1'
services:
db:
image: mysql
restart: always
environment:
- MYSQL_DATABASE=mgsv
- MYSQL_USER=mgsv_user
- MYSQL_PASSWORD=mgsvpass
- MYSQL_ROOT_PASSWORD=mysql123
volumes:
- ./mysql:/docker-entrypoint-initdb.d
networks:
- web-db-net
www:
build: ./mGSV
restart: always
ports:
- 8080:80
networks:
- web-db-net
networks:
web-db-net:
Then change your connect line to refer to the db container by name (you would also need to specify port if not using the MySQL default, 3306):
$con = mysqli_connect("db","mgsv_user","mgsvpass","mgsv");
EDIT2: fixed docker-compose.yml so that networks actually works
В скриптах PHP, вызывающих include(), require(), fopen() или их производных, таких как include_once, require_once или даже, move_uploaded_file(), часто возникает ошибка или предупреждение:
Не удалось открыть поток: нет такого файла или каталога.
Что такое хороший процесс, чтобы быстро найти основную причину проблемы?
Ответ 1
Есть много причин, по которым можно столкнуться с этой ошибкой, и, таким образом, хороший контрольный список того, что проверять в первую очередь, помогает значительно.
Давайте рассмотрим, что мы устраняем неисправности в следующей строке:
require "/path/to/file"
Контрольный
1. Проверьте путь к файлу для опечаток
- либо проверяйте вручную (визуально проверяя путь)
-
или переместите все, что вызвано
require*илиinclude*, в свою переменную, отобразите его, скопируйте и попробуйте получить доступ к нему из терминала:$path = "/path/to/file"; echo "Path : $path"; require "$path";Затем в терминале:
cat <file path pasted>
2. Проверьте, правильно ли указан путь к файлу относительно относительного или абсолютного пути.
- если он начинается с косой черты «/», то это относится не к корню папки вашего сайта (корню документа), а к корню вашего сервера.
- например, каталог вашего сайта может быть
/users/tony/htdocs
- например, каталог вашего сайта может быть
- если он не начинается с косой черты, то он либо полагается на путь включения (см. ниже), либо путь является относительным. Если он относительный, то PHP рассчитает относительно пути к текущему рабочему каталогу.
- таким образом, не относительно пути к корню вашего веб-сайта или файла, в который вы вводите
- по этой причине всегда используйте абсолютные пути к файлам
Лучшие практики:
Чтобы сделать ваш сценарий надежным на случай, если вы все передвигаете, и при этом генерируете абсолютный путь во время выполнения, у вас есть 2 варианта:
- используйте
require __DIR__ . "/relative/path/from/current/file". Волшебная константа__DIR__возвращает каталог текущего файла. -
определите константу
SITE_ROOTсамостоятельно:- в корне каталога вашего веб-сайта создайте файл, например,
config.php -
в
config.phpнапишитеdefine('SITE_ROOT', __DIR__); -
в каждом файле, где вы хотите сослаться на корневую папку сайта, включите
config.php, а затем используйте константуSITE_ROOT, где хотите:require_once __DIR__."/../config.php"; ... require_once SITE_ROOT."/other/file.php";
- в корне каталога вашего веб-сайта создайте файл, например,
Эти 2 метода также делают ваше приложение более переносимым, поскольку оно не зависит от настроек ini, таких как путь включения.
3. Проверьте ваш путь включения
Другой способ включения файлов, ни относительный, ни сугубо абсолютный, заключается в использовании пути включения. Это часто относится к библиотекам или фреймворкам, таким как Zend Framework.
Такое включение будет выглядеть так:
include "Zend/Mail/Protocol/Imap.php"
В этом случае вам нужно убедиться, что папка, в которой находится «Zend», является частью пути включения.
Вы можете проверить путь включения с помощью:
echo get_include_path();
Вы можете добавить в него папку с помощью:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Убедитесь, что ваш сервер имеет доступ к этому файлу
Может случиться так, что все вместе, пользователь, выполняющий процесс сервера (Apache или PHP), просто не имеет разрешения на чтение или запись в этот файл.
Чтобы проверить, под каким пользователем работает сервер, вы можете использовать posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Чтобы узнать разрешения для файла, введите в терминале следующую команду:
ls -l <path/to/file>
и посмотрите символьную запись разрешения
Если ничего из вышеперечисленного не сработало, возможно, проблема в том, что некоторые настройки PHP запрещают ему доступ к этому файлу.
Три настройки могут иметь отношение:
- open_basedir
- Если это установлено, PHP не сможет получить доступ ни к какому файлу за пределами указанного каталога (даже через символическую ссылку).
- Тем не менее, поведение по умолчанию не должно быть установлено, в этом случае нет никаких ограничений
- Это можно проверить, позвонив
phpinfo()или воспользовавшисьini_get("open_basedir") - Вы можете изменить настройку, отредактировав файл php.ini или файл httpd.conf
- .безопасный режим
- если это включено, ограничения могут применяться. Однако это было удалено в PHP 5.4. Если вы все еще используете версию, которая поддерживает обновление в безопасном режиме, до версии PHP, которая все еще поддерживается.
- allow_url_fopen и allow_url_include
- это относится только к включению или открытию файлов через сетевой процесс, такой как http://не при попытке включить файлы в локальную файловую систему
- это можно проверить с помощью
ini_get("allow_url_include")и установить с помощьюini_set("allow_url_include", "1")
Angular чехлы
Если ничего из перечисленного не позволяет диагностировать проблему, вот несколько особых ситуаций, которые могут возникнуть:
1. Включение библиотеки с использованием пути включения
Может случиться так, что вы включите библиотеку, например, Zend Framework, используя относительный или абсолютный путь. Например:
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Но тогда вы все равно получаете такую же ошибку.
Это может произойти из-за того, что файл, который вы (успешно) включили, сам имеет оператор включения для другого файла, и этот второй оператор включения предполагает, что вы добавили путь этой библиотеки к пути включения.
Например, упомянутый ранее файл Zend Framework может содержать следующее:
include "Zend/Mail/Protocol/Exception.php"
который не является ни включением ни по относительному пути, ни по абсолютному пути. Предполагается, что каталог Zend Framework был добавлен в путь включения.
В таком случае единственное практическое решение — добавить каталог в путь включения.
2. SELinux
Если вы работаете в Security-Enhanced Linux, это может быть причиной проблемы, поскольку доступ к файлу с сервера запрещен.
Чтобы проверить, включен ли SELinux в вашей системе, выполните команду sestatus в терминале. Если команда не существует, значит, SELinux отсутствует в вашей системе. Если он существует, он должен сообщить вам, применяется ли он принудительно или нет.
Чтобы проверить, являются ли политики SELinux причиной проблемы, вы можете временно отключить ее. Однако будьте осторожны, так как это полностью отключит защиту. Не делайте этого на своем производственном сервере.
setenforce 0
Если проблема с выключенным SELinux больше не возникает, это является основной причиной.
Чтобы решить эту проблему, вам необходимо соответствующим образом настроить SELinux.
Будут необходимы следующие типы контекста:
httpd_sys_content_tдля файлов, которые вы хотите, чтобы ваш сервер мог читатьhttpd_sys_rw_content_tдля файлов, к которым вы хотите иметь права на чтение и записьhttpd_log_tдля файлов журналаhttpd_cache_tдля каталога кэша
Например, чтобы назначить тип контекста httpd_sys_content_t для корневого каталога вашего сайта, выполните:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Если ваш файл находится в домашнем каталоге, вам также нужно включить логическое значение httpd_enable_homedirs:
setsebool -P httpd_enable_homedirs 1
В любом случае может быть множество причин, по которым SELinux может запретить доступ к файлу, в зависимости от ваших политик. Так что вам нужно будет выяснить это. Здесь — руководство по настройке SELinux для веб-сервера.
3. Symfony
Если вы используете Symfony и сталкиваетесь с этой ошибкой при загрузке на сервер, возможно, кэш приложения не был сброшен, либо потому, что app/cache был загружен, либо этот кэш не был очищен.
Вы можете проверить и исправить это, выполнив следующую консольную команду:
cache:clear
4. Не ACSII символы внутри Zip файла
По-видимому, эта ошибка также может возникать при вызове zip->close(), когда в некоторых файлах внутри zip есть не-ASCII-символы в имени файла, такие как «é».
Возможное решение — обернуть имя файла в utf8_decode() перед созданием целевого файла.
Кредиты Фрэн Кано для определения и предложения решения этой проблемы
Ответ 2
Чтобы добавить к (действительно хорошему) существующий ответ
Программное обеспечение общего хостинга
open_basedir — это тот, который может пнуть вас, потому что он может быть указан в конфигурации веб-сервера. Хотя это легко исправить, если вы запускаете собственный выделенный сервер, есть некоторые пакеты хостинга для совместного использования (например, Plesk, cPanel и т.д.), Которые будут настраивать директиву конфигурации для каждого домена. Поскольку программное обеспечение создает файл конфигурации (т.е. httpd.conf), вы не можете изменить этот файл напрямую, поскольку программное обеспечение хостинга просто перезапишет его при перезапуске.
С Plesk они предоставляют место для переопределения предоставленного httpd.conf, называемого vhost.conf. Этот файл может написать только администратор сервера. Конфигурация для Apache выглядит примерно так:
<Directory /var/www/vhosts/domain.com>
<IfModule mod_php5.c>
php_admin_flag engine on
php_admin_flag safe_mode off
php_admin_value open_basedir "/var/www/vhosts/domain.com:/tmp:/usr/share/pear:/local/PEAR"
</IfModule>
</Directory>
Попросите администратора вашего сервера обратиться к руководству по использованию хостинга и веб-серверного программного обеспечения, которое они используют.
Разрешения файла
Важно отметить, что выполнение файла через ваш веб-сервер сильно отличается от выполнения командной строки или выполнения задания cron. Большая разница в том, что ваш веб-сервер имеет свой собственный пользователь и разрешения. По соображениям безопасности пользователь довольно ограничен. Apache, например, часто apache, www-data или httpd (в зависимости от вашего сервера). Задача cron или выполнение CLI имеет все права, которые пользователь запускает (например, запуск PHP скрипт как root будет выполняться с правами root).
Много раз люди решат проблему с разрешениями, выполняя следующие действия (пример Linux)
chmod 777 /path/to/file
Это не умная идея, потому что файл или каталог теперь доступны для всего мира. Если вы владеете сервером и являетесь единственным пользователем, тогда это не так уж и важно, но если вы находитесь в среде совместного размещения, которую вы только что дали всем на вашем сервере, выполните следующие действия.
Что вам нужно сделать, так это определить пользователя (пользователей), которым нужен доступ, и предоставить только те, к которым они имеют доступ. Как только вы узнаете, какие пользователи нуждаются в доступе, вы захотите убедиться, что
-
Этот пользователь имеет файл и, возможно, родительский каталог (особенно родительский каталог, если вы хотите писать файлы). В большинстве общедоступных хостинговых сред это не будет проблемой, потому что ваш пользователь должен владеть всеми файлами под вашим корнем. Пример Linux приведен ниже.
chown apache:apache /path/to/file -
Пользователь и только тот пользователь имеет доступ. В Linux хорошей практикой будет
chmod 600(только владелец может читать и писать) илиchmod 644(владелец может писать, но каждый может читать)
Вы можете прочитать более расширенное обсуждение разрешений и пользователей Linux/Unix здесь
Ответ 3
- Посмотрите на точную ошибку
Мой код работал нормально на всех машинах, но только на этом начали возникать проблемы (которые раньше работали, я думаю). Использовал echo «document_root» путь для отладки, а также внимательно посмотрел на ошибку, нашел это
Предупреждение: включают в себя (D: /MyProjects/testproject//functions/connections.php): не удалось открыть поток:
Вы можете легко увидеть, где проблемы. Проблемы//перед функциями
$document_root = $_SERVER['DOCUMENT_ROOT'];
echo "root: $document_root";
include($document_root.'/functions/connections.php');
Так что просто удалите накладку/из include, и она должна работать нормально. Что интересно, это поведение отличается в разных версиях. Я запускаю один и тот же код на ноутбуке, Macbook Pro и на этом компьютере, пока все работало нормально. Надеюсь, это кому-нибудь поможет.
- Скопируйте файл в браузере, чтобы убедиться, что файл существует. Иногда файлы неожиданно удаляются (случилось со мной), и это также было проблемой в моем случае.
Ответ 4
Добавить скрипт с параметрами запроса
Это был мой случай. На самом деле это ссылка на вопроС# 4485874, но я собираюсь объяснить это здесь в ближайшее время.
Когда вы пытаетесь потребовать path/to/script.php?parameter=value, PHP ищет файл с именем script.php?parameter=value, потому что UNIX позволяет вам иметь такие пути.
Если вам действительно нужно передать некоторые данные во включенный скрипт, просто объявите его как $variable=... или $GLOBALS[]=... или другим способом, который вам нравится.
Ответ 5
Акции Самбы
Если у вас есть тестовый сервер Linux, и вы работаете с клиентом Windows, общий ресурс Samba вмешивается в команду chmod. Так что, даже если вы используете:
chmod -R 777 myfolder
на стороне Linux вполне возможно, что Unix Groupwww-data по-прежнему не имеет доступа для записи. Одно из рабочих решений, если ваш общий ресурс настроен так, что администраторы Windows отображаются в root: в Windows откройте «Разрешения», отключите наследование для вашей папки с копией, а затем предоставьте полный доступ к www-данным.
Ответ 6
Другая возможная причина: переименование и/или перемещение файлов в текстовом редакторе. Я прошел все этапы без успеха, пока не удалил файл, который продолжал бросать эту ошибку и создавал новую, которая исправила проблему.

