💀💀💀
С нами с 31.05.10
Сообщения: 4689
Рейтинг: 728
|
Добавлено: 20/12/16 в 21:05 |
если точно проверяешь на файл, то юзать is_file(). Бывают ситуации, когда путь к файлу например пишешь в базу, точнее не сам путь, а его кусок (до корневой директирии, или до директории с контентом). Например t/240x180/adc.jpg пишешь в базу, но когда будешь делать какие-то действия с ним, например наложить ватермарку или что-то другое, да просто проверить на существование. Будешь строить полный путь от корня.
Код: | $fullpath = '/var/www/blbla.../' . $filepath |
Где $filepath путь из базы. Вот. Но бывает случается херь, когда этот путь проебывается. Т.е. пусто в базе. А ты проверку делаешь по file_exists. И такая проверка вернет true, т.к. корень контент директории существует. Понятно да, что в логике ошибка закралась, и отловить ее будет проблемно. Вот тут пригодится is_file.
Короче, лично я по возможности стараюсь избегать file_exists используя конструкции типа
Код: |
if (!is_file($myFilepath) || !is_readable($myFilepath)) {
throw new Exception('Файл не существует или не доступен для чтения');
}
// тут делаем чо нада
|
Не всегда так конечно, но думаю общий посыл понятен.
Или вот с file_get_contents есть тоже нюансы.
Иногда нада скачать чота с сети без всяких курлов. Можно прям вот этой функцией. И если оно не смогло открыть удаленный файл генерируется варнинг, в курсе да? Но это можно проверить тоже, например
Код: |
$blob = @file_get_contents($myFilepath); // глушим варнинг
и проверяем открлось ли
if (false !== $blob) {
// отлично! работаем дальше
} else {
echo 'Ашипка скачивания';
return;
}
|
с простыми файлами примерно тож самое. Укороченная проверка на существование.
П.С.
Чот напало прям, захотелось буквы пописать ;[
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 20/12/16 в 22:22 |
Благодарю за столь развернутый ответ.
Касаемо: file_get_contents и file_put_contents вместо них, в самом начале изучения пхп я использовал fopen и и же с ним, но вот до сих пор не особо осознаю разницу, кроме большего размера строк при написании.
Да и в последнее время практически не встречаю fopen и и же с ним, в чьих то кодах.
|
|
|
|
www.phpdevs.com
С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105
|
Добавлено: 20/12/16 в 23:22 |
Lexikon писал: | Да и в последнее время практически не встречаю fopen и и же с ним, в чьих то кодах. |
Пригодится на больших файлах, на разборке csv файлов, когда необдходимо по содержимому передвигаться (например текстовая бд) и подобным. Иначе грузить содержимое в массив, потом из массива в массив парсить строки - сожрет кучу памяти.
|
|
Пишу на php/mysql/django за вменяемые деньги.
Обращаться в личку.
|
10
|
|
|
💀💀💀
С нами с 31.05.10
Сообщения: 4689
Рейтинг: 728
|
Добавлено: 20/12/16 в 23:33 |
fopen открывает поток (stream). Который необходимо потом закрыть. Но оно дает некоторые преимущества. Например можно считывать файл с определенной позиции, или писать в файл в поточном режиме, т.е. в цикле что-то делается, а результат дописывается в файл без повторного открытия.
file_get_contents хоть и проще в использовании но он например очень коварен в плане потребления памяти. Можно открыть какое-нибудь кино через него и оно все полезет в оперативу. Или, как чаще всего бывает, люди открываются всякие цсвшки по 100+ мегабайт. При записи происходит примерно тоже самое. Сначала набираешь кусок данных, которые могут весить довольно много, а потом только пишешь.
В общем для мелких файлов пойдет, а для чего покрупнее только fopen. Или использование всяих Spl для файлов. Оно хоть и объектно ориентированное, но оптимизировано хорошо и очень простое в использовании.
http://php.net/manual/ru/class.splfileobject.php
Например функция для чтения цсв файла: http://php.net/manual/ru/splfileobject.fgetcsv.php
Примеры там рабочие и гигабайтные файлы читаются очень быстро и не жрут память, в отличие от конструкций с file_get_contents + какой-нибудь str_getcsv()
|
|
|
|
Люблю то, что делаю!
С нами с 22.10.06
Сообщения: 5053
Рейтинг: 4418
|
Добавлено: 21/12/16 в 10:22 |
Нужно было на локалке разобрать файл дампа в 250 Mb и уже при чтении вылазила ошибка о нехватке памяти. Теперь я понял почему у меня PHP выдавал ошибку о нехватке памяти. Тогда пришлось поднять до двух гиг на локалке, я тогда еще офигел.
|
|
|
|
С нами с 27.12.16
Сообщения: 6
Рейтинг: -1
|
Добавлено: 29/12/16 в 21:21 |
Еще один совет, чтобы предотвратить содержимое файла остатся пустым на двух одновременных операций записи. Это случилось со мной с одним счетчиком посетителей который записывал в текст файле. Решение: Я добавил случайную задержку 20-80 мс перед fwrite(), и это устронило проблему, работает даже на сегодняшний день с гораздо более высоким числом посетителей.
|
|
|
|
С нами с 06.07.15
Сообщения: 110
Рейтинг: 171
|
Добавлено: 03/01/17 в 13:30 |
|
|
|
|
С нами с 09.08.12
Сообщения: 185
Рейтинг: 378
|
Добавлено: 05/01/17 в 08:34 |
способ блокировки через создание директории вроде получше чем через создание файла и если нет доступа к семафорам http://php.net/manual/ru/book.sem.php
Код: |
class Worker {
function __construct($name) {
$this->path = "tmp/"; // какойто путь для хранения статусов
$this->fstatus = $this->path . "/.job_" . $name;
}
function isWorking($timeout) {
// try lock, check is working
$result = !@mkdir($this->fstatus);
if ($result) {
// check timeout and reset working flag
if ($timeout > 0) {
if (filemtime($this->fstatus . "/.") < time() - $timeout) {
$result = false;
}
}
}
return $result;
}
function unlock() {
rmdir($this->fstatus);
}
function start($callback, $timeout = 0) {
if (!$this->isWorking($timeout)) {
$callback();
$this->unlock();
}
}
}
// пример использования
$worker = new Worker("import1");
$worker->start(function () {
// тут код обработчика
});
|
вот статья про описание способов
https://www.exakat.io/prevent-multiple-php-scripts-at-the-same-time/
Последний раз редактировалось: rickdeckard (07/01/17 в 19:00), всего редактировалось 1 раз
|
|
|
|
С нами с 09.08.12
Сообщения: 185
Рейтинг: 378
|
Добавлено: 05/01/17 в 08:40 |
Lexikon писал: | Вчера в качестве вечернего просмотра организовал себе просмотр видоса по sqlite, как я понял sqlite идет в PHP 5. У меня WAMP установлен, там тоже есть |
на локале то что угодно можно установить. а на типовом хостинге - бывает что нету. хостер мотивирует это тем что не нужно - т.к. есть mysql.
все равно sqlite кривоватая в плане работы с паральельными запросам - при частой записи или если много клиентов - будет тупить и вылетать по таймаутам. она больше для однопользовательского режима.
|
|
|
|
С нами с 09.08.12
Сообщения: 185
Рейтинг: 378
|
Добавлено: 05/01/17 в 09:01 |
Lexikon писал: | Благодарю!
Это да, но вот всё же, меня не покидает мысль, что как-то относительно просто ломают базы, х.з. может всё так изначально криво пишут, чтоб специально ломать. Знаю существуют большие базы с SQL запросами инъекций и ими хуярят различные форумы и сайты. Разве те, кто писал код сайта, не в курсе что да как? Может я что-то не понимаю, касаемо этого.
Вот уже наверное года 3-4 использую ПХП, но всё организовывал на файлах, наверное всё таки фобия |
если все в одном файле хранить будет много тратится времени на чтение и преобразование в нужный вид.
если прямо без БД надо. используй тогда php массивы и оптимальную структуру. будет nosql бд на файлах. а opcache закеширует данные для быстрого чтения.
запись
Код: |
function Write($fname, $data) {
file_put_contents(
$fname,
"<?php\nreturn " . var_export($data, true) . ";"
);
}
Write("products/124.php", [
"id" => "124",
"name" => "Product 1",
"price" => "100",
"currenncy" => "USD",
"category" => [1, 5],
]);
|
чтение
Код: |
$product = include "products/124.php";
|
еще создаешь там индексы для разных выборок
Код: | пример для категории /filter/category/1.php
<?php
return [
124 => 1, // product ids
125 => 1,
126 => 1,
];
|
или с сохранением части часто используемых данных чтобы не тратить время на подключение всего файла элемента.
Код: |
return [
124 => [
"id" => "124",
"name" => "Product 1",
],
125[
"id" => "124",
"name" => "Product 1",
],
126 => [
"id" => "124",
"name" => "Product 1",
],
];
|
пример прохода по выборке
Код: |
$categoryId = 1;
foreach (include "/filter/category/$categoryId.php" as $productId => $product) {
print_r($product);
// читаем все данные товара
$product = include "products/$productId.php";
} |
|
|
|
|