Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > PHP поиск по CSV файлу.


Автор: WebCob 4.8.2004, 18:08
Суть заключается в том, что есть CSV файл содержащий поля A;B;C;D;E;F
Поля A и В числовые. А это начало диапазона, В это конец диапазона.
Поиск производится только по диапазону. В случае, если введенное число соответствует одному из диапазонов, то нужно вывести на print поля C;D;E;F именно той строки в которой было найдено число Э диапазону.

Автор: Ignat 4.8.2004, 18:40
И какие проблемы?
Код
$number=5; //число
$lines=file("file.csv");
foreach ($lines as $line_num => $line) {
  $nums=explode(";",$line);
  ($nums[0]<$number&&$nums[1]>$number)?echo $line:"";
}

Автор: IZ@TOP 4.8.2004, 20:34
Ignat
Зачем такой изврат с foreach??? Мне кажется что эту конструкцию в данном случае лучше заменить на for.

Автор: Ignat 4.8.2004, 21:51
А чччёрт его знает, мне почему-то больше foreach нравится, можно еще while сделать, кстати, пример из мануала smile.gif

Автор: IZ@TOP 4.8.2004, 23:13
Ignat
Про мануал то понятно. Просто работа цикла foreach по понятным соображениям в несколько раз медленее чем for.

PS Правила улучшения производительности, часть 1.

Автор: Ignat 5.8.2004, 08:55
Уговорил:
Код
$number=5; //число
$lines=file("file.csv");
for($i=0;$i<count($lines);$i++){
 $nums=explode(";",$lines[$i]);
 ($nums[0]<$number&&$nums[1]>$number)?echo $lines[$i]:"";
}

Автор: WebCob 5.8.2004, 09:05
У меня это получилось так:
$massive = file("test1.csv", "r");
$count_data = count($massive);
for($i=0; $i<$count_data; $i++)
$data = explode(";", $massive[$i]);
$index_no[$i] = $data[0];
$begin_count[$i] = $data[1];
$end_count[$i] = $data[2];
$start_action[$i] = $data[3];
$end_action[$i] = $data[4];
$info_action[$i] = $data[5];
$data[1] = array($begin_count[$i]);
$data[2] = array($end_count[$i]);
$data_count = count($begin_count);
while (--$data_count+1)
if ($begin_count[$data_count] <= $int_no and $int_no <= $end_count[$data_count])
Но работать не хочет. По умолчанию выводит информацию из последней строки полей C;D;E;F
Все заганяется в массив, потом индексируется. А вот дальше я не соображаю как сделать...

Автор: Ignat 5.8.2004, 09:27
Ничего у тебя в массив не загоняется - только последняя строчка файла. Скобки поставь.

Автор: WebCob 5.8.2004, 09:47
На счет последней строчки, ладно скобки поставлю. А вот на счет моего вопроса:
Поля A и В числовые. А это начало диапазона, В это конец диапазона.
Поиск производится только по диапазону. В случае, если введенное число соответствует одному из диапазонов, то нужно вывести на print поля C;D;E;F именно той строки в которой было найдено число Э диапазону.
В моем примере А=$begin_count[$i], а В=$end_count[$i].
Нужно, чтобы найдя нужное значение между А и В в какой то из строк, выводилась информация полей C;D;E;F принадлежащие этой строке.

Автор: Ignat 5.8.2004, 09:55
Пожди, а мой пример что делает - обратно в файл, чтоль, записывает?

Автор: WebCob 5.8.2004, 10:26
А Ты бы мог дать пояснение к примеру? Этот пример, есть и на www.php.net. Но я нет так хорошо знаю PHP поэтому пока-что не поворотлив в нем. Если можно, то на моем примере. То, что задаем число, читаем файл, потом задаем цикл, и считаем строки задавая каждому $lines - свой номер строки, а что вот это:
($nums[0]<$number&&$nums[1]>$number)?echo $lines[$i]:""; Что она делает прежде чем выведет на печать?
Что такое $nums[0]? $number&&$nums[1]>$number - сравнение? тогда что с чем?

Автор: Ignat 5.8.2004, 12:27
Конструкция ... ?... : .... ; Берет свое начало в си - это аналог if(....){ ....}else{.....}; , но в одну строчку.
($nums[0]<$number&&$nums[1]>$number)?echo $lines[$i]:"";
Здесь ($nums[0]<$number&&$nums[1]>$number) - условие.
$nums[0]-A, $nums[1]-B, && - "И"(AND)

