теги.


Печатая вслед за выводом объединенных данных, мы формируем полную строку таблицы. И функция substr(), и функция unpack() имеют одинаковые возможности, если поля фиксированной ширины содержат строки, но функция unpack() является наилучшим решением при наличии полей других типов данных..



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Анализ данных, разделенных запятой
Включение функций и выражений в строки
Доступ к подстрокам
Замещение подстрок
Посимвольная обработка строк

Вернуться в раздел: PHP / 1. Строки



Анализ данных, состоящих из полей фиксированной ширины

Задача
Необходимо разбить на части записи фиксированной ширины в строке.

Решение
Это делается при помощи функции substr():

$fp = fopen('fixed-width-records.txt','r') or die ("can't open file");
while ($s = fgets($fp,1024)) {
$fields[1] = substr($s,0,10); // первое поле:
первые 10 символов строки
$fields[2] = substr($s,10,5); // второе поле:
следующие 5 символов строки
$fields[3] = substr($s,15,12); // третье поле:
следующие 12 символов строки
// функция обработки полей
process_fields($fields);
}
fclose($fp) or die("can't close file");

Или функции unpack():
$fp = fopen('fixed-width-records.txt','r') or die ("can't open file");
while ($s = fgets($fp,1024)) {
// ассоциативный массив с ключами "title", "author" и "publication_year"
$fields = unpack('A25title/A14author/A4publication_year',$s);
// функция обработки полей
process_fields($fields);
}
fclose($fp) or die("can't close file");

Обсуждение
Данные, в которых каждому полю выделено фиксированное число символов в строке, могут выглядеть, как этот список книг, названий и дат опубликования:

$booklist=<< Elmer Gantry Sinclair Lewis1927
The Scarlatti InheritanceRobert Ludlum 1971
The Parsifal Mosaic Robert Ludlum 1982
Sophie's Choice William Styron1979
END;

В каждой строке название занимает 25 символов, имя автора – следующие 14 символов, а год публикации – следующие 4 символа.


Зная ширину полей, очень просто с помощью функции substr() перенести поля в массив.

$books = explode("\n",$booklist);
for($i = 0, $j = count($books); $i < $j; $i++) {
$book_array[$i]['title'] = substr($books[$i],0,25);
$book_array[$i]['author'] = substr($books[$i],25,14);
$book_array[$i]['publication_year'] = substr($books[$i],39,4);
}

Разбиение переменной $booklist на массив строк позволяет применить один код разбора одной строки ко всем строкам, прочитанным из файла. Цикл можно сделать более гибким, определив отдельные массивы для имен полей и их ширины, которые могут быть переданы в анализирующую функцию, как показано в функции pc_fixed_width_substr() примера 1.3.

Пример 1.3. pc_fixed_width_substr()
function pc_fixed_width_substr($fields,$data) {
$r = array();
for ($i = 0, $j = count($data); $i < $j; $i++) {
$line_pos = 0;
foreach($fields as $field_name => $field_length) {
$r[$i][$field_name] = rtrim(substr($data[$i],$line_pos,$field_length));
$line_pos += $field_length;
}
}
Return $r;
}
$book_fields = array('title' => 25,
'author' => 14,
'publication_year' => 4);
$book_array = pc_fixed_width_substr($book_fields,$books);

Переменная $line_pos отслеживает начало каждого поля, и она увеличивается на ширину предыдущего поля по мере того, как код обрабатывает каждую строку.


Для удаления пробельных символов в конце каждого поля предназначена функция rtrim().
Как альтернатива функции substr() для извлечения полей может применяться функция unpack(). Вместо того чтобы задавать имена полей и их ширину в виде ассоциативных массивов, создайте строку форматирования для функции. Код для извлечения полей фиксированной ширины аналогичен функции pc_fixed_width_unpack(), показанной в примере 1.4.

Пример 1.4. pc_fixed_width_unpack()
function pc_fixed_width_unpack($format_string,$data) {
$r = array();
for ($i = 0, $j = count($data); $i < $j; $i++) {
$r[$i] = unpack($format_string,$data[$i]);
}
return $r;
}
$book_array = pc_fixed_width_unpack('A25title/A14author/A4publication_year',
$books);

Формат A означает «строку в обрамлении пробелов», поэтому нет необходимости удалять завершающие пробелы с помощью функции rtrim(). Поля, перенесенные с помощью какой-либо функции в переменную $book_array, могут быть отображены в виде HTML-таблицы, например:

$book_array = pc_fixed_width_unpack('A25title/A14author/A4publication_year',
$books);
print "\n";
// печатаем строку заголовка
print '\n";
// печатаем каждую строку данных
foreach ($book_array as $row) {
print '\n";
}
print '
';
print join('
',array_keys($book_array[0]));
print "
';
print join('
',array_values($row));
print "
\n';

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