Мы имеем на входе 3 переменных, 2-передаются методом POST и одна юзерагентом: Код:
$ip = $_SERVER['REMOTE_ADDR'];
$mac = $_POST[pMAC];
$guid = $_POST[pGUID];
Нужно сделать, что бы скрипт писал в файл эти данные в формате |$ip|$mac|$guid|, каждый запрос с новой строки. НО. Должна существовать проверка... Если строка с содержимым переменной $guid уже существует, то мы просто переписываем целиком всю строку... Если в файле вообще нет такой строки, то мы просто её туда дописываем. И никак я не могу сообразить как это сделать. Пока только написал, что бы скрипт читал данные из файла, разбивал их на массив и искал строку с $guid и в случае её обнаружения менял на новую...
$ip = $_SERVER['REMOTE_ADDR'];
$mac = $_POST[pMAC];
$guid = $_POST[pGUID];
$row = 1;
$handle = fopen ("test.dat","r+");
while ($data = fgetcsv ($handle, 1000, ","))
{
$num = count ($data);
$row++;
for ($c=0; $c< $num; $c++)
{
if($data[2]==$guid){
$arr[$row][0] = $ip;
$arr[$row][1] = $mac;
$arr[$row][2] = $guid;
}
else{
$arr[$row][$c] = $data[$c];
}
echo $arr[$row][$c]."<br>\n";
}
}
fclose ($handle);
Очень надеюсь на вашу помощь, что бы решить эту, казалось бы простую, задачку.
Спустя 3 часа, 24 минуты, 14 секунд (19.08.2010 - 14:02) Димитер написал(а):
|-'это, как я понял, переносы строки, то есть если $ip="первый запрос", $mac="первый запрос", $guid="третий запрос", то файл должен выглядеть так:
первый запрос
второй запрос
третий запрос
?
$handle = fopen ("test.dat","r+");//открываем файл
ftruncate($handle,0);//cносим все содержимое файла
$filedata=$id."\r\n".$mac."\r\n".$quid;//cтроим строку, в которой содержится новое содержимое файла
fwrite($handle,$filedata,50);//пишем строку в файл
fclose($handle);//закрываем файл
Спустя 9 минут, 40 секунд (19.08.2010 - 14:11) novell написал(а):
Я же написал ! Что храниться должны в формате |$ip|$mac|$guid|, каждый новый запрос от клиента пишется на новую строку... Тоесть
|$ip|$mac|$guid|
|$ip|$mac|$guid|
|$ip|$mac|$guid|
|$ip|$mac|$guid|
И так далее !!! Но должна существовать проверка описанная выше !
|$ip|$mac|$guid|
|$ip|$mac|$guid|
|$ip|$mac|$guid|
|$ip|$mac|$guid|
И так далее !!! Но должна существовать проверка описанная выше !
Спустя 1 час, 12 минут, 44 секунды (19.08.2010 - 15:24) sergeiss написал(а):
Цитата (novell @ 19.08.2010 - 11:37) |
Нужно сделать, что бы скрипт писал в файл эти данные в формате |$ip|$mac|$guid|, каждый запрос с новой строки. НО. Должна существовать проверка... Если строка с содержимым переменной $guid уже существует, то мы просто переписываем целиком всю строку... |
Эта задача - для БД, а не для файлов. Научись работать с БД и не парь мозХ ни себе, ни другим

Спустя 5 минут, 49 секунд (19.08.2010 - 15:30) Димитер написал(а):
Тогда открывай файл модом 'a+', формируй строку с символами | и дописывай все это в файл без его сноса. Это дописывание. Если же проверка дает отрицательный результат, сносишь файл и все равно дописываешь.
Сама проверка: проверяешь длину строки файла, она должна быть меньше без третьей переменной.
Сама проверка: проверяешь длину строки файла, она должна быть меньше без третьей переменной.
Спустя 8 минут, 41 секунда (19.08.2010 - 15:38) novell написал(а):
sergeiss База данных не нужна. Нужны именно файлы. Я сам понимаю, что с базой было бы проще и быстрее всё это дело написать. Но файлы и только файлы
Нет возможности использовать базу...
Димитер А как я по Вашему буду заменять строку ?

Димитер А как я по Вашему буду заменять строку ?
Спустя 2 минуты (19.08.2010 - 15:40) Basili4 написал(а):
sergeiss
novell рекарнация Kafe до того как он сдал экзамен по БД.
Тот тоже на отрез отказывался от баз.
novell рекарнация Kafe до того как он сдал экзамен по БД.
Тот тоже на отрез отказывался от баз.
Спустя 2 минуты, 1 секунда (19.08.2010 - 15:42) Димитер написал(а):
Я отредактил, там все написано.
Спустя 2 минуты, 29 секунд (19.08.2010 - 15:45) novell написал(а):
Ты не понимаешь по всей видимости !!! Допусти... Существует в файле строка
|1|2|3|
На вход поступают переменные
|10|2|3|
В таком случае в файле нужно строку |1|2|3| заменить на |10|2|3|
|1|2|3|
На вход поступают переменные
|10|2|3|
В таком случае в файле нужно строку |1|2|3| заменить на |10|2|3|
Спустя 7 минут, 56 секунд (19.08.2010 - 15:53) Димитер написал(а):
Тогда построй все остальные строки без |(если совсем надо, можешь заменить слешами или другими символами), и проверяй каждый элемент массива файла на |. Это осуществление проверки. Если нету, то дописываешь. Если есть, то элемент массива, в котором есть |, заменяешь на новую строку. склеиваешь implode-ом все элементы в новую строку, сносишь файл и дописываешь ее.
Спустя 5 минут, 58 секунд (19.08.2010 - 15:59) sergeiss написал(а):
Цитата (novell @ 19.08.2010 - 16:38) |
База данных не нужна. Нужны именно файлы. |
Звучит примерно как "Нет, дядя Вова... Скрипач не нужен!"

Почему именно файлы, почему не БД?
Второй вариант - делай свою БД, т.е. файлы с данными и файлы с индексами. Если, конечно, делать больше нечего в жизни.
Спустя 5 минут, 27 секунд (19.08.2010 - 16:04) novell написал(а):
sergeiss
Какая вообще задача стоит. Я пишу что-то типа таблици ARP, откуда я буду забирать по IP клиента 2 параметра мак сетевухи и гуид матери. Пишу это я для чата, который работает на чат демоне и не использует базы данных ! MySQL на серваке есть, но он переодически отваливается, а если я не получу мак и гуид пользюка, то в чат он просто не войдёт. Это всё делается для эффективности бана чата !
Какая вообще задача стоит. Я пишу что-то типа таблици ARP, откуда я буду забирать по IP клиента 2 параметра мак сетевухи и гуид матери. Пишу это я для чата, который работает на чат демоне и не использует базы данных ! MySQL на серваке есть, но он переодически отваливается, а если я не получу мак и гуид пользюка, то в чат он просто не войдёт. Это всё делается для эффективности бана чата !
Спустя 10 минут, 27 секунд (19.08.2010 - 16:15) sergeiss написал(а):
А почему именно MySQL? Есть еще, например, SQLite. Там вся БД лежит в одном файле, и таблицы, и индексы.
Но это по-любому БД, хоть и проще, чем MySQL. Для описанной тобой цели более чем достаточно будет.
Узнай, поддерживает ли твой хост эту БД. Обычно, кстати, при ограничении количества баз данных хостеры считают MySQL, PostgerSQL и другие серьёзные БД, но количество SQLite не учитывается.
PS. А самое главное, ты не будешь "парить свой мозг" всякой фигней, а сможешь сосредоточиться на функционале.
Но это по-любому БД, хоть и проще, чем MySQL. Для описанной тобой цели более чем достаточно будет.
Узнай, поддерживает ли твой хост эту БД. Обычно, кстати, при ограничении количества баз данных хостеры считают MySQL, PostgerSQL и другие серьёзные БД, но количество SQLite не учитывается.
PS. А самое главное, ты не будешь "парить свой мозг" всякой фигней, а сможешь сосредоточиться на функционале.
Спустя 5 минут, 11 секунд (19.08.2010 - 16:20) novell написал(а):
Я понимаю твоё рвение посадить меня на БД. Но я ещё раз повторяю, что никакие базы я использовать не смогу... И я знаю, что на php мою задачу написать реально, но мне не хватает знаний.... Так что давайте отбросим в сторону базы данных и если Вы мне реально можете помочь с написанием этого скрипта, то я буду очень признателен...
Спустя 31 минута, 9 секунд (19.08.2010 - 16:51) sergeiss написал(а):
Цитата (novell @ 19.08.2010 - 17:20) |
Я понимаю твоё рвение посадить меня на БД |
Анекдот вспоминается: "папа, ты сейчас с кем разговаривал?"



Если тебе "кровь из носу" надо сделать такую хрень на файлах и ты категорически не хочешь потратить 1,5 часа на изучение БД... То тогда не работай с разделителями, и используй под каждую "колонку" определенное количество знаков. Тогда под одну запись (строку) у тебя тоже будет отведено известное заранее количество знаков, плюс добавь несколько служебных полей. Тогда ты сможешь легко перейти к любой записи, не загружая весь файл (особенно, если сделаешь индексы). Тогда ты сможешь заменить данные в любой записи, не нарушая структуру файла. Тогда ты сможешь сделать пометки для любой записи о том, что она удалена и с ней не надо работать.
Но в итоге, после длительных мучений, ты сделаешь свою личную пародию на БД. Оно тебе надо? Занимайся. Алгоритм (в кратком виде) описан в предыдущем абзаце.
Спустя 5 часов, 3 минуты, 18 секунд (19.08.2010 - 21:54) Nord написал(а):
Вариант на скорую руку:
Вообще, правильно говорят, что такие вещи надо делать в БД,
Но если хочется сделать имено с файлами, то лучше поменять структуру файла: как минимум, нужно отсортировать строки по guid и сделать строки фиксированной длины(данные же, как я понял, на практике будут фиксированного размера), чтобы не пришлось каждый раз переписывать файл, если длина строки изменится
$lines = file('test.dat');
$count = count($lines);
for ($i = 0; $i < $count; $i++){
$vars = explode('|', substr($lines[$i], 1));
// Ищем guid
if ($vars[2] == $guid){
$lines[$i] = "|$ip|$mac|$guid|";
break;
}
}
if ($i == $count){
// guid'а еще нет, добавляем
$handle = fopen('test.dat', 'a');
fwrite($handle, "\n|$ip|$mac|$guid|");
} else {
// строки изменены, переписываем файл
$handle = fopen('test.dat', 'w');
fwrite($handle, implode('', $linea));
}
fclose($handle);
Вообще, правильно говорят, что такие вещи надо делать в БД,
Но если хочется сделать имено с файлами, то лучше поменять структуру файла: как минимум, нужно отсортировать строки по guid и сделать строки фиксированной длины(данные же, как я понял, на практике будут фиксированного размера), чтобы не пришлось каждый раз переписывать файл, если длина строки изменится
Спустя 10 часов, 28 минут, 9 секунд (20.08.2010 - 08:23) novell написал(а):
Длинна строки будет разной, так как IP меняется...
Огромное спасибо. Всё работает... Только при записи новой строки скрипт пишет через строку новые данные, но это не беда.... И у Вас опечатка была )))
Огромное спасибо. Всё работает... Только при записи новой строки скрипт пишет через строку новые данные, но это не беда.... И у Вас опечатка была )))
fwrite($handle, implode('', $linea));
Спустя 12 минут, 16 секунд (20.08.2010 - 08:35) linker написал(а):
Зря вот так
$vars = explode('|', substr($lines[$i], 1));лишняя операция в цикле ни к чему, достаточно
$vars = explode('|', $lines[$i]);Вот только, какого вида этот guid? Можно и так
if ($vars[3] == $guid)
{
...
}
if (!strcmp($vars[3], $guid))И еще вот так лучше
{
...
}
fwrite($handle, "|$ip|$mac|$guid|\n");
Спустя 7 минут, 39 секунд (20.08.2010 - 08:42) novell написал(а):
linker
Ещё как к чему, если сделать как сказали Вы, то найденая страка не меняется на новую, а тупо пишется ещё раз
Ещё как к чему, если сделать как сказали Вы, то найденая страка не меняется на новую, а тупо пишется ещё раз
Спустя 2 минуты, 29 секунд (20.08.2010 - 08:45) linker написал(а):
novell
Это к какому участку моего поста относится?
Это к какому участку моего поста относится?
Спустя 1 минута, 58 секунд (20.08.2010 - 08:47) novell написал(а):
Цитата (linker @ 20.08.2010 - 05:35) |
Зря вот так$vars = explode('|', substr($lines[$i], 1));лишняя операция в цикле ни к чему, достаточно $vars = explode('|', $lines[$i]);Вот только, какого вида этот guid? Можно и так if (!strcmp($vars[3], $guid)) |
ВОт
Спустя 3 минуты, 10 секунд (20.08.2010 - 08:50) linker написал(а):
Заметь, $vars[3], а не $vars[2] - это важно.
Использование strcmp() возможно при guid'ах аля md5.
Использование strcmp() возможно при guid'ах аля md5.
Спустя 1 минута, 37 секунд (20.08.2010 - 08:52) novell написал(а):
По поводу $vars[2] я и сам понял ! Исчисления всё же с 0 идут
а гуид имеет вид MS1C7CBA3G05272
а гуид имеет вид MS1C7CBA3G05272
Спустя 2 минуты, 6 секунд (20.08.2010 - 08:54) novell написал(а):
Теперь дело за малым )))) Нужно написать ф-цию, в которую будет передаваться IP, а возвращаться MAC и GUID )))))
Спустя 28 минут, 38 секунд (20.08.2010 - 09:22) novell написал(а):
Только почему-то, когда заменяется найденая строка на новую, то нет перехода на новую строку и к новой добавляется нижняя строка.. и получается что-то вроде
|$ip|$mac|$guid||$ip2|$mac2|$guid2|
|$ip|$mac|$guid||$ip2|$mac2|$guid2|
Спустя 13 минут, 42 секунды (20.08.2010 - 09:36) linker написал(а):
for ($i = 0; $i < $count; $i++)
{
$vars = explode('|', $lines[$i]);
if ($vars[3] == $guid)
{
$lines[$i] = "|$ip|$mac|$guid|\n";
break;
}
}
Спустя 7 минут, 15 секунд (20.08.2010 - 09:43) novell написал(а):
Не помогает ! Делал !
До изменения
После
До изменения
|1.0.0.1|00:1E:8C:7A:36:BE|MS1C7CBA3G05273|
|1.0.0.2|00:1D:60:77:39:0F|MT7079K05603606|
|1.0.0.3.109.21.4|00:0D:61:18:A4:21|MT7079KG0527|
После
|1.0.0.4|00:1E:8C:7A:36:BE|MS1C7CBA3G05273||1.0.0.2|00:1D:60:77:39:0F|MT7079K05603606|
|1.0.0.3.109.21.4|00:0D:61:18:A4:21|MT7079KG0527|
Спустя 20 минут, 16 секунд (20.08.2010 - 10:04) linker написал(а):
$lines = file('test.dat');
$count = count($lines);
for ($i = 0; $i < $count; $i++)
{
$vars = explode('|', $lines[$i]);
if ($vars[3] == $guid)
{
$lines[$i] = "|$ip|$mac|$guid|\n";
break;
}
}
if ($i == $count)
$lines[] = "|$ip|$mac|$guid|\n";
file_put_contents('test.dat', $lines);
Спустя 16 минут, 20 секунд (20.08.2010 - 10:20) novell написал(а):
И опять же всё тоже самое !!!!
Спустя 8 минут, 47 секунд (20.08.2010 - 10:29) linker написал(а):
Ищи, опечатку у себя. У меня все работает, проверил прямо сейчас. Файл должен заканчиваться переводом строки
данные
данные
данные
<-- пустая строка <-- EOF
Попробуй заменить "\n" на "\n\r"
данные
данные
данные
<-- пустая строка <-- EOF
Попробуй заменить "\n" на "\n\r"
Спустя 1 минута, 54 секунды (20.08.2010 - 10:31) novell написал(а):
Как можно опечататься, если я код копирую ! Ну попробую ещё раз...
Спустя 14 минут, 9 секунд (20.08.2010 - 10:45) Nord написал(а):
Только наоборот, не \n\r, а \r\n.
Или вообще использовать специальную константу PHP_EOL
Или вообще использовать специальную константу PHP_EOL
Спустя 5 минут, 38 секунд (20.08.2010 - 10:50) novell написал(а):
Всё работает!!! Это я сглупил.. Спать нужно больше. Изменял 1 файл а запускал в другой !!! Спасибо огромное всем за помощь !
Спустя 1 минута, 10 секунд (20.08.2010 - 10:52) linker написал(а):
Уффффф!!!