echo $lines[$i] - блок THEN
"" - блок ELSE (т.к. пустой ставим кавычки).
Explode есть и в твоем примере, думаю, с ним все понятно.

Автор: WebCob 5.8.2004, 14:14
Наверное я не правильно описал то что я хочу сделать.
Чего то не получается у меня... www.php.net, уже весь перевернул. Создавать текстовую базу это конечно дело не благодарное но решать задачу нужно. Вот копия содержимого test1.csv файла.
index_no;begin_count;end_count;start_action;end_action;info_action
1;lrmos117720000;lrmos117729999;01.05.2000;04.08.2004;Продается в салоне А
2;lrmos117730000;lrmos117739999;09.07.2001;05.08.2004;Продается в салоне В
3;lrmos117740000;lrmos117749999;15.08.2002;06.08.2004;Продается в салоне С
4;lrmos117750000;lrmos117759999;01.03.2002;07.08.2004;Продается в салоне D
5;lrmos117760000;lrmos117769999;01.01.2003;08.08.2004;Продается в салоне E
6;lrmos117770000;lrmos117779999;08.02.2003;09.08.2004;Продается в салоне F
7;lrmos117780000;lrmos117789999;30.07.2004;10.08.2004;Продается в салоне G
8;lrmos117790000;lrmos117799999;04.08.2004;11.08.2004;Продается в салоне H

Вот моя программа, которая должна обрабатывать csv файл и выводить на принт информацию только той строки в которой найден счет (к примеру: lrmos117720527, то вывести на принт поля 01.05.2000;04.08.2004;Продается в салоне А)

<?php
/*Okno dlya vvoda*/
print "<FORM NAME='card' METHOD=get><center><h1><br>";
print "<h2><font color=black>Введите счет начинающийся c lrmos.<br>";
print "<INPUT TYPE=text NAME=int_no SIZE=15>";
print "<INPUT TYPE=SUBMIT NAME=button VALUE=Enter><br>";
if ($button=="Enter")
/*Finish Okno dlya vvoda*/

$massive = file("test1.csv", "r");
$count_data = count($massive);
for($i=0; $i<$count_data; $i++)
$data = explode(";", $massive[$i]);
$index_no[$i] = $data[0];
$begin_count[$i] = $data[1];
$end_count[$i] = $data[2];
$start_action[$i] = $data[3];
$end_action[$i] = $data[4];
$info_action[$i] = $data[5];
$data[1] = array($begin_count[$i]);
$data[2] = array($end_count[$i]);
$data_count = count($begin_count);
while (--$data_count+1)
print "<br> $data[$i]- i<br>$int_no<br>$data[0]-0<br>$data[1]-1<br> $data[2]-2<br>$data[3]-3
$data[4]-4<br> $data[5]-5<br>\n";
if ($begin_count[$data_count] <= $int_no and $int_no <= $end_count[$data_count])
?>

Может есть идеи? С примером выше я уже пробовал.

Автор: Ignat 5.8.2004, 14:32
Лови, если не работает, скажи, тогда проверю. А сейчас со временем не очень.
Код
<?php
function rplc($text){
return str_replace("lrmos","",$text);
}

/*Okno dlya vvoda*/
print "<FORM NAME='card' METHOD=get><center><h1><br>";
print "<h2><font color=black>Введите счет начинающийся c lrmos.<br>";
print "<INPUT TYPE=text NAME=int_no SIZE=15>";
print "<INPUT TYPE=SUBMIT NAME=button VALUE=Enter><br>";
/*Finish Okno dlya vvoda*/

if (!empty($_GET)){

$number=&$_GET['int_no']
$lines=file("test1.csv","r");
for($i=0;$i<count($lines);$i++){
$nums=explode(";",$lines[$i]);

(rplc($nums[1])<$number&&rplc($nums[2])>$number)?printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";
}

}
?>



Автор: WebCob 5.8.2004, 14:42
Ок! У меня со временем тоже не особо, по этому понимаю. Ignat я через парочку минут и скажу Тебе.

Автор: WebCob 5.8.2004, 14:57
Вот что выводит
lrmos117790000,lrmos117799999
Если для проверки воткнуть принт

(rplc($nums[1])<$number&&rplc($nums[2])>$number)?printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";
}
print "$nums[1],$nums[2]";// проверка

}

Либо, без него не выводит ни чего...

Автор: Ignat 5.8.2004, 15:11
Странно, у меня работает...
А вот так у тебя будет работать?
Код
<?php
function rplc($text){
return str_replace("lrmos","",$text);
}

/*Okno dlya vvoda*/
print "<FORM NAME='card' METHOD=get><center><h1><br>";
print "<h2><font color=black>Ââåäèòå ñ÷åò íà÷èíàþùèéñÿ c lrmos.<br>";
print "<INPUT TYPE=text NAME=int_no SIZE=15>";
print "<INPUT TYPE=SUBMIT NAME=button VALUE=Enter><br>";
/*Finish Okno dlya vvoda*/

if (!empty($_GET)){

$number=rplc($_GET['int_no']);
$lines=file("test1.csv","r");
for($i=0;$i<count($lines);$i++){
$nums=explode(";",$lines[$i]);

(rplc($nums[1])<$number&&rplc($nums[2])>$number)?printf("c %s ïî %s ïðîäàåòñÿ â ñàëîíå %s",$nums[3],$nums[4],$nums[5]):"";
}

}
?>

Автор: WebCob 5.8.2004, 17:35
Ни хочет работать... Перебрал несколько вариантов. Все в пустую.
Думал может под Виндой такой глюк но и на линухе под аппаче тоже самое...

Автор: Ignat 5.8.2004, 17:44
Какая версия пхп? Попробуй $_GET заменить на $HTTP_GET_VARS;

Добавлено @ 17:44
Какую-нибудь ошибку дает?
Добавлено @ 17:47
После этой строчки
$nums=explode(";",$lines[$i]);
попробуй поставить
print_r($nums);

Автор: WebCob 5.8.2004, 18:06
$_GET исправил на $HTTP_GET_VARS.
У меня вообщето используется вот эта логика:
//HTTP_GET_VARS
//**************
while (list($key, $val) = @each($HTTP_GET_VARS)) {
$GLOBALS[$key] = $val;
}
//**************
//HTTP_POST_VARS
//**************
while (list($key, $val) = @each($HTTP_POST_VARS)) {
$GLOBALS[$key] = $val;
}
//**************
//HTTP_POST_FILES
//**************
while (list($key, $val) = @each($HTTP_POST_FILES)) {
$GLOBALS[$key] = $val;
}
//**************
//$HTTP_SESSION_VARS
//**************
while (list($key, $val) = @each($HTTP_SESSION_VARS)) {
$GLOBALS[$key] = $val;
}
//**************
//$_SERVER
//**************
while (list($key, $val) = @each($_SERVER)) {
$GLOBALS[$key] = $val;
}
#===End- global======#

Это спасает от PHP и Windows глюков.
Но в данном случае я ее сейчас не пользую. Хотя пробовал и с ней, но убрал.

Ошибок ни каких не выдает. Переписал немного, справил синтаксические ошибки, заработала. Теперь она печатает весь csv файл, не разбирая его.
(rplc($nums[1])<$number&&rplc($nums[2])>$number);
print "(c $s ïî $s ïðîäàåòñÿ â ñàëîíå $s,,$nums[3],$nums[4],$nums[5])";

Поставил print_r($nums); и Теперь вот что выдает:
ОбычныйТерминСписокопределенийАдресЦитатыФорматированныйArray ( [0] => index_no [1] => begin_count [2] => end_count [3] => start_action [4] => end_action [5] => info_action ) (c по продается в салоне ,,start_action,end_action,info_action )Array ( [0] => 1 [1] => lrmos117720000 [2] => lrmos117729999 [3] => 01.05.2000 [4] => 04.08.2004 [5] => Продается в салоне А ) (c по продается в салоне ,,01.05.2000,04.08.2004,Продается в салоне А )Array ( [0] => 2 [1] => lrmos117730000 [2] => lrmos117739999 [3] => 09.07.2001 [4] => 05.08.2004 [5] => Продается в салоне В ) и т.д. до споледней строки.

А PHP Version 4.3.7

Автор: Ignat 6.8.2004, 09:03
Цитата
Это спасает от PHP и Windows глюков.

