вторник, 5 февраля 2013 г.

Многострочный текст в php-сценарии

Когда php-сценарий должен выводить многострочный текст из элемента формы <textarea> (или из текстового файла), возникает проблема реализации перехода на новую строку. Кроме того, оказывается, что при пересылке из формы кавычки в тексте автоматически экранируются, т.е. к каждой кавычке добавляется слэш. Это значит, что в настройках сервера, на котором работает php-сценарий, включены "магические кавычки" (magic_quotes). Решаем эти проблемы:
Как выполняется переход на новую строку
Отображение многострочного текста в браузере
- Получение массива строк исходного текста
- Использование функции nl2br
- Нумерация строк
Как устранить экранирование

Как выполняется переход на новую строку

В текстовом файле или в многострочном текстовом поле формы строки отделяются специальными управляющими символами n и/или r (в зависимости от операционной системы): в Windows это rn, в Unix - n, а в MacOX - nr.
А в браузере (текст с html-разметкой) переход на новую строку (разрыв строки) - это тег <br/> (break)
<body>
...
строка 1<br>
строка 2<br>
строка 3
...
Это значит, что перед выводом многострочного текста в браузер нужно заменить управляющие символы тегами.

Отображение многострочного текста в браузере

Допустим, нужно показать в браузере исходный текст, который может содержать html-разметку.Это может быть текст с примерами html-кода.

Получение массива строк исходного текста

Текстовый файл может быть прочитан сразу как массив (список) отдельных строк, например, с помощью функции file(). Но из поля формы <textarea> текст передается в сценарий как одна строка, в которой присутствуют управляющие символы перехода на новую строку. Сначала разделим текст на строки с использованием регулярного выражения, а потом выведем эти строки с нужным разделителем. Массив $lines содержит отдельные строки исходного текста $text, в котором специальные html-символы заменены их эквивалентами (функция htmlspecialchars), чтобы они не интерпретировались браузером, а отображались "как есть":
<? php
$lines = preg_split("/((r(?!n))|((?<!r)n)|(rn))/", htmlspecialchars($text));
// вывод элементов массива $lines с заданным разделителем "<br>"
echo(implode("<br>", $lines));
?>
Аналогично работает php-функция nl2br, которая вставляет разрыв строки '<br />' (xhtml, по умолчанию) или '<br>' перед каждой новой строкой.

Использование функции nl2br

string nl2br ( string $string [, bool $is_xhtml = true ] )
<? php
$text="строка1n строка2";
$text1 = nl2br(htmlspecialchars($text)); // вставляет <br />
echo($text1);
?>
Если функция htmlspecialchars не используется, а в исходном тексте есть тег <pre>:
<pre>
строка1
строка2
</pre>
добавление функцией nl2br тегов разрыва строки приведет к появлению пустых строк, и сами теги <pre> не будут показаны в браузере :
строка1

строка2

Нумерация строк

Первый из приведенных способов, когда создается массив строк текста (например, с использованием регулярного выражения), является более гибким. Полученные отдельные строки можно помещать внутрь таких тегов, как <div>, <span> или <li> или обрабатывать как-то еще. Например, можно получить <div>-слои с уникальными id:
<? php
  $lines = preg_split("/((r(?!n))|((?<!r)n)|(rn))/", $text);
  $num=count($lines) -1;
  // вывод элементов массива $lines
  for ($i = 0; $i <$num; $i++) {
  echo("<div class="line" id="line". $i ."">" . $lines[$i] . "</div>");
  }
?>

  <div class="line" id="line1">строка1</div>
  <div class="line" id="line2">строка2</div>
  <div class="line" id="line3">строка3</div>
или нумерованный список:
<ol>
<li>строка1</li>
<li>строка2</li>
<li>строка3</li>
</ol>

Как устранить экранирование

"Волшебные кавычки" (magic_quotes) используются в PHP из соображений безопасности. Когда экранирование добавляется автоматически (к одинарным и двойным кавычкам, обратным слэшам () и NUL), не нужно добавлять слэши функцией addslashes() во всех запросах Get, Post и Cookie. Но, к сожалению, при этом экранирование появляется и там, где это не нужно. Удалить ненужные слэши из строки позволяет функция stripslashes(). Но можно и "отключить" экранирование на время выполнения сценария, добавив в начале:
<?php
  // magic_quotes
  function strips(&$el) {
  if (is_array($el))
   foreach($el as $k=>$v)
    strips($el[$k]);
   else $el = stripslashes($el);
  }
  if (get_magic_quotes_gpc()) {
   strips($_GET);
   strips($_POST);
   strips($_COOKIE);
   strips($_REQUEST);
   if (isset($_SERVER['PHP_AUTH_USER'])) strips($_SERVER['PHP_AUTH_USER']);
   if (isset($_SERVER['PHP_AUTH_PW']))   strips($_SERVER['PHP_AUTH_PW']);
  }
?>
или, если есть такая возможность, можно добавить в файл .htaccess сайта:
#php_flag magic_quotes_gpc 0
#php_flag magic_quotes_runtime 0
Всего просмотров 493, сегодня 6
Запись опубликована в рубрике PHP с метками , , , , , , . Добавьте в закладки постоянную ссылку.

Комментариев нет:

Отправить комментарий