Глюк fgetcsv или кривые руки ?

Krisha

pain in the neck
Глюк fgetcsv или кривые руки ?

Имеется текстовый файл (tab delimited), который я читаю вполне обычным способом:
PHP:
$handle = fopen($this->filename,"r");
while ($data = fgetcsv($handle, $this->length, $this->delimiter)) {
   $list[] = $data;
}
fclose($handle);
В результате, по-мимо имеющихся строк получаю какие-то "левые" пустые строки, то есть массив вида:
Код:
Array
(
    [0] => 
)
Вот файлик: import.txt

Не пойму как с этим бороться. Попробуйте его почитать плиз.

Win2000, Apache 1.3.29, PHP 4.3.4
 

crocodile2u

http://vbolshov.org.ru
Попробовал твой код с твоим же файлом. При fgetcsv-length заведомо больше длины самой длинной строки файла все отрабатывает на ура. Глюки начинаются при fgetcsv-length меньше длины самой длинной строки файла.

Мануал:

Length must be greater than the longest line to be found in the CSV file (allowing for trailing line-end characters).
 

Krisha

pain in the neck
Хм, вот как я вычисляю самую длинную строку. Может быть тут глюк.
PHP:
       $length  = 0;
       $array   = file($this->filename);
       $counter = count($array);

       for ($i=0; $i<$counter; $i++) {
          if ($length < strlen($array[$i])) {
              $length = strlen($array[$i]);
          }
       }
       unset($array);

       $this->length = $length;
-~{}~ 12.05.04 12:17:

хм, да, если сделать, к примеру: $this->length = $length + 1024;
то глюки пропадают...
 

crocodile2u

http://vbolshov.org.ru
По идее хватило бы length+1 :)

И еще: зачем два раза читать файл - первый раз с помощью file(), а второй - с помощью fgetcsv() ?

PHP:
$list    = array();
$array   = file("import.txt"); 
$counter = count($array); 

for ($i=0; $i<$counter; $i++) { 
  if (trim($array[$i])) {
  	$list[] = explode("\t", $array[$i]);
  }
} 
unset($array);
print_r($list);
 

Krisha

pain in the neck
crocodile2u
По-поводу +1 это я по-приколу написал.

Ну, во первых у меня это length используется в нескольких местах, поэтому лучше один раз его получить, а потом использовать, чем каждый раз дергать файл.

По-поводу file + explode тут уже где-то обсуждалось, я правда внятного объяснения чем это хуже не видел, но мало ли :)

tony2001
Да, обновить-то я могу, но пока админ не обновил на live сервере я этого у себя тоде делать не хотел бы, чтобы лишние косяки потом не вылавливать. А когда он обновит никто не знает, я уего уже 30 раз просил.
 

crocodile2u

http://vbolshov.org.ru
Специально полазил по форуму, нашел несколько тредов насчет file+explode & fgetcsv. Я правда, заходил только в те, где уже в теме есть что-то схожее.

Вот результаты:

Кое-кто советует использовать file+explode (
а)нет глюков с кириллицей (правда, tony2001 говорит, что в 4.3.5 что-то пофиксили);
б) не надо указывать length
)

Тот же tony2001 говорит, что заменять fgetcsv на file+explode не есть правильно, и кроме того: "если бы все было так просто, зачем вообще нужна была бы fgetcsv" (цитата приблизительная)

Однако, исчерпывающих аргументов в пользу той или иной версии я лично не нашел. А хотелось бы...
 

Profic

just Profic (PHP5 BetaTeam)
Зачем Тони :)
При делиметере, который в данных встретиться не может и, следовательно, нет строк с ограничителями можно использоавть и тот способ и тот
А что будет с такой строкой при exlode?
field1;"field2;field2";field3
правильно - ничего хорошего. Будет 4 поля и не убраны ограничители. fgetcsv всё сделает правильно, но у него проблемы с руским (но это вроде как уже пофиксили). Можно конечно на такую строку натравить explode и потом его еще обработать, но зачем, если fgetcsv все сделает заметно лучше?

Выводы:
1) если символ разделитель такой, что строк с ограничителями нет, то логичнее использовать explode - убираются проблемы с length и руссским
2) если строки с ограничителями есть, то только один выход - использовать fgetcsv, т.к. постобработка результата explode ИМХО будет посложнее своей собственной fgetcsv (варианта для параноиков :) - хотя сам писал - одна мелкая регулярка и маленькая постобработка :)
 
Сверху