Ничего подобного - это выводит в глобальное окружение массивы, а это нехорошо, тем более это можно сделать проще.
Цитата
печатает весь csv файл, не разбирая его.
(rplc($nums[1])<$number&&rplc($nums[2])>$number);
print "(c $s ïî $s ïðîäàåòñÿ â ñàëîíå $s,,$nums[3],$nums[4],$nums[5])";

И не будет разбирать - у тебя нет проверки условия.
Синтаксическая ошибка в первом примере была только одна - я про....л точку с запятой.
вот это
Код
(rplc($nums[1])<$number&&rplc($nums[2])>$number)?printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";

замени на
if(rplc($nums[1])<$number&&rplc($nums[2])>$number){
printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";
}
Ты листинг исполняешь в том виде, в котором я привожу или куда-то вставляешь?

Автор: WebCob 6.8.2004, 09:50
На счет листинга, пока я отрабатываю форму, я исполняю только в том виде в котором Ты приводишь. Думаю это правильно.
Даже с учетом того, что
if(rplc($nums[1])<$number&&rplc($nums[2])>$number){
printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";
}
Не происходит индескирование строк, каждая строка начинается с единицы.


Автор: WebCob 6.8.2004, 10:38
Ignat не совсем понятно почему $number=rplc($_GET['int_no']); а не $number=rplc($_GET[$int_no]);
Мог бы пояснить?

Автор: Ignat 6.8.2004, 10:46
Блин, я уже ничего не понимаю. Вот код, скопируй его в отдельный файл и выполни, так как он есть:
Код
<?php
function rplc($text){
return str_replace("lrmos","",$text);
}

/*Okno dlya vvoda*/
?>
<FORM NAME='card' METHOD=get action=<?=$_SERVER['PHP_SELF']?>><center><h1><br>
<h2><font color=black>Введите счет начинающийся c lrmos.<br>
<INPUT TYPE=text NAME=int_no SIZE=15>
<INPUT TYPE=SUBMIT NAME=button VALUE=Enter><br>
<?
/*Finish Okno dlya vvoda*/

if (!empty($_GET['int_no'])){

$number=rplc($_GET['int_no']);
$lines=file("test1.csv","r");
for($i=0;$i<count($lines);$i++){
$nums=explode(";",$lines[$i]);

(rplc($nums[1])<=$number&&rplc($nums[2])>=$number)?printf("c %s по %s продается в салоне %s",$nums[3],$nums[4],$nums[5]):"";
}

}
?>

Автор: WebCob 6.8.2004, 11:52
Супер! Вот сейчас цепочка полная.
Благодаря не большому изменению в программе, а именно здесь:
if (!empty($_GET['int_no'])) Программа заработала!!!
Ignat - Огромное спасибо!!!
Я только изучаю PHP, но чем дальше, тем интереснее.
Можно Тебе еще один вопрос?
Вопрос касается добавление в этот же файл тех же полей в конец списка через web форму, грубо говоря, есть пользовательская часть, которая считывает информацию из CSV (То, что Ты помог мне), а есть административная, которая добавляет и изменяет содержимое строк(не полей!)? Или для этого Вопроса/Ответа нужно новый топик начинать?

Автор: Ignat 6.8.2004, 12:32
Да, новый топик, но скорее всего тебе будет не нужен. Поищи по форуму "файл", "fwrite" найдешь море информации об файловых БД.

Автор: WebCob 6.8.2004, 13:13
Ignat, спасибо за терпение и очень грамотную помощь!
Скажи, я ни как не могу найти, как репутацию повышать, тому кто тебе помогает?
Очень хочется помимо спасибо еще поднять и Твой уровень репутации.

Автор: Ignat 6.8.2004, 13:41
smile.gif Спасибо, но репутацию сможешь повышать, после 100 постов.
А на помощь здесь всегда можно рассчитывать...
Удачи в изучении.
Добавлено @ 13:45
Цитата(WebCob @ 6.8.2004, 11:38)
Ignat не совсем понятно почему $number=rplc($_GET['int_no']); а не $number=rplc($_GET[$int_no]);
Мог бы пояснить?

Упс, не заметил этот пост.
$_GET - ассоциативный массив (хеш), в котором именнованные поля, которые носят имя передаваемого параметра ('int_no'), а не его значения ($int_no).
Отсюда: $_GET['int_no']

Автор: WebCob 6.8.2004, 14:32
Все понял! Спасибо еще раз.
Удачи!
На счет форума, я уже понял, здесь точно помогут! Это приятно.
Спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)