БлогNot. PHP: читаем массив строк, проверяем закрытие тегов в строке и выводим в 2 колонк...

PHP: читаем массив строк, проверяем закрытие тегов в строке и выводим в 2 колонки

Входный файл имеет формат вида

Блок 1 текста, можно <b>с разметкой HTML</b>,<br>но в одну строку файла
http://blog.kislenko.net/pictures/10714.jpg
Блок 2 текста, все тексты в Юникоде (UTF-8), <i>тег не закрыт</p>
http://blog.kislenko.net/pictures/3298.jpg

то есть, в нём чередуются однострочные (или вытянутые в одну строку) кусочки HTML-кода и URL-адреса картинок.

Нам нужно за одно выполнение скрипта прочитать этот файл и вывести его содержимое в двухколоночный макет, причём, слева всегда выводятся текстовые блоки, а справа - картинки. Таблицы HTML (теги <table>) для формирования макета не применяем.

Функция readData читает в массив переданный ей аргументом файл, потом бьёт его на массивы нечётных ($content) и чётных ($urls) по порядку строк. В строках массива $content функция closetags закрывает незакрытые теги, если таковые есть, а стандартный метод filter_var позволяет отфильтровать некорректные URL-адреса.

Вот полный листинг скрипта, который справился с задачей на локалхосте, предполагается, что он будет сохранён и выполнен в Юникоде (UTF-8).

<!DOCTYPE html>
<html dir="ltr" lang="ru-RU">
<head>
 <meta charset="utf-8">
 <title></title>
 <style>
  .content {
   width: 800px; margin: 0 auto;
  }
  .column1 {
   float: left; width: 50%;
  }
  .column2 {
   float: left; width: 50%;
  }
  .imgin {
   max-width: 100%;
   height: auto;
   max-height:100%;
 }
 </style>
</head>
<body>

<?php
 function closetags($html) {
  preg_match_all ('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
  $openedtags = $result[1];
  preg_match_all('#</([a-z]+)>#iU', $html, $result);
  $closedtags = $result[1];
  $len_opened = count($openedtags);
  //if (count($closedtags) == $len_opened) return $html;
  $openedtags = array_reverse($openedtags);
  for ($i=0; $i < $len_opened; $i++) {
   if (!in_array($openedtags[$i], $closedtags)) $html .= '</'.$openedtags[$i].'>';
   else unset ($closedtags[array_search($openedtags[$i], $closedtags)]);
  }
  return $html;
 } 

 function readData ($filename) {
  $data = @file ($filename) or die ("Не могу открыть файл $filename");
  if (count($data) < 2 or count($data)%2) 
   die ("В файле $filename менее 2 строк или нечётное количество строк");
  //Делим массив $data на массивы нечётных ($content) и чётных ($urls) строк
  $content = $urls = array();
  array_walk ($data, 
   function ($value, $key, $result) {
    array_push ($result[$key & 1], $value);
   }, 
   array (&$content, &$urls));
  //Проверяем закрытие тегов и корректность URL
  for ($i = 0; $i < count ($urls); $i++) {
   $content[$i] = closetags (trim($content[$i]));
   $urls[$i] = trim($urls[$i]);
   if (!filter_var ($urls[$i], FILTER_VALIDATE_URL))
    die ("Неверный URL<br>{$urls[$i]}<br>в файле $filename");
  }
  return array ($content, $urls);
 }

 $s = '<div class="content">'."\n";
 list ($content, $urls) = readData("data.txt");
 for ($i = 0; $i < count ($urls); $i++) {
  $s .= '<div class="column1">'.$content[$i].'</div>'."\n";
  $s .= '<div class="column2"><a href="'.$urls[$i].
   '" target="_blank"><img class="imgin" src="'.$urls[$i].'" alt="'.$urls[$i].'"></a></div>'."\n";
 }
 $s .= '</div>'."\n";
 echo "$s";
?>
</body></html>

Замечания:

1. Не факт, что мы корректно для всех браузеров обращаемся с рисунком, масштабируя его указанием в теге <img> стилевого класса imgin. Класс предназначен, чтобы подогнать размеры картинки под размеры раздела.

2. Так как весь файл читается сразу, подход годится для относительно небольших по размеру файлов, для миллионов строк его применять не стоит.

30.01.2019, 10:56 [1593 просмотра]


теги: textprocessing программирование css php форматы

К этой статье пока нет комментариев, Ваш будет первым