Php fopen не открывает файл
Примеры сохранения и чтения текстовых данных и массивов в файлы.
Сохранение в файл
Функция file_put_contents() записывает содержимое переменной в файл, если файла не существует. то пытается его создать, если существует то полностью перезапишет его.
File_put_contents:
Fopen / fwrite:
Набор функций fopen, fwrite, fclose предназначены для более гибкой работы с файлами.
- fopen – открытие или создание файла.
- fwrite – запись данных.
- fclose – закрытие файла.
Возможные режимы fopen():
Mode | Описание |
---|---|
r | Открывает файл только для чтения, помещает указатель в начало файла. |
r+ | Открывает файл для чтения и записи, помещает указатель в начало файла. |
w | Открывает файл только для записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пробует его создать. |
w+ | Открывает файл для чтения и записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пытается его создать. |
a | Открывает файл только для записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
a+ | Открывает файл для чтения и записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
x | Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт false и выдаст ошибку. Если файл не существует, попытается его создать. |
x+ | Создаёт и открывает для чтения и записи, в остальном имеет то же поведение, что и « x ». |
c | Открывает файл только для записи. Если файл не существует, то он создаётся. Если же файл существует, то он не обрезается (в отличие от « w »), и вызов к этой функции не вызывает ошибку (также как и в случае с « x »). Указатель на файл будет установлен на начало файла. |
c+ | Открывает файл для чтения и записи, в остальном имеет то же поведение, что и « c ». |
Доступно в место fwrite() используют fputs() , разницы ни какой т.к. эта функция является псевдонимом.
В PHP скриптах, вызывая include() , require() , fopen() или их производные, такие как include_once , require_once или даже move_uploaded_file() , часто появляются ошибки или предупреждения:
Не удалось открыть поток: нет такого файла или каталога.
Как быстро найти первопричину проблемы?
Ответ 1
Есть много причин, по которым можно столкнуться с этой ошибкой, и поэтому я дам контрольный список того, что необходимо проверить в первую очередь для решения этой ситуации.
Предположим, у нас есть следующая строка:
require "/path/to/file"
Контрольный список
1. Проверьте путь к файлу на предмет опечаток
проверьте вручную (визуально проверив путь) ;
переместите все, что вызывается с помощью require* или include* в переменную, скопируйте ее и попробуйте получить к ней доступ с терминала:
2. Убедитесь, что путь к файлу правильный с точки зрения относительного и абсолютного пути
если он начинается с косой черты "/", то это относится не к корню папки вашего веб-сайта (корень документа), а к корню вашего сервер :
например, каталог вашего веб-сайта может быть /users/tony/htdocs ;
не относительно пути к корню вашего веб-сайта или файла ;
или всегда используйте абсолютные пути к файлам .
используйте require __DIR__."/relative/path/from/current/file" , который возвращает каталог текущего файла ;
определите SITE_ROOT константу самостоятельно:
в корне каталога вашего веб-сайта создайте файл, например , config.php
в config.php напишите :
в каждом файле, в котором вы хотите сослаться на корневую папку сайта, включите config.php и затем используйте SITE_ROOT константу везде, где хотите:
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>
5. Проверьте настройки PHP
Если установлено, PHP не сможет получить доступ к любому файлу за пределами указанного каталога (даже через символическую ссылку).
По умолчанию не устанавливается, и в этом случае ограничений нет.
Можно проверить, вызвав phpinfo() или используя ini_get("open_basedir") .
Вы можете изменить настройку, отредактировав файл php.ini или файл httpd.conf.
Е сли включено, могут быть ограничения. Однако данный режим был удален в PHP 5.4. Если вы все еще используете версию, которая поддерживает безопасный режим, обновитесь до версии PHP, которая это еще поддерживает .
О тносится только к включению или открытию файлов через сетевой процесс, такой как http://, но не работает для локальной файловой системы.
Э ти опции можно проверить, используя ini_get("allow_url_include") или установи в с помощью ini_set("allow_url_include", "1") .
Этот пользователь владеет файлом и, возможно, родительским каталогом (особенно родительским каталогом, если вы хотите записывать файлы). В большинстве сред общего хостинга это не будет проблемой, потому что ваш пользователь должен владеть всеми файлами под вашим корневым каталогом.
В Linux хорошей практикой будет использова ние chmod 600 (только владелец может читать и писать) или chmod 644 (владелец может писать, но все могут читать) .
Другие случаи
Если ничего из вышеперечисленного не помогло диагностировать проблему, могут возникнуть следующие особые ситуации:
1. Включение библиотеки на основе пути включения
Может случиться так, что вы подключаете библиотеку, например, платформу Zend, используя относительный или абсолютный путь. Например:
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Но по-прежнему получаете такую же ошибку.
Это могло произойти из-за того, что файл, который вы (успешно) включили, сам имеет оператор include для другого файла, и этот второй оператор include предполагает, что вы добавили путь этой библиотеки к пути включения.
Например, упомянутый ранее файл фреймворка Zend может включать следующее:
include "Zend/Mail/Protocol/Exception.php"
что не является включением ни по относительному пути, ни по абсолютному пути. Предполагается, что каталог фреймворка Zend был добавлен в путь включения.
В таком случае единственное практическое решение - добавить каталог в ваш путь включения.
2. SELinux
3. Symfony
Если вы используете Symfony и получаете эту ошибку при загрузке на сервер, возможно, к э ш приложения не был сброшен, либо потому, что app/cache был загружен, либо этот к э ш не был очищен.
Для этого надо выполнить следующую консольную команду:
cache:clear
4. Внутри Zip-файла символы, отличные от A SC II
По-видимому, эта ошибка может произойти также при вызове zip->close(), когда некоторые файлы внутри zip имеют в своем имени не-ASCII символы, такие как, например, «é».
Потенциальное решение - обернуть имя файла, используя utf8_decode(), перед созданием целевого файла.
Ответ 2
В дополнение к предыдущему ответу:
Программное обеспечение для виртуального хостинга
Права доступа к файлам
Ответ 3
Samba Shares
Если у вас есть тестовый сервер Linux и вы работаете из клиента Windows, общий ресурс Samba мешает команде chmod . Даже если вы используете:
chmod -R 777 myfolder
со стороны Linux вполне возможно, что Unix Group\www-data все еще не будет иметь доступ на запись. Есть рабочее решение : если ваш общий ресурс настроен так, что администраторы Windows сопоставлены с корневым каталогом – в Windows откройте разрешения, отключите наследование для вашей папки с копией, а затем предоставьте полный доступ для www-данных.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
fopen() закрепляет именованный ресурс, указанный в аргументе filename , за потоком.
Список параметров
Если PHP установлено, что filename указывает на локальный файл, тогда выполняется попытка открыть поток к этому файлу. Файл должен быть доступен PHP, так что вам следует убедиться, что права доступа на файл это разрешают. Если вы включили безопасный режим или open_basedir, то накладываются дальнейшие ограничения.
На платформе Windows, необходимо экранировать все обратные слеши в пути к файлу или использовать прямые слеши.
Замечание: Поддержка контекста была добавлена в PHP 5.0.0. Для описания контекстов смотрите раздел Потоки.
Возвращаемые значения
Возвращает указатель на файл в случае успешной работы, или FALSE в случае ошибки.
Ошибки
Если открыть файл не удалось, будет сгенерирована ошибка уровня E_WARNING . Вы можете использовать оператор @ для подавления этой ошибки.
Список изменений
Примеры
<?php$handle = fopen ( "/home/rasmus/file.txt" , "r" );
$handle = fopen ( "/home/rasmus/file.jpg" , "wb" );
$handle = fopen ( "http://www.example.com/" , "r" );
$handle = fopen ( "ftp://user:[email protected]/somefile.txt" , "w" );
?>
Примечания
Замечание: Когда опция safe mode включена, PHP проверяет, имеет ли каталог, с которым вы собираетесь работать, такой же UID (владельца), как и выполняемый скрипт.
Замечание:
Если вы сталкиваетесь с проблемами во время чтения или записи файлов, и вы используете PHP в виде серверного модуля, убедитесь в том, что процесс сервера имеет доступ к используемым вами файлам и директориям.
Замечание:
Эта функция также может выполниться успешно, в случае если filename является директорией. Если вы не уверены является ли filename файлом или директорией, то вам необходимо воспользоваться функцией is_dir() , до вызова fopen() .
Я пытаюсь научиться создавать веб-ботов и прорабатываю книгу Майкла Шренка под названием Веб-боты, пауки и скребки экрана . В книге он приводит пример кода базового бота, загружающего веб-страницу. Я скопировал код точно так же, как в книге (без комментариев):
Я поместил этот код в файл php и загрузил на свой сайт. Однако когда я перехожу к нему в браузере, ничего не происходит. Он просто загружает пустую страницу. Без содержания.
Раньше я пробовал другой фрагмент, предоставленный автором, опять же, этот был ТОЧНО скопирован из книги, только с этим я действительно не получил пустую страницу, страница просто пыталась загрузиться, пока не истекло время ожидания. Так и не получил обратно правильный контент:
Я проверил URL-адрес, чтобы убедиться, что файл существует, и он существует. Понятия не имею, почему это не сработает. Я прочитал, как использовать file (); и fopen (); функции в PHP, но насколько я могу судить, они оба используются правильно. Что я здесь делаю не так?
3 ответа
Доступ к URL-адресам через fopen() - плохая идея . Для этого необходимо, чтобы в вашей конфигурации PHP был включен allow_url_fopen , что открывает двери для огромного количества эксплойтов (хостеры отключают его по какой-то причине).
Попробуйте вместо этого использовать функции cURL: они предоставят вам гораздо больше гибкости и контроля . Документация PHP дает вам несколько отличных примеров для начала.
Сначала вы должны поместить error_reporting(E_ALL); ini_set('display_errors', '1'); в свой скрипт, чтобы включить отображение ошибок в вашем скрипте, как AbraCadaver упомянул в своем комментарии.
Причина может быть в том, что allow_url_fopen отключен на вашем хостинге.
Вы можете проверить это через:
Ваш сценарий требует, чтобы true работал правильно.
Если allow_url_fopen не является true или 1 , вы можете попробовать использовать file_get_contents() для загрузки URL.
Не fgets($file_handle, 4096) , а fread($file_handle, 4096) ;
Позже, если вы захотите создать новый файл из извлеченного текста:
Как и большинство языков программирования, PHP поддерживает работу с файлами, которые являются одним из способов хранения информации.
Чтение и запись файлов
Открытие и закрытие файлов
Для открытия файлов в PHP определена функция fopen() . Она имеет следующее определение: resource fopen(string $filename, string $mode) . Первый параметр $filename представляет путь к файлу, а второй - режим открытия. В зависимости от цели открытия и типа файла данный параметр может принимать следующие значения:
'r' : файл открывается только для чтения. Если файла не существует, возвращает false
'r+' : файл открывается только для чтения с возможностью записи. Если файла не существует, возвращает false
'w' : файл открывается для записи. Если такой файл уже существует, то он перезаписывается, если нет - то он создается
'w+' : файл открывается для записи с возможностью чтения. Если такой файл уже существует, то он перезаписывается, если нет - то он создается
'a' : файл открывается для записи. Если такой файл уже существует, то данные записываются в конец файла, а старые данные остаются. Если файл не существует, то он создается
'a+' : файл открывается для чтения и записи. Если файл уже существует, то данные дозаписываются в конец файла. Если файла нет, то он создается
Результатом функции fopen будет дескриптор файла. Этот дескриптор используется для операций с файлом и для его закрытия.
После окончания работы файл надо закрыть с помощью функции fclose() , которая принимает в качестве параметра дескриптор файла. Например, откроем и закроем файл:
Чтение файла
Для чтения файла можно использовать несколько функций. Для построчного чтения используется функция fgets() , которая получает дескриптор файла и возвращает одну считанную строку. Пройдем построчно по всему файлу:
При каждом вызове fgets() PHP будет помещать указатель в конец считанной строки. Чтобы проследить окончание файла, используется функция feof() , которая возвращает true при завершении файла. И пока не будет достигнут конец файла, мы можем применять функцию fgets().
Чтение файла полностью
Если нам надо прочитать файл полностью, то мы можем облегчить себе жизнь, применив функцию file_get_contents() :
При этом нам не надо открывать явно файл, получать дескриптор, а затем закрывать файл.
Поблочное считывание
Также можно провести поблочное считывание, то есть считывать определенное количество байт из файла с помощью функции fread() :
Функция fread() принимает два параметра: дескриптор считываемого файла и количество считываемых байтов. При считывании блока указатель в файле становится в конец этого блока. И также с помощью функции feof() можно отследить завершение файла.
Запись файла
Для записи файла применяется функция fwrite() , которая записывает в файл строку:
Аналогично работает другая функция fputs() :
Работа с указателем файла
При открытии файла для чтения или записи в режиме 'w', указатель в файле помещается в начало. При считывании данных PHP перемещает указатель в файле в конец блока считанных данных. Однако мы также вручную можем управлять указателем в файле и устанавливать его в произвольное место. Для этого надо использовать функцию fseek, которая имеет следующее формальное определение:
Параметр $handle представляет дескриптор файла. Параметр $offset - смещение в байтах относительно начала файла, с которого начнется считывание/запись. Третий необязательный параметр задает способ установки смещения. Он может принимать три значения:
SEEK_SET : значение по умолчанию, устанавливает смещение в offset байт относительно начала файла
SEEK_CUR : устанавливает смещение в offset байт относительно начала текущей позиции в файле
SEEK_END : устанавливает смещение в offset байт от конца файла
В случае удачной установки указателя функция fseek() возвращает 0, а при неудачной установке возвращает -1.
Читайте также: