[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Интересная задачка с массивами.
novell
Уважаемые Гуру... Я только начал изучать php и мне бы хотелось написать один скриптик. Что он должн делать:

Мы имеем на входе 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|

И так далее !!! Но должна существовать проверка описанная выше !

Спустя 1 час, 12 минут, 44 секунды (19.08.2010 - 15:24) sergeiss написал(а):
Цитата (novell @ 19.08.2010 - 11:37)
Нужно сделать, что бы скрипт писал в файл эти данные в формате |$ip|$mac|$guid|, каждый запрос с новой строки. НО. Должна существовать проверка... Если строка с содержимым переменной $guid уже существует, то мы просто переписываем целиком всю строку...

Эта задача - для БД, а не для файлов. Научись работать с БД и не парь мозХ ни себе, ни другим smile.gif

Спустя 5 минут, 49 секунд (19.08.2010 - 15:30) Димитер написал(а):
Тогда открывай файл модом 'a+', формируй строку с символами | и дописывай все это в файл без его сноса. Это дописывание. Если же проверка дает отрицательный результат, сносишь файл и все равно дописываешь.
Сама проверка: проверяешь длину строки файла, она должна быть меньше без третьей переменной.















Спустя 8 минут, 41 секунда (19.08.2010 - 15:38) novell написал(а):
sergeiss База данных не нужна. Нужны именно файлы. Я сам понимаю, что с базой было бы проще и быстрее всё это дело написать. Но файлы и только файлы sad.gif Нет возможности использовать базу...

Димитер А как я по Вашему буду заменять строку ?

Спустя 2 минуты (19.08.2010 - 15:40) Basili4 написал(а):
sergeiss

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|

Спустя 7 минут, 56 секунд (19.08.2010 - 15:53) Димитер написал(а):
Тогда построй все остальные строки без |(если совсем надо, можешь заменить слешами или другими символами), и проверяй каждый элемент массива файла на |. Это осуществление проверки. Если нету, то дописываешь. Если есть, то элемент массива, в котором есть |, заменяешь на новую строку. склеиваешь implode-ом все элементы в новую строку, сносишь файл и дописываешь ее.














Спустя 5 минут, 58 секунд (19.08.2010 - 15:59) sergeiss написал(а):
Цитата (novell @ 19.08.2010 - 16:38)
База данных не нужна. Нужны именно файлы.

Звучит примерно как "Нет, дядя Вова... Скрипач не нужен!" wink.gif

Почему именно файлы, почему не БД?

Второй вариант - делай свою БД, т.е. файлы с данными и файлы с индексами. Если, конечно, делать больше нечего в жизни.

Спустя 5 минут, 27 секунд (19.08.2010 - 16:04) novell написал(а):
sergeiss
Какая вообще задача стоит. Я пишу что-то типа таблици ARP, откуда я буду забирать по IP клиента 2 параметра мак сетевухи и гуид матери. Пишу это я для чата, который работает на чат демоне и не использует базы данных ! MySQL на серваке есть, но он переодически отваливается, а если я не получу мак и гуид пользюка, то в чат он просто не войдёт. Это всё делается для эффективности бана чата !

Спустя 10 минут, 27 секунд (19.08.2010 - 16:15) sergeiss написал(а):
А почему именно MySQL? Есть еще, например, SQLite. Там вся БД лежит в одном файле, и таблицы, и индексы.
Но это по-любому БД, хоть и проще, чем 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)
Я понимаю твоё рвение посадить меня на БД

Анекдот вспоминается: "папа, ты сейчас с кем разговаривал?" biggrin.gif biggrin.gif biggrin.gif

Если тебе "кровь из носу" надо сделать такую хрень на файлах и ты категорически не хочешь потратить 1,5 часа на изучение БД... То тогда не работай с разделителями, и используй под каждую "колонку" определенное количество знаков. Тогда под одну запись (строку) у тебя тоже будет отведено известное заранее количество знаков, плюс добавь несколько служебных полей. Тогда ты сможешь легко перейти к любой записи, не загружая весь файл (особенно, если сделаешь индексы). Тогда ты сможешь заменить данные в любой записи, не нарушая структуру файла. Тогда ты сможешь сделать пометки для любой записи о том, что она удалена и с ней не надо работать.

Но в итоге, после длительных мучений, ты сделаешь свою личную пародию на БД. Оно тебе надо? Занимайся. Алгоритм (в кратком виде) описан в предыдущем абзаце.

Спустя 5 часов, 3 минуты, 18 секунд (19.08.2010 - 21:54) Nord написал(а):
Вариант на скорую руку:

$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]);
if ($vars[3] == $guid)
{
...
}
Вот только, какого вида этот 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]);
if ($vars[3] == $guid)
{
...
}
Вот только, какого вида этот guid? Можно и так
if (!strcmp($vars[3], $guid))
{
...
}

ВОт

Спустя 3 минуты, 10 секунд (20.08.2010 - 08:50) linker написал(а):
Заметь, $vars[3], а не $vars[2] - это важно.
Использование strcmp() возможно при guid'ах аля md5.

Спустя 1 минута, 37 секунд (20.08.2010 - 08:52) novell написал(а):
По поводу $vars[2] я и сам понял ! Исчисления всё же с 0 идут
а гуид имеет вид 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|

Спустя 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"

Спустя 1 минута, 54 секунды (20.08.2010 - 10:31) novell написал(а):
Как можно опечататься, если я код копирую ! Ну попробую ещё раз...

Спустя 14 минут, 9 секунд (20.08.2010 - 10:45) Nord написал(а):
Только наоборот, не \n\r, а \r\n.
Или вообще использовать специальную константу PHP_EOL

Спустя 5 минут, 38 секунд (20.08.2010 - 10:50) novell написал(а):
Всё работает!!! Это я сглупил.. Спать нужно больше. Изменял 1 файл а запускал в другой !!! Спасибо огромное всем за помощь !

Спустя 1 минута, 10 секунд (20.08.2010 - 10:52) linker написал(а):
Уффффф!!!
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.