Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: Подскажите, как лучше реализовать на PHP.
цитата
20/12/16 в 21:05
 Ailk
если точно проверяешь на файл, то юзать 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;
}

с простыми файлами примерно тож самое. Укороченная проверка на существование.

П.С.
Чот напало прям, захотелось буквы пописать ;[
цитата
20/12/16 в 22:22
 Lexikon
smail54.gif Благодарю за столь развернутый ответ.
Касаемо: file_get_contents и file_put_contents вместо них, в самом начале изучения пхп я использовал fopen и и же с ним, но вот до сих пор не особо осознаю разницу, кроме большего размера строк при написании.
Да и в последнее время практически не встречаю fopen и и же с ним, в чьих то кодах.
цитата
20/12/16 в 23:22
 Stek
Lexikon писал:
Да и в последнее время практически не встречаю fopen и и же с ним, в чьих то кодах.

Пригодится на больших файлах, на разборке csv файлов, когда необдходимо по содержимому передвигаться (например текстовая бд) и подобным. Иначе грузить содержимое в массив, потом из массива в массив парсить строки - сожрет кучу памяти.
цитата
20/12/16 в 23:33
 Ailk
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()
цитата
21/12/16 в 10:22
 Lexikon
Нужно было на локалке разобрать файл дампа в 250 Mb и уже при чтении вылазила ошибка о нехватке памяти. Теперь я понял почему у меня PHP выдавал ошибку о нехватке памяти. Тогда пришлось поднять до двух гиг на локалке, я тогда еще офигел.
цитата
29/12/16 в 21:21
 PhUllOF7h3m
Еще один совет, чтобы предотвратить содержимое файла остатся пустым на двух одновременных операций записи. Это случилось со мной с одним счетчиком посетителей который записывал в текст файле. Решение: Я добавил случайную задержку 20-80 мс перед fwrite(), и это устронило проблему, работает даже на сегодняшний день с гораздо более высоким числом посетителей.
цитата
03/01/17 в 13:30
 IgorZ
^^^

Это самый уебищный костыль facepalm.gif, кури http://php.net/manual/ru/function.flock.php
цитата
05/01/17 в 08:34
 rickdeckard
способ блокировки через создание директории вроде получше чем через создание файла и если нет доступа к семафорам 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 раз
цитата
05/01/17 в 08:40
 rickdeckard
Lexikon писал:
Вчера в качестве вечернего просмотра организовал себе просмотр видоса по sqlite, как я понял sqlite идет в PHP 5. У меня WAMP установлен, там тоже есть icon_smile.gif


на локале то что угодно можно установить. а на типовом хостинге - бывает что нету. хостер мотивирует это тем что не нужно - т.к. есть mysql.
все равно sqlite кривоватая в плане работы с паральельными запросам - при частой записи или если много клиентов - будет тупить и вылетать по таймаутам. она больше для однопользовательского режима.
цитата
05/01/17 в 09:01
 rickdeckard
Lexikon писал:
Благодарю!
Это да, но вот всё же, меня не покидает мысль, что как-то относительно просто ломают базы, х.з. может всё так изначально криво пишут, чтоб специально ломать. Знаю существуют большие базы с SQL запросами инъекций и ими хуярят различные форумы и сайты. Разве те, кто писал код сайта, не в курсе что да как? Может я что-то не понимаю, касаемо этого. icon_confused.gif
Вот уже наверное года 3-4 использую ПХП, но всё организовывал на файлах, наверное всё таки фобия smail101.gif


если все в одном файле хранить будет много тратится времени на чтение и преобразование в нужный вид.
если прямо без БД надо. используй тогда 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";
}
Стр. « первая   <  1, 2


Эта страница в полной версии