PHP « Создание, дополнение массива. PHP

Существует файл

$data = file('bd.dat');

Данные в него должны записываться следующим образом:

1[:]4|5|6|7|456|2
4[:]56|7|3|23|5

Каждая строка - новый массив, состоящий из двух значений.
Первое значение - ID пользователя
Второе значение - ещё один массив.

Требуется следующее:

Пользователь нажимает ссылку, скрипт проверяет, если нет строчки, первое значение которой равно ID нажавшего пользователя, то он добавляет такую строчку, а через [:] записывает нужное число.
В случае если такая строчка существует, и уже есть какое-либо число
1[:]3 , то скрипт добавляет через "|" ещё одно число.

1[:]3|4|5|6|78 и так далее.


/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }

<?php
$m_id = '1'; // ID нажавшего на ссылку
$h_id = '3'; // число которое нужно записать

 $data = file('bd.dat');

   foreach($data as $line){
     list($gid, $arr_id) = explode('[:]', $line); // смотрим что у нас в уже записаных строчках
     
       if ($gid=$m_id) {

                             // нужная строка уже существует, работаем с ней
         } else {

            // нужная строка отсутствует, добавляем её

      }
   }
?>
 


Хотел бы получить поддержку:)

1 ответов


Inkvizitor, тебе повезло и я сегодня добрый :) Раз уж охота заниматься dbSM и нормальная БД или множество файлов не подходят - набросал скриптик, который выполняет требуемую задачу. Сразу о "граблях" - flock(), если верить документации не везде работает как надо (т.е. есть риск потерять данные при одновременной работе скрипта у нескольких пользователей). Плюс при ручном редактировании файла с данными редактор может наставить переносов строк так, как ему вздумается и вся структура данных пойдет лесом.

// я беру данные из $_GET - вы берите откуда нужно
$user = (int)$_GET['user']; // ID пользователя
$link = (int)$_GET['link']; // какое-то искомое число

$data = file('db.dat'); // получаем данные из нашего файла
$new_data = array(); // в этот массив будем собирать данные для перезаписи

foreach ($data as $line) {
    $arr = explode('[:]', $line);
    $search_user = $arr[0]; // получаем ID пользователя из записаных данных
    $links_arr = str_replace("\n", "", $arr[1]); // удаляем концевой символ переноса строки
    $links_arr   = explode('|', $links_arr); // остальные данные строки превращаем в массив
    $new_data[$search_user] = $links_arr; // составляем многомерный массив для поиска по ключам
}

// ищем, есть ли у нас запись с текущим пользователем:
if (array_key_exists($user, $new_data)) {
    // пользователь найден - проверяем есть-ли нужные данные
    if (array_search($link, $new_data[$user]) === false) {
        $new_data[$user][] = $link; // дописываем данные
    }
} else {
    // пользователя нет - создаем для него новый массив и записываем данные
    $new_data[$user][] = $link;    
}

// начинам запись данных в файл
$file = fopen("db.dat", "w+"); // открываем файл для записи, удаляем старые данные
flock($file, LOCK_EX); // блокируем от одновременной записи
foreach ($new_data as $key=>$data) {
    fwrite($file, $key."[:]".implode('|', $data)."\n"); // записываем строку
}
flock($file, LOCK_UN); // разблокировка файла
fclose($file); // закрываем файл

// смотрим что получилось
$data = file('db.dat');
echo "<h3>Содержимое файла:</h3>";
foreach ($data as $line) {
    echo $line."
"
;
}
 
Здесь - демонстрация для выявления косяков.
Надеюсь помог подняться еще на одну ступеньку профессионализма ;)

Вы ждете от PHP реакции человека - открыл файл, просмотрел, нашел строку, установил курсор, дописал значение, сохранил файл.
То, что вы хотите сделать - осуществить можно, но это будет метод "через задницу" - в любом случае придется перезаписывать весь файл. А если файл разрастется до 100 мегабайт? А самая главная засада - что вы будете делать, когда одновременно к файлу будет обращение нескольких пользователей.
Мой совет: сделайте на каждого пользователя свой файлик - db_1.dat, db_2.dat и т.д. Проверку - есть файл или нет делаем с помощью функции file_exists(). Если файл нашелся - дописываем нужное значение. Если не находит - создаем и записываем что нужно.

PS: что такое bd? Закос под db? :)


Ладно... Придется сжалиться... =), но писать код за вас не буду.
Если речь идет о небольшом количестве строк в файле. Один фиг - вы все строки в массив скинули.
Вы поймете:
1. Считываем файл и преобразовываем в многомерный массив вида:


$data = array(
    1 => array(4,5,6,7,4,56,2),
    4 => array(56,7,3,23,5)
);
 
в этом массиве первый ключ - id пользователя, а его значения - массив значений "чисел, которые нужно записать".
далее смотрите мэджик (только подсказки):
array_key_exists(); - поможет вам определить, есть ли в массиве опредленный ключ (читай, пользователь)
далее, если ключ есть - делаете array_push() значения, которое нужно записать (ну или $data[$key][] = $value;)
если нет - записываете ключ пользователя в массив данных, и к нему лепите массив со "значнием, которое нужо записать".
далее делаете обратное преобразование массива в массив ваших страшных строчек и запихиваете в вашу bazy dannyh

если вы не предполагаете редактирование данных вручную, то для вас удобнее будет хранить данные не в ваших малопригодных для обработки строчках, а использовать serialize() и unserialize() для хранения сразу массива, без ненужных преобразований туда-обратно.

А вообще, самое время для вас начать изучать базы данных. Задача подходящая.