За последние 24 часа нас посетил 17461 программист и 1717 роботов. Сейчас ищут 1636 программистов ...

Проверка наличия данных в текстовом файле.

Тема в разделе "PHP для новичков", создана пользователем АлексейКоваль, 28 июл 2016.

  1. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    ну тут кто то писал что надо для большого количества юзеров надо на на смещениях в файле и т.д.. ну вот

    даже для реального с локальным файлом sqlite. да даже для теста sqlite.. а это фан
    --- Добавлено ---
    ненужно. и так все понятно же
     
    #51 Schrodinger, 1 авг 2016
    Последнее редактирование: 1 авг 2016
  2. pinokio

    pinokio Новичок

    С нами с:
    25 июл 2016
    Сообщения:
    160
    Симпатии:
    6
    не буду спорить не знаю как MySQL поведёт себя на миллионе пользователей, только вот кажется что даже не чухнет. Ну да ладно. когда буду данные такими кол-вами пробрасывать, подумаю над твоими словами, а пока можно не заморачиваться есть вещи по серьёзней в данный момент.
     
  3. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @rodent90 херню не неси. "прочитать файл и потом изучить этот поток на наличие подстроки" сравни с "прочитать файл, разбив его по строкам занести в массив, и потом найти в этом массиве значение равное строке". так-то первая операция быстрее, поэтому предложенный @pinokio вариант один из самых быстрых. Другое дело что скил у него ещё нулевой и он предложил рукожопое решение. На предложение поработать головой и напильником над своим кодом - пациент бросается на окружающих. Всё придет со временем. И у тебя. И у него.
     
    pinokio нравится это.
  4. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    и kvl не чухнет думаю
     
  5. pinokio

    pinokio Новичок

    С нами с:
    25 июл 2016
    Сообщения:
    160
    Симпатии:
    6
    @Schrodinger но база данных та удобней и привычней... Ну и думаю, защита у неё оч серьёзная :) Ну только конечно, если дырко в ней не оставить :) Но в php куда быстрее оставить дырки чем при стыковки к бд.... xD там всё элементарно pdo::quote и всё или pdo::prepare и всё и запрос, элементарный и он полностью рабочий) А главное что там много поточность запросов реализована, то есть он сам будет распределять запросы и выдачу овтетов, в общем это оч умная система на самом деле.
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Вы опять меняете условия задачи. Зачем?
    Самое быстрое решение - preg_match, только не такой, какой @Schrodinger предложил. Оригинальная задумка ТС всегда либо самая медленная, либо почти самая медленная.
     
  7. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    О да! Гении блин собрались. Смехота. Хотел дать более правильное решение, но вы не достойны его, пользуйтесь этим калом дальше, оно же самое быстрое :D
    Для меня тема умерла, как и вы! Удачи! Шпиюны :)
     
  8. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @rodent90 давай без обедулек и пустозвонства. Есть "более правильное решение" - выкладывай. Нет - не трынди.
     
  9. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    самый быстрый не индексированный поиск будет вида
    PHP:
    1. $data = file_get_contents('users.txt');
    2. $search = "{$login}{$pass}\n";
    3.  
    4. if ( (substr($data, 0, strlen($search)) === $search) || (strpos($data, "\n{$search}") !== false) ) {
    5.     echo "Valid\n";
    6. } else {
    7.     echo "Invalid\n";
    8. }
    при условии что добавляли как fwrite($fp, "{$login}{$pass}\n");
    ----
    индексированное же будет самое быстрое будет(скорей всего на чтение быстрее mysql и sqlite Будет, хотя я не сравнивал с ними) вида(только проверу ключа надо доделать т.к. могут быть совпадения)
    PHP:
    1. interface Cache {
    2.     public function Get($key, $callback = null);
    3.     public function Set($key, $value);
    4. }
    5.  
    6. class FileCache implements Cache {
    7.     private $pathDB;
    8.     private $handle;
    9.     public function __construct($pathDB = null) {
    10.         $pathDB = $pathDB === null ? __DIR__ . "/_cache" : $pathDB;
    11.         if ( !is_dir($dir = dirname($pathDB)) ) {
    12.             if ( !@mkdir($dir, 0777, 1) ) throw new \Excpection("File ~mkdir('$dir')~ error.");
    13.         }
    14.         if ( !$this->handle = fopen($pathDB, "c+") ) throw new \Excpection("File ~fopen('$pathDB')~ error.");
    15.         if ( $this->Stat('size') < 1 << 24 << 2 ) {
    16.             $this->Lock(function() {
    17.                 if ( $this->Stat('size') < 1 << 24 << 2 ) {
    18.                     ftruncate($this->handle, 1 << 24 << 2);
    19.                 }
    20.             });
    21.         }
    22.     }
    23.     public function Get($key, $callback = null) {
    24.         return $this->doKV($key)->Lock(function() use($callback) {
    25.             $offset = $this->ReadUInt32($this->offset);
    26.             while(1) {
    27.                 if ( !$offset ) {
    28.                     if ( $callback !== null ) {
    29.                         $this->Set( $data = $callback() );
    30.                         return $data;
    31.                     }
    32.                     return null;
    33.                 }
    34.                 if ( $this->ReadBuffer($offset, strlen($this->hash)) === $this->hash ) { break; }
    35.                
    36.                 $offset = $this->ReadUInt32($offset + strlen($this->hash));
    37.             }
    38.             $size = $this->ReadUInt32($offset + strlen($this->hash) + 4);
    39.             return $this->ReadBuffer($offset + strlen($this->hash) + 4 + 4, $size);
    40.            
    41.         }, LOCK_SH);
    42.     }
    43.     public function Set($key, $value) {
    44.         $this->doKV($key, $value)->Lock(function() {
    45.                 $prevOffset = $this->offset;
    46.                 $offset = $this->ReadUInt32($this->offset);
    47.                 while( $offset ) {
    48.                     if ( $this->ReadBuffer($offset, strlen($this->hash)) === $this->hash ) { break; }
    49.  
    50.                     $prevOffset = $offset;
    51.                     $offset = $this->ReadUInt32($offset + strlen($this->hash));
    52.                 }
    53.                 if ( $offset ) {
    54.                     $prevOffset = $this->ReadUInt32($offset + strlen($this->hash));
    55.                 }
    56.                
    57.                 $this->WriteUInt32(
    58.                     $this->offset,
    59.                     $this->WriteNew(
    60.                         $this->hash,
    61.                         $this->value,
    62.                         $this->ReadUInt32($this->offset)
    63.                     )
    64.                 );
    65.         }, LOCK_EX);
    66.         return $this;
    67.     }
    68.     private function WriteNew($hash, $value, $next) {
    69.         $offset = $this->Stat('size');
    70.         ftruncate($this->handle, $offset + strlen($hash) + 4 + 4 + strlen($value));
    71.         $this->WriteBuffer($offset, $hash);
    72.         $this->WriteUInt32($offset + strlen($hash) , $next);
    73.         $this->WriteUInt32($offset + strlen($hash) + 4, strlen($value));
    74.         $this->WriteBuffer($offset + strlen($hash) + 4 + 4, $value);
    75.         return $offset;
    76.     }
    77.     private function Lock($callback, $mode = LOCK_EX) {
    78.         if ( !flock($this->handle, $mode) ) throw new \Excpection("File ~flock()~ error.");
    79.             $result = $callback();
    80.         if ( !flock($this->handle, LOCK_UN) ) throw new \Excpection("File ~flock()~ error.");
    81.         return $result;
    82.     }
    83.     private function Stat($params = null) {
    84.         if ( $params === null ) {
    85.             return fstat($this->handle);
    86.         }
    87.         return fstat($this->handle)[$params];
    88.     }
    89.     private function ReadUInt32($offset) {
    90.         fseek($this->handle, $offset);
    91.         return unpack("l", fread($this->handle,4))[1];
    92.     }
    93.     private function ReadBuffer($offset, $size) {
    94.         fseek($this->handle, $offset);
    95.         return fread($this->handle, $size);
    96.     }
    97.     private function WriteUInt32($offset, $value) {
    98.         fseek($this->handle, $offset);
    99.         fwrite($this->handle, pack("l", $value));
    100.         return $this;
    101.     }
    102.     private function WriteBuffer($offset, $value) {
    103.         fseek($this->handle, $offset);
    104.         fwrite($this->handle, $value);
    105.         return $this;
    106.     }
    107.  
    108.  
    109.     private $hash;
    110.     private $offset;
    111.     private $value;
    112.     private function doKV($key, $value = null) {
    113.         $this->hash = md5($key);
    114.         $this->offset = hexdec(substr($this->hash,0,6)) << 2;
    115.         $this->hash = substr($this->hash, 6);
    116.         $this->value = $value;
    117.         return $this;
    118.     }
    119. }
    120.  
    121. $cache = new FileCache(__DIR__ . "/users-fc-data");
    122.  
    123. if ( $cache->Get($login) === $pass ) {
    124.         // some
    125. }
    ,а самое красивое квл( хотя скорость там будет не большой( изза общей локировки на запись что при чтении что при записи, и изза большой абстракции)
    --- Добавлено ---
    пс: все рассматриваемое в рамках файловых функций php
     
  10. faerkot

    faerkot Активный пользователь

    С нами с:
    24 май 2016
    Сообщения:
    18
    Симпатии:
    1
    Адрес:
    Иркутск
    Вообще использовать заглушки ошибок в виде "@" плохой тон. Лично я пишу код, чтобы не было даже e-notice.
     
    denis01 нравится это.
  11. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    как придраться к орфографии…
     
  12. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @Schrodinger твой код дает фолс-позитивы. Тем не менее я его прогнал через свой бенч этой темы. Медленнее, чем preg_match. На больших объемах, конечно, быстрее, но это можно не учитывать, в виду кривизны.
     
  13. faerkot

    faerkot Активный пользователь

    С нами с:
    24 май 2016
    Сообщения:
    18
    Симпатии:
    1
    Адрес:
    Иркутск
    Из-за этой "орфографии" может поломаться весь код :) Допустим, чтобы вы сделали заглушки, а потом через пол года полезли в код и где-то в далеком начале скриптов что-то изменили. Конечно же заглушенные ошибки не отобразятся и вы посчитаете скрипт рабочим, хотя на самом деле скрипт уже будет либо с багами, либо в "боевых" условиях не рабочий.
    И если не ошибаюсь, то @ кушает дополнительные ресурсы сервера. Немного, но кушает. И так с каждого пользователя.
     
  14. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    что это такое?
    где кривизна в коде?( я про неиднексированный способ )
    помой му с задачей проверки существования набора символов(кроме \n) вполне справляется
     
  15. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ложные срабатывания. В данном случае ложно совпадение со строкой, с которой совпадения быть не должно. Учи матчасть.

    Правильно это слово пишется "по-моему". Или всё же ты реально предлагаешь помыть какую-то му? Ты перед тем как публиковать - тестируй. По опыту бенчмарка прошлой темы (с айпишниками) - сначала "решение" надо тестировать на корректность алгоритма а потом уже время замерять. Не имеет смысл тестировать алгоритм, который неверно работает с данными. Так что я твоё "решение" лишь скопипастил, оно не прошло тест, ну и как следствие - дало бессмысленные результаты бенчмарка.

    Да, прошу меня малость извинить. Конечно же, самым быстрым является решение со strpos. Но не те, которые предложили @pinokio и @Schrodinger. У первого вообще не тестировалось, так как фолс-позитивы видно даже при чтении сурса. А второй написал было сложную конструкцию, но выстрелил ею себе в ногу. На втором месте - preg_match, но не в версии @Schrodinger.
     
  16. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    я ошибок не вижу. если вы про это {$login}{$pass}
    то изначально как я у автора скоприровал $ud=$name.$pass; так и пошло. к тестам скорости это врятли относится
     
  17. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @Schrodinger а как ты ошибки ищешь? ЧИТАЕШЬ ИСХОДНЫЙ КОД ШТОЛЕ?
     
  18. Schrodinger

    Schrodinger Новичок

    С нами с:
    8 июн 2016
    Сообщения:
    40
    Симпатии:
    5
    PHP:
    1. function _check($login, $pass) {
    2.     $data = @file_get_contents('users222.txt');
    3.     $search = "$login\r$pass\n";
    4.     return ( (substr($data, 0, strlen($search)) === $search) || (strpos($data, "\n{$search}") !== false) );
    5. }
    6. function _set($login, $pass) {
    7.     $search = "$login\r$pass\n";
    8.     $fp=fopen('users222.txt', "a+"); fwrite($fp, $search); fclose($fp);
    9. }
    так лучше?
     
  19. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Не, так не лучше. Ты опять меняешь условия задачи и формат хранения данных. Не надо.
     
  20. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @Schrodinger сорян! В процессе копипаста потерял одну важную строку. С ней твой алгоритм вполне не дает фолс-позитивов. И даже выигрывает трофеи в моём бенчмарке.
     
    mahmuzar нравится это.