За последние 24 часа нас посетили 60800 программистов и 1771 робот. Сейчас ищут 892 программиста ...

Поиск ключа по ini файлу

Тема в разделе "Прочие вопросы по PHP", создана пользователем Brooks, 13 мар 2015.

  1. Brooks

    Brooks Новичок

    С нами с:
    13 мар 2015
    Сообщения:
    4
    Симпатии:
    0
    На сервере есть файл 'ip.txt', записи имеют примерно такой вид:

    11.11.11.11 = 3
    44.44.44.44 = 1
    88.88.88.88 = 1

    Как сделать, чтобы искался ip из переменной $ip и если он найден прибавлять после знака = +1, то есть если

    $ip = 44.44.44.44, то 44.44.44.44 = 2 (было 44.44.44.44 = 1)
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.818
    Симпатии:
    1.333
    Адрес:
    Лень
  3. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Код (Text):
    1.  
    2. <?php
    3.  
    4. /*
    5.   //открываем файл, и сохраним его содержимое в переменной
    6.   //сначала разбив на ip и его значение, которое идет после
    7.   // получим такого вида массив:
    8.  * array(3) {
    9.   [0]=>
    10.   array(2) {
    11.   [0]=>
    12.   string(12) "11.11.11.11 "
    13.   [1]=>
    14.   string(3) "3
    15.   "
    16.   }
    17.   [1]=>
    18.   array(2) {
    19.   [0]=>
    20.   string(12) "44.44.44.44 "
    21.   [1]=>
    22.   string(2) "1
    23.   "
    24.   }
    25.   [2]=>
    26.   array(2) {
    27.   [0]=>
    28.   string(12) "88.88.88.88 "
    29.   [1]=>
    30.   string(3) "1
    31.   "
    32.   }
    33.   }
    34.  *
    35.  * пример чтения файла взять из документации php.net с последюющим незначительными
    36.  * правками
    37.  * http://php.ru/manual/function.fgets.html
    38.  */
    39. $handle = @fopen("ip.txt", "r"); //получим файловый указатель.
    40. $i = 0;
    41. if (flock($handle, LOCK_EX)) { // выполняем эксклюзивную блокировку
    42.     ftruncate($handle, 0); // очищаем файл
    43.     if ($handle) {
    44.         while (($buffer = fgets($handle)) !== false) {
    45.  
    46.             $ip_data[] = explode("=", $buffer);
    47.             $i++;
    48.         }
    49.         if (!feof($handle)) {
    50.             echo "Error: unexpected fgets() fail\n";
    51.         }
    52.  
    53.         fflush($handle);        // очищаем вывод перед отменой блокировки
    54.         flock($handle, LOCK_UN); // отпираем файл
    55.         fclose($handle);//закрываем открыйтый дескриптор файла
    56.     }
    57. }
    58.  
    59. //отладка
    60. echo "<pre>";
    61. var_dump($ip_data);
    62. echo "</pre>";
    63.  
    64. /*
    65.  * теперь имея массив с данными из файла, мы  можем сравнивать IP-адреса с
    66.  * IP-адресом из переменной $ip
    67.  *
    68.  *
    69.  */
    70. //пусть $ip = "88.88.88.88";
    71. $ip = "88.88.88.88";
    72. $to_write;
    73. for ($j = 0; $j < count($ip_data); $j++) {
    74.     if (strcmp($ip, trim($ip_data[$j][0])) === 0) {
    75.         echo $new_value = trim($ip_data[$j][1]) + 1;
    76.         $to_write .=$ip_data[$j][0] . "=" . $new_value . "\r\n";
    77.     } else {
    78.         $to_write .=$ip_data[$j][0] . "=" . trim($ip_data[$j][1]) . "\r\n";
    79.     }
    80. }
    81.  
    82. //отладка
    83. echo "<pre>";
    84. var_dump($to_write);
    85. echo "</pre>";
    86.  
    87. /*
    88.  * Теперь, сохраним изменения в файле
    89.  *
    90.  * Этот код тоже взять из документации
    91.  * с незначительными изменениями.
    92.  * http://php.ru/manual/function.fwrite.html
    93.  */
    94. $filename = "ip.txt";
    95. // Вначале давайте убедимся, что файл существует и доступен для записи.
    96. if (is_writable($filename)) {
    97.  
    98.  
    99.     //Открывает файл только для записи; помещает указатель в начало файла и
    100.     //обрезает файл до нулевой длины. Если файл не существует - пробует его создать.
    101.     if (!$handle = fopen($filename, 'w')) {
    102.         echo "Не могу открыть файл ($filename)";
    103.         exit;
    104.     }
    105.     if (flock($handle, LOCK_EX)) { // выполняем эксклюзивную блокировку
    106.         ftruncate($handle, 0); // очищаем файл
    107.         // Записываем $to_write в наш открытый файл.
    108.         if (fwrite($handle, $to_write) === FALSE) {
    109.             echo "Не могу произвести запись в файл ($filename)";
    110.             exit;
    111.         }
    112.  
    113.         echo "Ура! Записали ($somecontent) в файл ($filename)";
    114.         fflush($handle);        // очищаем вывод перед отменой блокировки
    115.         flock($handle, LOCK_UN); // отпираем файл
    116.         fclose($handle);//закрываем открыйтый дескриптор файла
    117.     } else {
    118.         echo "Файл $filename недоступен для записи";
    119.     }
    120. }
    121. unset($handle);
     
  4. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    mahmuzar, состояние гонки?
     
  5. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    гонки?
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.818
    Симпатии:
    1.333
    Адрес:
    Лень
    $to_write; обделили?
     
  7. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    если ты про то что denis01 уже проделал такое, и я выложил, то выложил потому что уже написал.
    Вариант denis01 мне больше нравится.

    Добавлено спустя 2 минуты 1 секунду:
    ??
     
  8. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ты только что продемонстрировал какой ты специалист. никакой. если не знаком с термином можно втихую пойти погуглить.
    в задании не сказано что обращение к скрипту будет исключительно одно монопольное. следовательно не исключена вероятность одновременного обращения к обрабатываемому файлу. и как следствие скрипты находясь в состоянии гонки приведут к потере целостности данных - стату запишет тот скрипт который записывает последним. переписав потуги того который начался первым. я как бы не стал публично критиковать то что ты называешь кодом и просто сразу указал на ту проблему которую ты вообще не учел. состояние гонки. учи матчасть.
     
  9. Brooks

    Brooks Новичок

    С нами с:
    13 мар 2015
    Сообщения:
    4
    Симпатии:
    0
    Спасибо! Но мне больше понравился первый вариант, все работает, но числа не прибавляются, прибавляется только 1, а потом 2, 3 и.д - нет

    Код (Text):
    1. <?php
    2. $usnum = array();
    3. $num = file('settings.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    4. $out = '';
    5.  
    6. foreach (file('settings.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $key => $value) {
    7.     $x = explode('=', $value);
    8.     if($x) {
    9.         if(in_array($x[0], $num))
    10.         {
    11.             $x[1] = trim($x[1]) + 1;
    12.         }
    13.  
    14.         $usnum[$x[0]] = $x[1];
    15.         $out = $out.PHP_EOL.$x[0].'='.$x[1];
    16.     }
    17. }
    18.  
    19. file_put_contents('settings.txt', ltrim($out));
    20. ?>
     
  10. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    а почему допустим не сделать preg_replace_callback по всему тексту файла?
     
  11. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    не додумался, и спасибо, уже есть чт-то новое.. состояние гонки.
    я только за критику

    О блокировке я подумал , но куда-то улетучилась эта мысль по ходу копирования и вставки кода.
    Отредактировал свое первое сообщение.

    Добавлено спустя 3 минуты 24 секунды:
    это еще какой -то термин*?
     
  12. Ganzal

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

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

    Добавлено спустя 12 минут 27 секунд:
    перед прогулкой решил таки бенчмарк своей идеи и твоего кода устроить. 1000 проходов по фиксированно произвольному массиву в 120 "айпишников". файл данных на рамдрайве дабы йопы не сильно влияли.
    Код (Text):
    1. ru_php_forum_52305_GANZAL_01 : 6.430408
    2. ru_php_forum_52305_GANZAL_02 : 8.444232
    3. ru_php_forum_52305_mahmuzar_01 : 15.105814
    4. ru_php_forum_52305_mahmuzar_02 : 16.030584
    корректность твоего алгоритма не отлаживал. допустим он дает такие же корректные данные как и мой.
     
  13. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    вижу разница огромная
    хотел бы увидеть твой вариант

    я еще раз отредактировал свой вариант.
    Код (Text):
    1. //откроем файл для чтения и записи
    2. $fp = fopen("ip.txt", 'r+') or die("не удалось прочесть файл");
    3. //пусть $ip = "132.154.226.1";
    4. $ip = "132.154.226.1";
    5.  
    6. if (flock($fp, LOCK_EX)) { // выполняем эксклюзивную блокировку
    7.     while (($line = fgets($fp)) !== false) {
    8.         //$line - это прочтенная строка из файла
    9.         $ip_from_file = trim(strstr($line, '=', TRUE));//получим из строки ip
    10.         $ip_value = trim(substr($line, strrpos($line, '=') + 1));//получим значение ip
    11.  
    12.         if (strcmp($ip, $ip_from_file) === 0) {
    13.             $to_write .= $ip_from_file . "=" . sprintf($ip_value + 1) . "\r\n";
    14.         } else {
    15.             $to_write .=$ip_from_file . "=" . $ip_value . "\r\n";
    16.         }
    17.     }
    18.    
    19.     fseek($fp, 0);//переместим указатель в начало файла
    20.     ftruncate($fp, 0); // очищаем файл
    21.     //
    22.     // Записываем $to_write в наш открытый файл.
    23.     if (fwrite($fp, $to_write) === FALSE) {
    24.         echo "Не могу произвести запись в файл";
    25.         exit;
    26.     }
    27.    
    28.     fflush($fp);        // очищаем вывод перед отменой блокировки
    29.     fclose($fp); //закрываем открытый дескриптор файла
    30. }
    что насчет варианта denis01?
     
  14. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ты делаешь очень много действий бесполезных.
    ща твой кодец к себе в бенчмарк портирую да расскажу в чем ты не прав.

    Добавлено спустя 22 минуты 13 секунд:
    такой ты жоский))))

    смари. вот этот вот код который прям перед этим моим постом:
    Код (Text):
    1. ru_php_forum_52305_mahmuzar_03 : 8.850873
    с улыбкой удаляю 67 МЕГАБАЙТ ВОРНИНГОВ, ставлю сабаки перед переменными которые ты инициализируешь где-то во сне и запускаю повторно
    Код (Text):
    1. ru_php_forum_52305_mahmuzar_03 : 6.473487
    отличный результат. но абсолютно бесполезный потому что результат накидывания тестового набора айпишников не соответствует эталонному.

    Парам парам пам, фшшшшшшыыыть, ПАМ!
     
  15. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Тут как бы с точки производительности в глаза бросается 2 момента
    1. Дать поиск нужного ip с строкой нужно до расчленения строки на ip и значение. Тем самым убираем несколько лишних действий.
    2. Зачем делать какие то конкатенации когда есть нужная не измененная целая строка в $line?
     
  16. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    smitt, предлагай алгоритм)
     
  17. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Да ну, влом как то, можно еще строчку
    Код (PHP):
    1. $ip_value = trim(substr($line, strrpos($line, '=') + 1));//получим значение ip    
    с 3 функций сократить до 1
    Код (PHP):
    1. $value = explode(" = ", $line)[1];
    Мы же знаем что перед и после равно есть пробел, формат записи строки не должен меняться.
    Искомый ip имеется нам не надо создавать переменную для ее хранения.
     
  18. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    при обнаружении $ip можно далее не продолжать конкатенацию.

    Как же так, у меня ворнинга не было нигде.
    А какие были правки?) вроде все инициализировано
     
  19. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    ??? Твой код работает несколько иначе, или мне кажется? Я его не запускал, на глаз определяю:)
     
  20. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    работает как написан)
    Я имею в виду подумывал о том же, что ты говоришь. Можно было бы не продолжать конкатенацию, после того, как находится совпадение ip
     
  21. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    if (strcmp($ip, $ip_from_file) === 0) {
    @$to_write .= $ip_from_file . "=" . sprintf($ip_value + 1) . "\r\n";
    } else {
    @$to_write .=$ip_from_file . "=" . $ip_value . "\r\n";
    }

    вот такая была правка. потому что ты конкатенируешь но переменная не объявлена. высыпается ворнинг. а поскольку у меня это всё дело обернуто в метод который вызывается для каждого из 123 (да, теперь 123) айпишников из пакета и тысячу прогонов то получаем 123000 (сто двадцать три тысячи) ворнингов за тест. фу-фу-фу.
     
  22. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Забавно. А почему у меня нету воргнинга?

    Добавлено спустя 3 минуты 47 секунд:
    Код (Text):
    1. Notice: Undefined variable: to_write in C:\server\www\tester\call.php on line 25
    error_reporting = E_ALL & ~E_NOTICE
    предупреждения у меня были в игноре, поэтому не высвечивались))

    Добавлено спустя 5 минут 57 секунд:
    когда ты сказал про ворниг, я реально подумал про ворнинг.
    учту, что и это дело сказывается на производительности.

    Спасибо, было позновательно.
    а что насчет этого подхода?

    Добавлено спустя 14 минут 44 секунды:
    эту строку можно сменить этой
    Код (Text):
    1. $to_write .=$line;
     
  23. INETCHIK

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

    С нами с:
    13 фев 2014
    Сообщения:
    35
    Симпатии:
    0
  24. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ща у меня самый толстый тест пролетит и этот код попробую. но уже видно что идет двойное чтение файла.
     
  25. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Добавлено спустя 3 минуты 43 секунды:
    Вызывают некоторые сомнения строчка
    Код (PHP):
    но лень есть лень, запускать твой код не буду поэтому это останется моей догадкой:)