- Запись и чтение файлов в PHP
- Сохранение в файл
- File_put_contents:
- Fopen / fwrite:
- Возможные режимы fopen():
- Дописать строку в начало файла
- Дописать строку в конец файла
- Чтение из файла
- Чтение всего файла
- Чтение файла в массив
- Чтение файла сразу в браузер
- Получить первую строку из файла
- Первые три строки из файла:
- Получить последнюю строку из файла
- Последние три строки из файла:
- Запись и чтение массивов в файл
- Serialize
- Запись:
- Чтение:
- JSON
- Запись:
- Чтение:
- PHP class для скачки и закачки файлов на сервер
- 1. Отдача файла через браузер без показа его места хранения с возможностью докачки и регулирования скорости
- 2. Загрузка файла/ов на сервер через браузер с индикатором прогресса
- 3. Скачивание файлов с удаленного сервера на свой сервер
- 4. Отдаем файл на удаленный сервер со своего сервера
- По итогу хочу сказать
Запись и чтение файлов в PHP
Примеры сохранения и чтения текстовых данных и массивов в файлы.
Сохранение в файл
Функция file_put_contents() записывает содержимое переменной в файл, если файла не существует. то пытается его создать, если существует то полностью перезапишет его.
File_put_contents:
$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'; $filename = __DIR__ . '/file.txt'; file_put_contents($filename, $text);
Fopen / fwrite:
Набор функций fopen, fwrite, fclose предназначены для более гибкой работы с файлами.
- fopen – открытие или создание файла.
- fwrite – запись данных.
- fclose – закрытие файла.
$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'; $filename = __DIR__ . '/file.txt'; $fh = fopen($filename, 'w'); fwrite($fh, $text); fclose($fh);
Возможные режимы fopen():
Mode | Описание |
---|---|
r | Открывает файл только для чтения, помещает указатель в начало файла. |
r+ | Открывает файл для чтения и записи, помещает указатель в начало файла. |
w | Открывает файл только для записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пробует его создать. |
w+ | Открывает файл для чтения и записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пытается его создать. |
a | Открывает файл только для записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
a+ | Открывает файл для чтения и записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
x | Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт false и выдаст ошибку. Если файл не существует, попытается его создать. |
x+ | Создаёт и открывает для чтения и записи, в остальном имеет то же поведение, что и « x ». |
c | Открывает файл только для записи. Если файл не существует, то он создаётся. Если же файл существует, то он не обрезается (в отличие от « w »), и вызов к этой функции не вызывает ошибку (также как и в случае с « x »). Указатель на файл будет установлен на начало файла. |
c+ | Открывает файл для чтения и записи, в остальном имеет то же поведение, что и « c ». |
Доступно в место fwrite() используют fputs() , разницы ни какой т.к. эта функция является псевдонимом.
Дописать строку в начало файла
$new_str = 'New line of text.'; $filename = __DIR__ . '/file.txt'; $text = file_get_contents($filename); file_put_contents($filename, $new_str . PHP_EOL . $text);
Дописать строку в конец файла
$new_str = 'New line of text.'; $filename = __DIR__ . '/file.txt'; file_put_contents($filename, PHP_EOL . $new_str, FILE_APPEND);
$new_str = 'New line of text.'; $filename = __DIR__ . '/file.txt'; $fh = fopen($filename, 'c'); fseek($fh, 0, SEEK_END); fwrite($fh, PHP_EOL . $new_str); fclose($fh);
Чтение из файла
Чтение всего файла
$filename = __DIR__ . '/file.txt'; $text = file_get_contents($filename); echo $text;
$filename = __DIR__ . '/file.txt'; $text = ''; $fh = fopen($filename, 'r'); while (!feof($fh)) < $line = fgets($fh); $text .= $line . PHP_EOL; >fclose($fh); echo $text;
Чтение файла в массив
Функция file() – читает содержимое файла и помещает его в массив, доступны опции:
- FILE_IGNORE_NEW_LINES – пропускать новую строку в конце каждого элемента массива.
- FILE_SKIP_EMPTY_LINES – пропускать пустые строки.
$filename = __DIR__ . '/file.txt'; $array = file($filename); print_r($array);
Чтение файла сразу в браузер
$filename = __DIR__ . '/file.txt'; readfile($filename);
Получить первую строку из файла
$filename = __DIR__ . '/file.txt'; $fh = fopen($filename, 'r'); echo fgets($fh); fclose($fh); /* или */ $filename = __DIR__ . '/file.txt'; $array = file($filename); echo $array[0];
Первые три строки из файла:
$filename = __DIR__ . '/file.txt'; $array = file($filename); $first_3 = array_slice($array, 0, 3); print_r($first_3);
Получить последнюю строку из файла
$filename = __DIR__ . '/file.txt'; $array = file($filename); $last = array_slice($array, -1); echo $last[0];
Последние три строки из файла:
$filename = __DIR__ . '/file.txt'; $array = file($filename); $last_3 = array_slice($array, -3); print_r($last_3);
Запись и чтение массивов в файл
Serialize
Не очень удачное хранение данных в сериализованном виде т.к. изменение одного символа может привести к ошибке чтения всех данных в файле. Подробнее в статье «Функция serialize, возможные проблемы»
Запись:
$array = array('foo', 'bar', 'hallo', 'world'); $text = base64_encode(serialize($array)); file_put_contents(__DIR__ . '/array.txt', $text);
Чтение:
$array = unserialize(base64_decode($text)); print_r($array);
JSON
Запись:
$array = array('foo', 'bar', 'hallo', 'world'); $json = json_encode($array, JSON_UNESCAPED_UNICODE); file_put_contents(__DIR__ . '/array.json', $json);
Чтение:
$json = file_get_contents(__DIR__ . '/array.json'); $array = json_decode($json, true); print_r($array);
PHP class для скачки и закачки файлов на сервер
Раньше я об этом не задумывался и пользовался готовым решением типа от Drupal для отдачи файлов и более мне не надо было. Пока несколько месяцев назад у меня не возникла острая необходимость не только отдавать файлы.
В интернете есть много информации о том как скачивать файлы с сервера и загружать файлы на сервер, а также между серверами. Но нигде нет простого решения которое было бы более ли менее универсально.
Я несколько дней убил на изучение всяких заголовков и вариаций использования cUrl, но собрать все воедино не выходило. Видел много разных подобных классов, но везде было либо частичное решение, либо очень запутанно, либо и то, и другое.
И лишь благодаря единичным статьям, кусочкам информации с форумов и всяким комментариям удалось собрать пазл воедино. Я не утверждаю что мое решение полностью универсально, но очень удобное во многих случаях, хотя это вам решать.
Если у кого-либо возникнет желание улучшить мое решение этого вопроса и хватает знаний в этом направлении, то я буду рад, если вы сделаете какие-либо исправления или добавления к коду который лежит в открытом доступе на GitHub.
А теперь к делу, функции класса CargaDes:
- Отдача файла через браузер без показа его места хранения и с возможностью докачки;
- Загрузка файла на сервер через браузер с индикатором прогресса;
- Скачивание файлов с удаленного сервера на свой сервер с индикатором прогресса;
- Загрузка файлов со своего сервера на удаленный сервер с индикатором прогресса.
Для начала нужно скачать и подключить класс CargaDes:
1. Отдача файла через браузер без показа его места хранения с возможностью докачки и регулирования скорости
$realFilePath = dirname( __FILE__ ) . '/file.zip';//Полный путь к отдаваемому файлу
Этот метод очень похож на Drupal и иже с ним:
$CargaDes = new CargaDes; $client_d = new ClientD($realFilePath); //Не обязательные аргументы $client_d->erroff = false;//True отключает вывод ошибок $client_d->lang = 'ru'; $client_d->speed = 25;// это скорость отдачи в kB, если 0 то не используется;
Я добавил еще отдачу с помощью Apache, но должна быть включена директива XSendFile On
$client_d->apache = false;//True включает отдачу средствами Apache(работает он с докачкой или нет я пока так и не понял) //Выполнение команды $CargaDes->setOnStart(new Exe($client_d)); echo $CargaDes->Start();
Сразу после выполнения метода браузер выдаст окно для сохранения файла
2. Загрузка файла/ов на сервер через браузер с индикатором прогресса
$url_server = "http://ваш_сайт.com/upload.php";//Путь к принимающему скрипту на сервере. $multiple = 0;//True множественная загрузка файлов, False загрузка по одному файлу $CargaDes = new CargaDes; $client_u = new ClientU($url_server, $multiple); //Не обязательные параметры $client_u->param = 0;//Добавление данных в форму массивом в переменную param - сервер получит param=>array(ваш массив) $client_u->ajaxParam = '';//Добавление данных в форму - data.append("key", "val"); $client_u->returns = '';//Добавление действий после выполнения ajax $client_u->err_file_zero;//Текст ошибки о пустом файле $client_u->allowed_ext = 'gif,jpg,png,jpe,jpeg,zip,rar,exe,doc,pdf,swf,flv,avi,mp4,mp3';//Разрешенные расширения файлов $client_u->err_file_ext;//Текст ошибки об отсутствии расширения в списке $client_u->max_file_size = 0;//Ограничение на размер загружаемых файлов в байтах, по умолчанию отключено $client_u->err_file_size;//Текст ошибки о превышении установленного размера файла $client_u->max_file_count = 0;//Ограничение на количество загружаемых файлов, по умолчанию отключено $client_u->btn_input;//Имя кнопки выбора файлов $client_u->btn_enviar;//Имя кнопки отправки файлов $client_u->btn_del;//Имя кнопки удаления файлов из очереди $client_u->color;//Цвет линии прогресса загрузки $client_u->css;//Путь к файлу стилей $server->lang = 'ru'; //Получаем код скрипта $CargaDes->setOnStart(new Exe($client_u, 'p' )); echo $CargaDes->Start();
После выполнения метода появится кнопка для выбора файлов и кнопка для загрузки файлов. Индикатор будет появляться для каждого выбранного файла в отдельности.
3. Скачивание файлов с удаленного сервера на свой сервер
$CargaDes = new CargaDes; $server = new Server(); //Код индикатора $CargaDes->setOnStart(new Exe($server, 'p')); echo $CargaDes->Start(); $server->remoteUrl = 'http://сайт.com/test/file.zip'; $server->realFilePath = dirname( __FILE__ ) . '/file.zip'; //Не обязательные параметры $server->progress = 1;//Подключение/отключение индикатора $server->speed = 0;//Ограничение скорости $server->style;//Подключение стиля $server->color;//Цвет линии прогресса загрузки $server->erroff = false;//Отключение вывода ошибок $server->debug = false;//Отладка $server->login = 0;//Логин отправляемый на сервер, если есть авторизация типа .htaccess $server->pass = 0;//Пароль отправляемый на сервер, если есть авторизация типа .htaccess $server->lang = 'ru'; //Выполнение команды $CargaDes->setOnStart(new Exe($server, 's')); $r = $CargaDes->Start(); //Вывод ошибок if( $r['test'] == false )
4. Отдаем файл на удаленный сервер со своего сервера
$CargaDes = new CargaDes; $server = new Server(); //Код индикатора $CargaDes->setOnStart(new Exe($server, 'p')); echo $CargaDes->Start(); $server->remoteUrl = 'http://сайт.com/test/priem.php'; $server->realFilePath = dirname( __FILE__ ) . file.zip;//Можно использовать массив файлов //Не обязательные параметры $server->post = array( 'login' => 'test', 'pass' => '12345' );//Любые значения которые вы хотите передать на сервер $server->progress = 1;//Подключение/отключение индикатора $server->speed = 0;//Ограничение скорости $server->style;//Подключение стиля $server->color;//Цвет линии прогресса загрузки $server->erroff = false;//Отключение вывода ошибок $server->debug = false;//Отладка $server->login = 0;//Логин отправляемый на сервер, если есть авторизация типа .htaccess $server->pass = 0;//Пароль отправляемый на сервер, если есть авторизация типа .htaccess $server->lang = 'ru'; //Выполнение команды $CargaDes->setOnStart(new Exe($server, 'u')); $r = $CargaDes->Start(); //Вывод ошибок if( $r['test'] == false )
По итогу хочу сказать
Если этот класс поможет хотя бы одному человеку я буду очень рад этому. Как я уже говорил в начале буду рад конструктивной критике и дополнениям которые могут привести к улучшению класса. Ссылка на CargaDes.class.
Изменил в статье способы использования класса. И добавил описание того что изменилось в классе.
Вот закончил работу над ошибками, если это можно так назвать.
- Привел код к одному стилю с помощью PHPSTORM и старался соблюдать PSR;
- Убрал подчеркивания из названий функций;
- Полностью исключил jQuery;
- Убрал все статические методы;
- Сделал класс как пакет composer;
- cUrl портянку вынес в отдельный метод;
- Постарался соблюсти SRP;
- Сделал исключения и немного изменил вывод ошибок;
- Исправил тело конструкторов;
- Постарался улучшить конструкции if-else;
- Вынес js и html за пределы класса;
- Убрал закрывающий тег ?>;
- Добавил возможность перевода сообщений;
- Добавил папку с исполняющимися примерами.
- Перевод комментариев на английский(если это все одно никому не надо, то зачем тратить время);
- Не сменил названия функций на более понятные(мне не ясно какие, если английские, то смотреть пункт N1);
- Автотесты смотрел, но это оч. сложно сделать универсально т.к. у каждого свои сценарии действий, хотя может я ошибаюсь, то если вы считаете это нужным в классе который никому не нужен у вас есть возможность мне в этом помочь;
- Возможно еще что-то, но я уже не знаю что и у вас есть такая возможность мне об этом сказать.
В целом я постарался исправить, то о чем говорили в комментариях, если будут найдены еще какие либо недочеты или ошибки — пишите постараюсь исправить.
Благодарю за конструктивную критику webdevium и alutskevich, если бы мог, то плюсанул бы вам обязательно.
Так же благодарю всех остальных т.к. у меня появилось понимание моей главной ошибки и родилось пару идей.