<?include'h.php';?>
<html><head>
		<title>Учебник PHP, Глава 8</title>
		<meta http-equiv="Content-type" content="text/html; charset=Windows-1251">
		</head>
		
      <DIV class=infotxt>
      <LI><A href="#a">Глава 8. Строки и 
      регулярные выражения</A> 
      <UL>
        <LI><A href="#b">Регулярные выражения</A> 
        <UL>
          <LI><A href="#c">синтаксис регулярных 
          выражений(POSIX)</A> </LI></UL>
        <LI><A href="#d">Функции PHP для работы с 
        регулярными выражениями(POSIX-совместимые)</A> 
        <LI><A href="#e">Синтаксис регулярных 
        выражений в стиле Perl</A> 
        <UL>
          <LI><A href="#f">Метасимволы</A> 
          <LI><A href="#g">Модификаторы</A> 
        </LI></UL>
        <LI><A href="#h">Функции PHP для работы с 
        регулярными выражениями(Perl-совместимые)</A> 
        <LI><A href="#i">Другие строковые 
        функции</A> 
        <UL>
          <LI><A href="#j">Дополнение и сжатие 
          строк</A> 
          <LI><A href="#k">Определение длины 
          строки</A> 
          <LI><A href="#l">Сравнение двух 
          строк</A> 
          <LI><A href="#m">Обработка строковых 
          данных без применения регулярных выражений</A> 
          <LI><A href="#n">Преобразование строк и 
          файлов к формату HTML и наоборот</A> 
          <LI><A href="#o">Преобразование HTML в 
          простой текст</A> 
          <LI><A href="#p">Преобразование строки к 
          верхнему и нижнему регистру</A> </LI></UL>
        <LI><A href="#q">Проект: идентификация 
        браузера</A> 
        <LI><A href="#r">Итоги</A> </LI></UL>
      <UL></UL><A name=a></A>
      <P>&nbsp;</P>
      <P>ГЛАВА 8</P>
      <P>Строки и регулярные выражения</P>
      <P>Возможности эффективной организации, поиска и распространения 
      информации давно представляли интерес для специалистов в области 
      компьютерных технологий. Поскольку информация в основном представляет 
      собой текст, состоящий из алфавитно-цифровых символов, разработка средств 
      поиска и обработки информации по шаблонам, описывающим текст, стала 
      предметом серьезных теоретических исследований.</P>
      <P>Поиск по шаблону позволяет не только находить определенные фрагменты 
      текста, но и заменять их другими фрагментами. Одним из стандартных 
      примеров поиска по шаблону являются команды поиска/замены в текстовых 
      редакторах — например, в MS Word, Emacs и в моем любимом редакторе vi. 
      Всем пользователям UNIX хорошо известны такие программы, как sed, awk и 
      grep; богатство возможностей этих программ в значительной степени 
      обусловлено средствами поиска по шаблону. Механизмы поиска по шаблону 
      решают четыре основные задачи:</P>
      <UL>
        <LI>поиск строк, в точности совпадающих с заданным шаблоном; 
        <LI>поиск фрагментов строк, совпадающих с заданным шаблоном; 
        <LI>замену строк и подстрок по шаблону; 
        <LI>поиск строк, с которыми заданный шаблон не совпадает. </LI></UL>
      <P>Появление Web породило необходимость в более быстрых и эффективных 
      средствах поиска данных, которые бы позволяли пользователям со всего мира 
      находить нужную информацию среди миллиардов web-страниц. Поисковые 
      системы, онлайновые финансовые службы и сайты электронной коммерции — все 
      это стало бы абсолютно бесполезным без средств анализа гигантских объемов 
      данных в этих секторах. Действительно, средства обработки строковой 
      информации являются жизненно важной составляющей практически любого 
      сектора, так или иначе связанного с современными информационными 
      технологиями. В этой главе основное внимание посвящено средствам обработки 
      строк в РНР. Мы рассмотрим некоторые стандартные строковые функции (в 
      языке их больше 60!), а из приведенных определений и примеров вы получите 
      сведения, необходимые для создания web-приложений. Но прежде чем 
      переходить к специфике РНР, я хочу познакомить вас с базовым механизмом, 
      благодаря которому становится возможным поиск по шаблону. Речь идет о 
      регулярных выражениях.</P>
      <P><A href="http.html://doks.gorodok.net/0" name=b></A>Регулярные выражения</P>
      <P>Регулярные выражения лежат в основе всех современных технологий поиска 
      по шаблону. Регулярное выражение представляет собой последовательность 
      простых и служебных символов, описывающих искомый текст. Иногда регулярные 
      выражения бывают простыми и понятными (например, слово dog), но часто в 
      них присутствуют служебные символы, обладающие особым смыслом в синтаксисе 
      регулярных выражений, — например, &lt;(?)&gt;.*&lt;\/.?&gt;.</P>
      <P>В РНР существуют два семейства функций, каждое из которых относится к 
      определенному типу регулярных выражений: в стиле POSIX или в стиле Perl. 
      Каждый тип регулярных выражений обладает собственным синтаксисом и 
      рассматривается в соответствующей части главы. На эту тему были написаны 
      многочисленные учебники, которые можно найти как в Web, так и в книжных 
      магазинах. Поэтому я приведу лишь основные сведения о каждом типе, а 
      дальнейшую информацию при желании вы сможете найти самостоятельно. Если вы 
      еще не знакомы с принципами работы регулярных выражений, обязательно 
      прочитайте краткий вводный курс, занимающий всю оставшуюся часть этого 
      раздела. А если вы хорошо разбираетесь в этой области, смело переходите к 
      следующему разделу.</P>
      <P><A name=c></A>Синтаксис регулярных выражений (POSIX)</P>
      <P>Структура регулярных выражений POSIX чем-то напоминает структуру 
      типичных математических выражений — различные элементы (операторы) 
      объединяются друг с другом и образуют более сложные выражения. Однако 
      именно смысл объединения элементов делает регулярные выражения таким 
      мощным и выразительным средством. Возможности не ограничиваются поиском 
      литерального текста (например, конкретного слова или числа); вы можете 
      провести поиск строк с разной семантикой, но похожим синтаксисом — 
      например, всех тегов HTML в файле.</P>
      <P>Простейшее регулярное выражение совпадает с одним литеральным символом 
      — например, выражение g совпадает в таких строках, как g, haggle и bag. 
      Выражение, полученное при объединении нескольких литеральных символов, 
      совпадает по тем же правилам — например, последовательность gan совпадает 
      в любой строке, содержащей эти символы (например, gang, organize или 
      Reagan).</P>
      <P>Оператор | (вертикальная черта) проверяет совпадение одной из 
      нескольких альтернатив. Например, регулярное выражение php | zend 
      проверяет строку на наличие php или zend.</P>
      <P>Квадратные скобки</P>
      <P>Квадратные скобки ([ ]) имеют особый смысл в контексте регулярных 
      выражений — они означают «любой символ из перечисленных в скобках». В 
      отличие от регулярного выражения php, которое совпадает во всех строках, 
      содержащих литеральный текст php, выражение [php] совпадает в любой 
      строке, содержащей символы р или h. Квадратные скобки играют важную роль 
      при работе с регулярными выражениями, поскольку в процессе поиска часто 
      возникает задача поиска символов из заданного интервала. Ниже перечислены 
      некоторые часто используемые интервалы:</P>
      <UL>
        <LI>[0-9] — совпадает с любой десятичной цифрой от 0 до 9; 
        <LI>[a-z] — совпадает с любым символом нижнего регистра от а до z; 
        <LI>[A-Z] — совпадает с любым символом верхнего регистра от А до Z; 
        <LI>[a -Z] — совпадает с любым символом нижнего или верхнего регистра от 
        а до Z. </LI></UL>
      <P>Конечно, перечисленные выше интервалы всего лишь демонстрируют общий 
      принцип. Например, вы можете воспользоваться интервалом [0-3] для 
      обозначения любой десятичной цифры от 0 до 3 или интервалом [b-v] для 
      обозначения любого символа нижнего регистра от b до v. Короче говоря, 
      интервалы определяются совершенно произвольно.</P>
      <P>Квантификаторы</P>
      <P>Существует особый класс служебных символов, обозначающих количество 
      повторений отдельного символа или конструкции, заключенной в квадратные 
      скобки. Эти служебные символы (+, * и {...}) называются квантификаторами. 
      Принцип их действия проще всего пояснить на примерах:</P>
      <UL>
        <LI>р+ означает один или несколько символов р, стоящих подряд; 
        <LI>р* означает ноль и более символов р, стоящих подряд; 
        <LI>р? означает ноль или один символ р; 
        <LI>р{2} означает два символа р, стоящих подряд; 
        <LI>р{2,3} означает от двух до трех символов р, стоящих подряд; 
        <LI>р{2,} означает два и более символов р, стоящих подряд. </LI></UL>
      <P>Прочие служебные символы</P>
      <P>Служебные символы $ и ^ совпадают не с символами, а с определенными 
      позициями в строке. Например, выражение р$ означает строку, которая 
      завершается символом р, а выражение ^р — строку, начинающуюся с символа 
      р.</P>
      <UL>
        <LI>Конструкция [^a-zA-Z] совпадает с любым символом, не входящим в 
        указаные интервалы (a-z и A-Z). 
        <LI>Служебный символ . (точка) означает «любой символ». Например, 
        выражение р.р совпадает с символом р, за которым следует произвольный 
        символ, после чего опять следует символ р. </LI></UL>
      <P>Объединение служебных символов приводит к появлению более сложных 
      выражений. Рассмотрим несколько примеров:</P>
      <UL>
        <LI>^.{2}$ — любая строка, содержащая ровно два символа; 
        <LI>&lt;b&gt;(.*)&lt;/b&gt; — произвольная последовательность символов, 
        заключенная между &lt;Ь&gt; и &lt;/Ь&gt; (вероятно, тегами HTML для 
        вывода жирного текста); 
        <LI>p(hp)* — символ р, за которым следует ноль и более экземпляров 
        последовательности hp (например, phphphp). </LI></UL>
      <P>Иногда требуется найти служебные символы в строках вместо того, чтобы 
      использовать их в описанном специальном контексте. Для этого служебные 
      символы экранируются обратной косой чертой (\). Например, для поиска 
      денежной суммы в долларах можно воспользоваться выражением \$[0-9]+, то 
      есть «знак доллара, за которым следует одна или несколько десятичных 
      цифр». Обратите внимание на обратную косую черту перед $. Возможными 
      совпадениями для этого регулярного выражения являются $42, $560 и $3.</P>
      <P>Стандартные интервальные выражения (символьные классы)</P>
      <P>Для удобства программирования в стандарте POSIX были определены 
      некоторые стандартные интервальные выражения, также называемые символьными 
      классами (character classes). Символьный класс определяет один символ из 
      заданного интервала — например, букву алфавита или цифру:</P>
      <UL>
        <LI>[[:alpha:]] — алфавитный символ (aA-zZ); 
        <LI>[[:digit:]]-цифра (0-9); 
        <LI>[[:alnum:]] — алфавитный символ (aA-zZ) или цифра (0-9); 
        <LI>[[:space:]] — пропуски (символы новой строки, табуляции и т. д.). 
        </LI></UL>
      <P><A name=d></A>Функции РНР для работы с регулярными выражениями 
      (POSIX-совместимые)</P>
      <P>В настоящее время РНР поддерживает семь функций поиска с использованием 
      регулярных выражений в стиле POSIX:</P>
      <UL>
        <LI>еrеg( ); 
        <LI>еrеg_rерlасе( ); 
        <LI>eregi( ); 
        <LI>eregi_replace( ); 
        <LI>split( ); 
        <LI>spliti( ); 
        <LI>sql_regcase( ). </LI></UL>
      <P>Описания этих функций приведены в следующих разделах.</P>
      <P>ereg( )</P>
      <P>Функция еrеg( ) ищет в заданной строке совпадение для шаблона. Если 
      совпадение найдено, возвращается TRUE, в противном случае возвращается 
      FALSE. Синтаксис функции ereg( ):</P>
      <P>int ereg (string шаблон, string строка [, array совпадения])</P>
      <P>Поиск производится с учетом регистра алфавитных символов. Пример 
      использования ereg( ) для поиска в строках доменов .соm:</P>
      <P>$is_com - ereg("(\.)(com$)", $email):</P>
      <P>// Функция возвращает TRUE, если $email завершается символами 
".com"</P>
      <P>// В частности, поиск будет успешным для строк</P>
      <P>// "www.wjgilmore.com" и "someemail@apress.com"</P>
      <P>Обратите внимание: из-за присутствия служебного символа $ регулярное 
      выражение совпадает только в том случае, если строка завершается символами 
      .com. Например, оно совпадет в строке "www.apress.com", но не совпадет в 
      строке "www.apress.com/catalog".</P>
      <P>Необязательный параметр совпадения содержит массив совпадений для всех 
      подвыражений, заключенных в регулярном выражении в круглые скобки. В 
      листинге 8.1 показано, как при помощи этого массива разделить URL на 
      несколько сегментов.</P>
      <P>Листинг 8.1. Вывод элементов массива $regs</P>
      <P>$url = "http://www.apress.com";</P>
      <P>// Разделить $url на три компонента: "http://www". "apress" и "com"</P>
      <P>$www_url = ereg("^(http://www)\.([[:alnum:]+\.([[:alnum:]]+)". $url, 
      $regs);</P>
      <P>if ($www_url) : // Если переменная $www_url содержит URL</P>
      <P>echo $regs[0]; // Вся строка "http://www.apress.com"</P>
      <P>print "&lt;br&gt;";</P>
      <P>echo $regs[l]; // "http://www"</P>
      <P>print "&lt;br&gt;";</P>
      <P>echo $regs[2]; // "apress"</P>
      <P>print "&lt;br&gt;";</P>
      <P>echo $regs[3]; // "com" endif;</P>
      <P>При выполнении сценария в листинге 8.1 будет получен следующий 
      результат:</P>
      <P>http://www.apress.com http://www apress com</P>
      <P>ereg_replace( )</P>
      <P>Функция ereg_replace( ) ищет в заданной строке совпадение для шаблона и 
      заменяет его новым фрагментом. Синтаксис функции ereg_replace( ):</P>
      <P>string ereg_replace (string шаблон, string замена, string строке)</P>
      <P>Функция ereg_replace( ) работает по тому же принципу, что и ereg( ), но 
      ее возможности расширены от простого поиска до поиска с заменой. После 
      выполнения замены функция возвращает модифицированную строку. Если 
      совпадения</P>
      <P>отсутствуют, строка остается в прежнем состоянии. Функция ereg_replace( 
      ), как и еrеg( ), учитывает регистр символов. Ниже приведен простой 
      пример, демонстрирующий применение этой функции:</P>
      <P>$copy_date = "Copyright 1999":</P>
      <P>$copy_date = ereg_replace("([0-9]+)". "2000", $copy_date);</P>
      <P>print $copy_date: // Выводится строка "Copyright 2000"</P>
      <P>У средств поиска с заменой в языке РНР имеется одна интересная 
      возможность — возможность использования обратных ссылок на части основного 
      выражения, заключенные в круглые скобки. Обратные ссылки похожи на 
      элементы необязательного параметра-массива совпадения функции еrеg( ) за 
      одним исключением: обратные ссылки записываются в виде \0, \1, \2 и т. д., 
      где \0 соответствует всей строке, \1 — успешному совпадению первого 
      подвыражения и т. д. Выражение может содержать до 9 обратных ссылок. В 
      следующем примере все ссылки на URL в тексте заменяются работающими 
      гиперссылками:</P>
      <P>$url = "Apress (http://www.apress.com");</P>
      <P>$url = ereg_replace("http://(([A-Za-z0-9.\-])*)", "&lt;a 
      href=\"\\0\"&gt;\\0&lt;/a&gt;", $url);</P>
      <P>print $url;</P>
      <P>// Выводится строка:</P>
      <P>// Apress (&lt;a 
      href="http.html://www.apress.com"&gt;http://www.apress.com&lt;/a&gt;)</P>
      <P>eregi( )</P>
      <P>Функция eregi( ) ищет в заданной строке совпадение для шаблона. 
      Синтаксис функции eregi( ):</P>
      <P>int eregi (string шаблон, string строка [, array совпадения])</P>
      <P>Поиск производится без учета регистра алфавитных символов. Функция 
      eregi( ) особенно удобна при проверке правильности введенных строк 
      (например, паролей). Использование функции eregi( ) продемонстрировано в 
      следующем примере:</P>
      <P>$password = "abc";</P>
      <P>if (! eregi("[[:alnum:]]{8.10}, $password) :</P>
      <P>print "Invalid password! Passwords must be from 8 through 10 characters 
      in length.";</P>
      <P>endif;</P>
      <P>// В результате выполнения этого фрагмента выводится сообщение об 
      ошибке.</P>
      <P>// поскольку длина строки "abc" не входит в разрешенный интервал</P>
      <P>// от 8 до 10 символов.</P>
      <P>eregi_replace( )</P>
      <P>Функция eregi_replасе( ) работает точно так же, как ereg_replace( ), за 
      одним исключением: поиск производится без учета регистра символов. 
      Синтаксис функции ereg_replace( ):</P>
      <P>string eregi_replace (string шаблон, string замена, string строка)</P>
      <P>split( )</P>
      <P>Функция split( ) разбивает строку на элементы, границы которых 
      определяются по заданному шаблону. Синтаксис функции split( ):</P>
      <P>array split (string шаблон, string строка [, int порог])</P>
      <P>Необязательный параметр порог определяет максимальное количество 
      элементов, на которые делится строка слева направо. Если шаблон содержит 
      алфавитные символы, функция spl it( ) работает с учетом регистра символов. 
      Следующий пример демонстрирует использование функции split( ) для 
      разбиения канонического IP-адреса на триплеты:</P>
      <P>$ip = "123.345.789.000"; // Канонический IP-адрес</P>
      <P>$iparr = split ("\.", $ip) // Поскольку точка является служебным 
      символом.</P>
      <P>// ее необходимо экранировать.</P>
      <P>print "$iparr[0] &lt;br&gt;"; // Выводит "123"</P>
      <P>print "$iparr[1] &lt;br&gt;"; // Выводит "456"</P>
      <P>print "$iparr[2] &lt;br&gt;"; // Выводит "789"</P>
      <P>print "$iparr[3] &lt;br&gt;"; // Выводит "000"</P>
      <P>spliti( )</P>
      <P>Функция spliti( ) работает точно так же, как ее прототип split( ), за 
      одним исключением: она не учитывает регистра символов. Синтаксис функции 
      spliti( ):</P>
      <P>array spliti (string шаблон, string строка [, int порог])</P>
      <P>Разумеется, регистр символов важен лишь в том случае, если шаблон 
      содержит алфавитные символы. Для других символов выполнение spliti( ) 
      полностью аналогично split( ).</P>
      <P>sql_regcase( )</P>
      <P>Вспомогательная функция sql_regcase( ) заключает каждый символ входной 
      строки в квадратные скобки и добавляет к нему парный символ. Синтаксис 
      функции sql_regcase( ):</P>
      <P>string sql_regcase (string строка)</P>
      <P>Если алфавитный символ существует в двух вариантах (верхний и нижний 
      регистры), выражение в квадратных скобках будет содержать оба варианта; в 
      противном случае исходный символ повторяется дважды. Функция sql_regcase( 
      ) особенно удобна при использовании РНР с программными пакетами, 
      поддерживающими регулярные выражения в одном регистре. Пример 
      преобразования строки функцией sql_regcase( ):</P>
      <P>$version = "php 4.0";</P>
      <P>print sql_regcase($version);</P>
      <P>// Выводится строка [Pp][Hh][Pp][ ][44][..][00]</P>
      <P><A name=e></A>Синтаксис регулярных выражений в стиле Perl</P>
      <P>Perl (<A href="http.html://www.perl.com/">http://www.perl.com/</A>) давно 
      считается одним из самых лучших языков обработки текстов. Синтаксис Perl 
      позволяет осуществлять поиск и замену даже для самых сложных шаблонов. 
      Разработчики РHР сочли, что не стоит заново изобретать уже изобретенное, а 
      лучше сделать знаменитый синтаксис регулярных выражений Perl доступным для 
      пользователей РНР. Так появились функции для работы с регулярными 
      выражениями в стиле Perl.</P>
      <P>Диалект регулярных выражений Perl не так уж сильно отличается от 
      диалекта POSIX. В сущности, синтаксис регулярных выражений Perl является 
      отдаленным потомком реализации POSIX, вследствие чего синтаксис POSIX 
      почти совместим с функциями регулярных выражений стиля Perl.</P>
      <P>Оставшаяся часть этого раздела будет посвящена краткому знакомству с 
      диалектом регулярных выражений Perl. Рассмотрим простой пример:</P>
      <P>/food/</P>
      <P>Обратите внимание: строка food заключена между двумя косыми чертами. 
      Как и в стандарте POSIX, вы можете создавать более сложные шаблоны при 
      помощи квантификаторов:</P>
      <P>/fo+/</P>
      <P>Этот шаблон совпадает с последовательностью fo, за которой могут 
      следовать дополнительные символы о. Например, совпадения будут обнаружены 
      в строках food, fool и fo4. Рассмотрим другой пример использования 
      квантификатора:</P>
      <P>/fo{2,4}/</P>
      <P>Шаблон совпадает с символом f, за которым следуют от 2 до 4 экземпляров 
      символа о. К числу потенциальных совпадений относятся строки fool , fooool 
      и foosball .</P>
      <P>В регулярных выражениях Perl могут использоваться все квантификаторы, 
      упомянутые в предыдущем разделе для регулярных выражений POSIX.</P>
      <P><A name=f></A>Метасимволы</P>
      <P>Одной из интересных особенностей Perl является использование 
      метасимволов при поиске. Метасимвол [Следует отметить, что авторское 
      толкование термина «метасимвол» противоречит не только всем традициям, по 
      и официальной документации РНР. — Примеч. перев.] представляет собой 
      алфавитный символ с префиксом \ — признаком особой интерпретации 
      следующего символа. Например, метасимвол \d может использоваться при 
      поиске денежных сумм:</P>
      <P>/([d]+)000/</P>
      <P>Комбинация \d обозначает любую цифру. Конечно, в процессе поиска часто 
      возникает задача идентификации алфавитно-цифровых символов, поэтому в Perl 
      для них был определен метасимвол \w:</P>
      <P>/&lt;([\w]+)&gt;/</P>
      <P>Этот шаблон совпадает с конструкциями, заключенными в угловые скобки, — 
      например, тёгами HTML. Кстати, метасимвол \W имеет прямо противоположный 
      смысл и используется для идентификации символов, не являющихся 
      алфавитно-цифровыми.</P>
      <P>Еще один полезный метасимвол, \b, совпадает с границами слов:</P>
      <P>/sa\b/</P>
      <P>Поскольку метасимвол границы слова расположен справа от текста, этот 
      шаблон совпадет в строках salsa и lisa, но не в строке sand. 
      Противоположный метасимвол, \В, совпадает с чем угодно, кроме границы 
      слова:</P>
      <P>/sa\B/</P>
      <P>Шаблон совпадает в таких строках, как sand и Sally, но не совпадает в 
      строке salsa.</P>
      <P><A name=g></A>Модификаторы</P>
      <P>Модификаторы заметно упрощают работу с регулярными выражениями. 
      Впрочем, модификаторов много, и в табл. 8.1 приведены лишь наиболее 
      интересные из них. Модификаторы перечисляются сразу же после регулярного 
      выражения — например, /string/i.</P>
      <P>Таблица 8.1. Примеры модификаторов</P>
      <TABLE cellSpacing=0 cellPadding=0 width="100%" border=1>
        <TBODY>
        <TR>
          <TD align=middle width=100>
            <P align=left>Модификатор</P></TD>
          <TD align=middle width=351>
            <P align=left>Описание</P></TD></TR>
        <TR>
          <TD align=middle width=150>m</TD>
          <TD width=351>Фрагмент текста интерпретируется как состоящий из 
            нескольких «логических строк». По умолчанию специальные символы ^ и 
            $ совпадают только в начале и в конце всего фрагмента. При включении 
            «многострочного режима» при помощи модификатора m^ и $ будут 
            совпадать в начале и в конце каждой логической строки внутри 
            фрагмента</TD></TR>
        <TR>
          <TD align=middle width=143>s</TD>
          <TD width=351>По смыслу противоположен модификатору m — при поиске 
            фрагмент интерпретируется как одна строка, а все внутренние символы 
            новой строки игнорируются</TD></TR>
        <TR>
          <TD align=middle width=143>i</TD>
          <TD width=351>Поиск выполняется без учета регистра 
        символов</TD></TR></TBODY></TABLE>
      <P>Вводный курс получился очень кратким, поскольку полноценное описание по 
      регулярным выражениям выходит за рамки этой книги и требует нескольких 
      глав вместо нескольких страниц. За дополнительной информацией о синтаксисе 
      регулярных выражений обращайтесь к следующим ресурсам Интернета:</P>
      <UL>
        <LI><A 
        href="http.html://www.php.net/manual/pcre.pattern.modifiers.php">http://www.php.net/manual/pcre.pattern.modifiers.php</A>; 

        <LI><A 
        href="http.html://www.php.net/manual/pcre.pattern.syntax.php">http://www.php.net/manual/pcre.pattern.syntax.php</A>; 

        <LI><A 
        href="http.html://www.perlcom/pub/doc/manual/html/pod/perlre.html">http://www.perlcom/pub/doc/manual/html/pod/perlre.html</A>; 

        <LI><A 
        href="http.html://www.codebits.com/p5be">http://www.codebits.com/p5be</A>; 
        <LI><A 
        href="http.html://www.metronet.com/1/perlinfo/doc/FMTEYEWTK/regexps.html">http://www.metronet.com/1/perlinfo/doc/FMTEYEWTK/regexps.html</A>. 
        </LI></UL>
      <P><A href="http.html://doks.gorodok.net/996" name=h></A>Функции РНР для работы 
      с регулярными выражениями (Perl-совместимые)</P>
      <P>В РНР существует пять функций поиска по шаблону с использованием 
      Perl-совместимых регулярных выражений:</P>
      <UL>
        <LI>preg_match( ); 
        <LI>preg_match_all( ); 
        <LI>preg_replace( ); 
        <LI>preg_split( ); 
        <LI>preg_grep( ). </LI></UL>
      <P>Эти функции подробно описаны в следующих разделах.</P>
      <P>preg_match( )</P>
      <P>Функция pregjnatch( ) ищет в заданной строке совпадение для шаблона. 
      Если совпадение найдено, возвращается TRUE, в противном случае 
      возвращается FALSE. Синтаксис функции pregjnatch( ):</P>
      <P>int pregjnatch (string шаблон, string строка [, array совпадения})</P>
      <P>При передаче необязательного параметра совпадения массив заполняется 
      совпадениями различных подвыражений, входящих в основное регулярное 
      выражение. В следующем примере функция preg_match( ) используется для 
      проведения поиска без учета регистра:</P>
      <P>$linе = "Vi is the greatest word processor ever created!";</P>
      <P>// Выполнить поиск слова "Vi" без учета регистра символов:</P>
      <P>if (preg_match("/\bVi\b\i", $line, $matcn)) :</P>
      <P>print "Match found!";</P>
      <P>endif;</P>
      <P>// Команда if в этом примере возвращает TRUE</P>
      <P>preg_match_all( )</P>
      <P>Функция preg_match_all( ) находит все совпадения шаблона в заданной 
      строке.</P>
      <P>Синтаксис функции preg_match_all( ):</P>
      <P>Int preg_match_all (string шаблон, string строка, array совпадения [, 
      int порядок])</P>
      <P>Порядок сохранения в массиве совпадения текста, совпавшего с 
      подвыражениями, определяется необязательным параметром порядок. Этот 
      параметр может принимать два значения:</P>
      <UL>
        <LI>PREG_PATTERN_ORDER — используется по умолчанию, если параметр 
        порядок не указан. Порядок, определяемый значением PREG_PATTERN_ORDER, 
        на первый взгляд выглядит не совсем логично: первый элемент (с индексом 
        0) содержит массив совпадений для всего регулярного выражения, второй 
        элемент (с индексом 1) содержит массив всех совпадений для первого 
        подвыражения в круглых скобках и т. д.; 
        <LI>PREG_SET_ORDER — порядок сортировки массива несколько отличается от 
        принятого по умолчанию. Первый элемент (с индексом 0) содержит массив с 
        текстом, совпавшим со всеми подвыражениями в круглых скобках для первого 
        найденного совпадения. Второй элемент (с индексом 1) содержит 
        аналогичный массив для второго найденного совпадения и т. д. </LI></UL>
      <P>Следующий пример показывает, как при помощи функции preg_match_al( ) 
      найти весь текст, заключенный между тегами HTML 
&lt;b&gt;...&lt;/b&gt;:</P>
      <P>$user_info = "Name: &lt;b&gt;Rasmus Lerdorf&lt;/b&gt; &lt;br&gt; Title: 
      &lt;b&gt;PHP Guru&lt;/b&gt;";</P>
      <P>preg_match_all ("/&lt;b&gt;(.*)&lt;\/b&gt;/U", Suserinfo. 
      $pat_array);</P>
      <P>print $pat_array[0][0]." &lt;br&gt; ".pat_array[0][l]."\n":</P>
      <P>Результат:</P>
      <P>Rasmus Lerdorf</P>
      <P>PHP Guru</P>
      <P>preg_replace( )</P>
      <P>Функция preg_repl ace( ) работает точно так же, как и ereg_replасе( ), 
      за одним исключением — регулярные выражения могут использоваться в обоих 
      параметрах, шаблон и замена. Синтаксис функции preg_replace( ):</P>
      <P>mixed preg_replace (mixed шаблон, mixed замена, mixed строка [, int 
      порог])</P>
      <P>Необязательный параметр порог определяет максимальное количество замен 
      в строке. Интересный факт: параметры шаблон и замена могут представлять 
      собой масивы. Функция preg_replace( ) перебирает элементы обоих массивов и 
      выполняет замену по мере их нахождения.</P>
      <P>preg_split( )</P>
      <P>Функция preg_spl it( ) аналогична split( ) за одним исключением — 
      параметр шаблон может содержать регулярное выражение. Синтаксис функции 
      preg_split( ):</P>
      <P>array preg_split (string шаблон, string строка [, int порог [, int 
      флаги]]) </P>
      <P>Необязательный параметр порог определяет максимальное количество 
      элементов, на которые делится строка. В следующем примере функция 
      preg_split( ) используется для выборки информации из переменной.</P>
      <P>$user_info="+wj+++Gilmore+++++wjgi]more@hotmail.com</P>
      <P>+++++++Columbus+++OH";</P>
      <P>$fields = preg_split("/\+{1.}/", $user_info);&nbsp;</P>
      <P>while ($x &lt; sizeof($fields)):</P>
      <P>print $fields[$x]. "&lt;br&gt;";</P>
      <P>$x++;</P>
      <P>endwhile;</P>
      <P>Результат:</P>
      <P>WJ</P>
      <P>Gilmore</P>
      <P>wjgilmore@hotmail.com</P>
      <P>Columbus</P>
      <P>OH</P>
      <P>preg_grep( )</P>
      <P>Функция preg_grep( ) перебирает все элементы заданного массива и 
      возвращает все элементы, в которых совпадает заданное регулярное 
      выражение. Синтаксис функции preg_grep():</P>
      <P>array preg_grep (string шаблон, array массив)</P>
      <P>Пример использования функции preg_grep( ) для поиска в массиве слов, 
      начинающихся на р:</P>
      <P>$foods = array ("pasta", "steak", "fish", "potatoes");</P>
      <P>// Поиск элементов, начинающихся с символа "р".</P>
      <P>// за которым следует один или несколько символов</P>
      <P>$p_foods = preg_grep("/p(\w+)/", $foods):</P>
      <P>$х = 0;</P>
      <P>while ($x &lt; sizeof($p_foods)) :</P>
      <P>print $p_foods[$x]. "&lt;br&gt;";</P>
      <P>$Х++;</P>
      <P>endwhile;</P>
      <P>Результат:</P>
      <P>pasta</P>
      <P>potatoes</P>
      <P><A name=i></A>Другие строковые функции</P>
      <P>Кроме функций для работы с регулярными выражениями, описанными в первой 
      части этой главы, в РНР существует более 70 функций для выполнения 
      практически всех мыслимых операций со строками. Подробное перечисление и 
      описание всех функций выходит за рамки этой книги и приведет к обычному 
      повторению информации, приведенной в документации РНР. По этой причине я 
      превратил оставшуюся часть главы в своего рода список FAQ из вопросов, 
      часто встречающихся во многих электронных конференциях РНР и на многих 
      сайтах этой тематики. На мой взгляд, этот способ позволяет гораздо 
      эффективнее описать общие принципы громадной библиотеки строковых функций 
      РНР.</P>
      <P><A name=j></A>Дополнение и сжатие строк</P>
      <P>В процессе форматирования часто возникает необходимость в изменении 
      длины строки посредством дополнения или удаления символов. В РНР 
      существует несколько функций, предназначенных для решения этой задачи.</P>
      <P>chop ( )</P>
      <P>Функция chop( ) возвращает строку после удаления из нее завершающих 
      пропусков и символов новой строки. Синтаксис функции chop( ): </P>
      <P>string chop(string строка)</P>
      <P>В следующем примере функция chop( ) удаляет лишние символы новой 
      строки:</P>
      <P>$header = "Table of Contents\n\n";</P>
      <P>$header = chop($header);</P>
      <P>// $header = "Table of Contents"</P>
      <P>str_pad( )</P>
      <P>Функция str_pad( ) выравнивает строку до определенной длины заданными 
      символами и возвращает отформатированную строку. Синтаксис функции 
      str_pad( ):</P>
      <P>string str_pad (string строка, int длина_дополнения [, string 
      дополнение [, int тип_дополнения]])</P>
      <P>Если необязательный параметр дополнение не указан, строка дополняется 
      пробелами. В противном случае строка дополняется заданными символами. По 
      умолчанию строка дополняется справа; тем не менее, вы можете передать в 
      параметре тип_дополнения константу STR_PAD_RIGHT, STR_PAD_LEFT или 
      STR_PAD_BOTH, что приведет к дополнению строки в заданном направлении. 
      Пример демонстрирует дополнение строки функцией str_pad( ) с параметрами 
      по умолчанию:</P>
      <P>$food = "salad";</P>
      <P>print str_pad ($food, 5): // Выводит строку "salad</P>
      <P>В следующем примере используются необязательные параметры функции 
      str_pad( ):</P>
      <P>$header = "Table of Contents";</P>
      <P>print str_pad ($header, 5, "=+=+=", STR_PAD_BOTH);</P>
      <P>// В браузере выводится строка =+=+= Таbе of Contents=+=+="</P>
      <P>trim ( )</P>
      <P>Функция trim( ) удаляет псе пропуски с обоих краев строки и возвращает 
      полученную строку. Синтаксис функции trim( ):</P>
      <P>string trim (string страна] </P>
      <P>К числу удаляемых пропусков относятся и специальные символы \n, \r, \t, 
      \v и \0.</P>
      <P>ltrim( )</P>
      <P>Функция lrim( ) удаляет все пропуски и специальные символы с левого 
      края строки и возвращает полученную строку. Синтаксис функции ltrim( 
):</P>
      <P>string ltrim (string строка)</P>
      <P>Функция удаляет те же специальные символы, что и функция trim( ).</P>
      <P><A name=k></A>Определение длины строки</P>
      <P>Длину строки в символах можно определить при помощи функции strlen( ). 
      Синтаксис .функции strlen( ):</P>
      <P>int strlen (string строка)</P>
      <P>Следующий пример демонстрирует определение длины строки функцией 
      strlen( ):</P>
      <P>$string = "hello";</P>
      <P>$length = strlen($string);</P>
      <P>// $length = 5</P>
      <P><A name=l></A>Сравнение двух строк</P>
      <P>Сравнение двух строк принадлежит к числу важнейших строковых операций 
      любого языка. Хотя эту задачу можно решить несколькими разными способами, 
      в РНР существуют четыре функции сравнения строк:</P>
      <UL>
        <LI>strcmp( ); 
        <LI>strcasecmp( ); 
        <LI>strspn( ); 
        <LI>strcspn( ). </LI></UL>
      <P>Все эти функции подробно описаны в следующих разделах.</P>
      <P>strcmp( )</P>
      <P>Функция strcmp( ) сравнивает две строки с учетом регистра символов. 
      Синтаксис функции strcmp( ):</P>
      <P>int strcmp (string строка1, string строка2) </P>
      <P>После завершения сравнения strcmp( ) возвращает одно из трех возможных 
      значений:</P>
      <UL>
        <LI>0, если строка1 и строка2 совпадают; 
        <LI>&lt; 0, если строка1 меньше, чем строка2; 
        <LI>&gt; 0, если строка2 меньше, чем строка1. </LI></UL>
      <P>В следующем фрагменте сравниваются две одинаковые строки:</P>
      <P>$sthng1 = "butter";</P>
      <P>$string2 = "butter";</P>
      <P>if ((strcmp($string1. $string2)) == 0) :</P>
      <P>print "Strings are equivalent!"; endif;</P>
      <P>// Команда if возвращает TRUE</P>
      <P>strcasecmp( )</P>
      <P>Функция strcasecmp( ) работает точно так же, как strcmp( ), за одним 
      исключением — регистр символов при сравнении не учитывается. Синтаксис 
      функции strcasecmp( ):</P>
      <P>int strcasecmp (string cтpoкa1, string строка2)</P>
      <P>В следующем фрагменте сравниваются две одинаковые строки:</P>
      <P>$string1 = "butter";</P>
      <P>$string2 = "Butter";</P>
      <P>if ((strcmp($string1, $string2)) == 0) :</P>
      <P>print "Strings are equivalent!";</P>
      <P>endif;</P>
      <P>// Команда if возвращает TRUE</P>
      <P>strspn( )</P>
      <P>Функция strspn( ) возвращает длину первого сегмента строки1, 
      содержащего символы, присутствующие в строке2. Синтаксис функции strspn( 
      ):</P>
      <P>int strspn (string строка1, string строка2)</P>
      <P>Следующий фрагмент показывает, как функция strspn( ) используется для 
      проверки пароля:</P>
      <P>$password = "12345";</P>
      <P>if (strspn($password, "1234567890") != strlen($password)) :</P>
      <P>print "Password cannot consist solely of numbers!";</P>
      <P>endif:</P>
      <P>strcspn( )</P>
      <P>Функция strcspn( ) возвращает длину первого сегмента строки1, 
      содержащего символы, отсутствующие в строке2. Синтаксис функции strcspn( 
      ):</P>
      <P>int strcspn (string строка1, string строка2)</P>
      <P>В следующем фрагменте функция strcspn( ) используется для проверки 
      пароля:</P>
      <P>$password = "12345";</P>
      <P>if (strcspn($password, "1234567890") == 0) :</P>
      <P>print "Password cannot consist solely of numbers!";</P>
      <P>endif;</P>
      <P><A name=m></A>Обработка строковых данных без применения регулярных 
      выражений</P>
      <P>При обработке больших объемов информации функции регулярных выражений 
      сильно замедляют выполнение программы. Эти функции следует применять лишь 
      при обработке относительно сложных строк, в которых регулярные выражения 
      действительно необходимы. Если же анализ текста выполняется по 
      относительно простым правилам, можно воспользоваться стандартными 
      функциями РНР, которые заметно ускоряют обработку. Все эти функции описаны 
      ниже.</P>
      <P>strtok( )</P>
      <P>Функция strtok( ) разбивает строку на лексемы по разделителям, заданным 
      вторым параметром. Синтаксис функции strtok( ):</P>
      <P>string strtok (string строка, string разделители) </P>
      <P>У функции strtok( ) есть одна странность: чтобы полностью разделить 
      строку, функцию необходимо последовательно вызвать несколько раз. При 
      очередном вызове функция выделяет из строки следующую лексему. При этом 
      параметр строка задается всего один раз — функция отслеживает текущую 
      позицию в строке до тех пор, пока строка не будет полностью разобрана на 
      лексемы или не будет задан новый параметр строка. Следующий пример 
      демонстрирует разбиение строки по нескольким разделителям:</P>
      <P>$info = "WJ Gi1more:wjgilmore@hotmail.com | Columbus, Ohio";</P>
      <P>// Ограничители - двоеточие (:), вертикальная черта (|) и запятая (.) 
      $tokens = ":|,";</P>
      <P>$tokenized = strtok($info, $tokens);</P>
      <P>// Вывести элементы массива $tokenized</P>
      <P>while ($tokenized) :</P>
      <P>echo "Element = $tokenized&lt;br&gt;";</P>
      <P>// Обратите внимание: при последующих вызовах strtok</P>
      <P>// первый аргумент не передается</P>
      <P>$tokenized = strtok($tokens);</P>
      <P>endwhile;</P>
      <P>Результат:</P>
      <P>Element = WJGilmore</P>
      <P>Element = wjgilmore@hotmail.com</P>
      <P>Element = Columbus</P>
      <P>Element = Ohio</P>
      <P>parse_str( )</P>
      <P>Функция parse_str( ) выделяет в строке пары «переменная-значение» и 
      присваивает значения переменных в текущей области видимости. Синтаксис 
      функции parse_str( ):</P>
      <P>void parse_str (string строка)</P>
      <P>Функция parse_str( ) особенно удобна при обработке URL, содержащих 
      данные форм HTML или другую расширенную информацию. В следующем примере 
      анализируется информация, переданная через URL. Строка представляет собой 
      стандартный способ передачи данных между страницами либо откомпилированных 
      в гиперссылке, либо введенных в форму HTML:</P>
      <P>$url = "fname=wj&amp;lname=gilmore&amp;zip=43210";</P>
      <P>parse_str($url);</P>
      <P>// После выполнения parse_str( ) доступны следующие переменные:</P>
      <P>// $fname = "wj":</P>
      <P>// $lname = "gilmore";</P>
      <P>// $zip = "43210"</P>
      <P>Поскольку эта функция создавалась для работы с URL, она игнорирует 
      символ амперсанд (&amp;).</P>
      <P>Работа 
      с формами HTML в РНР описана в главе 10. </P>
      <P>&nbsp;</P>
      <P>explode ( )</P>
      <P>Функция explode( ) делит строку на элементы и возвращает эти элементы в 
      виде массива. Синтаксис функции explode( ):</P>
      <P>array explode (string разделитель, string строка [, int порог])</P>
      <P>Разбиение происходит по каждому экземпляру разделителя, причем 
      количество полученных фрагментов может ограничиваться необязательным 
      параметром порог. Разделение строки функцией explode( ) продемонстрировано 
      в следующем примере:</P>
      <P>$info = "wilson | baseball | indians";</P>
      <P>$user = explode("|", $info);</P>
      <P>// $user[0] = "wilson";</P>
      <P>// $user[1] = "baseball";</P>
      <P>// $user[2] = "Indians";</P>
      <P>Функция 
      explode( ) практически идентична функции регулярных выражений POSIX split( 
      ), описанной выше. Главное различие заключается в том, что передача 
      регулярных выражений в параметрах допускается только при вызове split( 
      ).</P>
      <P>implode ( )</P>
      <P>Если функция explode( ) разделяет строку на элементы массива, то ее 
      двойник — функция implode( ) - объединяет массив в строку. Синтаксис 
      функции implode( ):</P>
      <P>string implode (string разделитель, array фрагменты)</P>
      <P>Формирование строки из массива продемонстрировано в следующем 
      примере:</P>
      <P>$ohio_cities = array ("Columbus", "Youngstown", "Cleveland", 
      "Cincinnati");</P>
      <P>$city_string = implode("l", $ohio_cities);</P>
      <P>// $city_string = "Columbus | Youngstown | Cleveland | Cincinnati";</P>
      <P>У 
      implode( ) имеется псевдоним — функция join( ). </P>
      <P>&nbsp;strpos ( )</P>
      <P>Функция strpos( ) находит в строке первый экземпляр заданной подстроки. 
      Синтаксис функции strpos( ):</P>
      <P>int strpos (string строка, string подстрока [, int смещение])</P>
      <P>Необязательный параметр offset задает позицию, с которой должен 
      начинаться поиск. Если подстрока не найдена, strpos( ) возвращает FALSE 
      (0).</P>
      <P>В следующем примере определяется позиция первого вхождения даты в файл 
      журнала:</P>
      <P>$log = "</P>
      <P>206.169.23.11:/www/:2000-08-10</P>
      <P>206.169.23.11:/www/logs/:2000-02-04</P>
      <P>206.169.23.11:/www/img/:1999-01-31";</P>
      <P>// В какой позиции в журнале впервые встречается 1999 год?</P>
      <P>$pos = strpos($log, "1999");</P>
      <P>// $pos = 95. поскольку первый экземпляр "1999"</P>
      <P>// находится в позиции 95 строки, содержащейся в переменной $log</P>
      <P>strrpos( )</P>
      <P>Функция strrpos( ) находит в строке последний экземпляр заданного 
      символа. Синтаксис функции strrpos( ):</P>
      <P>int strpos (string строка, char символ)</P>
      <P>По возможностям эта функция уступает своему двойнику — функции strpos( 
      ), поскольку она позволяет искать только отдельный символ, а не всю 
      строку. Если во втором параметре strrpos( ) передается строка, при поиске 
      будет использован только ее первый символ.</P>
      <P>str_replace( )</P>
      <P>Функция str_replace( ) ищет в строке все вхождения заданной подстроки и 
      заменяет их новой подстрокой. Синтаксис функции str_replace( ):</P>
      <P>string str_replace (string подстрока, string замена, string строка)</P>
      <P>Функция 
      substr_replace( ), описанная ниже в этом разделе, позволяет провести заме 
      ну лишь в определенной части строки. Ниже показано, как функция 
      str_replace( ) используется для проведения глобальной замены в строке.</P>
      <P>Если подстрока ни разу не встречается в строке, исходная строка не 
      изменяется:</P>
      <P>$favorite_food = "My favorite foods are ice cream and chicken 
      wings";</P>
      <P>$favorite_food = str_replace("chicken_wings", "pizza", 
      $favohte_food);</P>
      <P>// $favorite_food = "My favorite foods are ice cream and pizza"</P>
      <P>strstr( )</P>
      <P>Функция strstr( ) возвращает часть строки, начинающуюся с первого 
      вхождения заданной подстроки. Синтаксис функции strstr( ):</P>
      <P>string strstr (string строка, string подстрока)</P>
      <P>В следующем примере функция strstr( ) используется для выделения имени 
      домена из URL:</P>
      <P>$url = "http://www.apress.com"; $domain - strstr($url, ".");</P>
      <P>// $domain = ".apress.com"</P>
      <P>substr( )</P>
      <P>Функция substr( ) возвращает часть строки, начинающуюся с заданной 
      начальной позиции и имеющую заданную длину. Синтаксис функции substr( 
      ):</P>
      <P>string substr (string строка, int начало [, int длина])</P>
      <P>Если необязательный параметр длина не указан, считается, что подстрока 
      начинается с заданной начальной позиции и продолжается до конца строки. 
      При использовании этой функции необходимо учитывать четыре 
      обстоятельства:</P>
      <UL>
        <LI>если параметр начало положителен, возвращаемая подстрока начинается 
        с позиции строки с заданным номером; 
        <LI>если параметр начало отрицателен, возвращаемая подстрока начинается 
        с позиции (длина строки - начало); 
        <LI>если параметр длина положителен, в возвращаемую подстроку включаются 
        все символы от позиции начало до позиции начало+длина. Если последняя 
        величина превышает длину строки, возвращаются символы до конца строки; 
        <LI>если параметр длина отрицателен, возвращаемая подстрока 
        заканчивается на заданном расстоянии от конца строки. </LI></UL>
      <P>Помните 
      о том, что параметр начало определяет смещение от первого символа строки; 
      таким образом, возвращаемая строка в действительности начинается с символа 
      с номером (начало + 1).</P>
      <P>Следующий пример демонстрирует выделение части строки функцией substr( 
      ):</P>
      <P>$car = "1944 Ford"; Smodel = substr($car, 6);</P>
      <P>// Smodel = "Ford"</P>
      <P>Пример с положительным параметром длина:</P>
      <P>$car = "1944 Ford";</P>
      <P>$model = substr($car, 0, 4);</P>
      <P>// $model = "1944"</P>
      <P>Пример с отрицательным параметром длина:</P>
      <P>$car = "1944 Ford";</P>
      <P>$model = substr($car, 2, -5);</P>
      <P>// $model = "44"</P>
      <P>&nbsp;substr_count( )</P>
      <P>Функция substr_count( ) возвращает количество вхождений подстроки в 
      заданную строку. Синтаксис функции substr_count( ):</P>
      <P>int substr_count (string строка, string подстрока)</P>
      <P>В следующем примере функция substr_count( ) подсчитывает количество 
      вхождений подстроки ain:</P>
      <P>$tng_twist = "The rain falls mainly on the plains of Spain";</P>
      <P>$count = substr_count($tng_twist, "ain");</P>
      <P>// $count = 4</P>
      <P>substr_replace( )</P>
      <P>Функция substr_replace( ) заменяет часть строки, которая начинается с 
      заданной позиции. Если задан необязательный параметр длина, заменяется 
      фрагмент заданной длины; в противном случае производится замена по всей 
      длине заменяющей строки. Синтаксис функции substr_replace( ):</P>
      <P>string substr_replace (string строка, string замена, int начало [, int 
      длина])</P>
      <P>Параметры начало и длина задаются по определенным правилам:</P>
      <UL>
        <LI>если параметр начало положителен, замена начинается с заданной 
        позиции; 
        <LI>если параметр начало отрицателен, замена начинается с позиции (длина 
        строки -начало); 
        <LI>если параметр длина положителен, заменяется фрагмент заданной длины; 

        <LI>если параметр длина отрицателен, замена завершается в позиции (длина 
        строки -длина). </LI></UL>
      <P>Простая замена текста функцией substr_replace( ) продемонстрирована в 
      следующем примере:</P>
      <P>$favs = " 's favorite links";</P>
      <P>$name = "Alessia";</P>
      <P>// Параметры "0, 0" означают, что заменяемый фрагмент начинается</P>
      <P>// и завершается в первой позиции строки.</P>
      <P>$favs - substr_replace($favs, $name, 0, 0);</P>
      <P>print $favs:</P>
      <P>Результат:</P>
      <P>Alessia's favorite links</P>
      <P><A name=n></A>Преобразование строк и файлов к формату HTML и 
      наоборот</P>
      <P>Преобразовать строку или целый файл к формату, подходящему для 
      просмотра в web-браузере (или наоборот), проще, чем может показаться на 
      первый взгляд. В РНР для этого существуют специальные функции.</P>
      <P>Преобразование текста в HTML</P>
      <P>Быстрое преобразование простого текста к формату web-браузера — весьма 
      распространенная задача. В ее решении вам помогут функции, описанные в 
      этом разделе.</P>
      <P>nl2br( )</P>
      <P>Функция nl2br( ) заменяет все символы новой строки (\n) эквивалентными 
      конструкциями HTML &lt;br&gt;.</P>
      <P>Синтаксис функции nl2br( ):</P>
      <P>string nl2br (string строка)</P>
      <P>Символы новой строки могут быть как видимыми (то есть явно включенными 
      в строку), так и невидимыми (например, введенными в редакторе). В 
      следующем примере текстовая строка преобразуется в формат HTML посредством 
      замены символов \n разрывами строк:</P>
      <P>// Текстовая строка, отображаемая в редакторе.</P>
      <P>$text_recipe = "</P>
      <P>Party Sauce recipe:</P>
      <P>1 can stewed tomatoes</P>
      <P>3 tablespoons fresh lemon juice</P>
      <P>Stir together, server cold.";</P>
      <P>// Преобразовать символы новой строки в &lt;br&gt;</P>
      <P>$htinl_recipe = nl2br($text_recipe)</P>
      <P>При последующем выводе $html_recipe браузеру будет передан следующий 
      текст в формате HTML:</P>
      <P>Party Sauce recipe:&lt;br&gt;</P>
      <P>1 can stewed tomatoes&lt;br&gt;</P>
      <P>3 tablespoons fresh lemon juice&lt;br&gt;</P>
      <P>Stir together, server cold.&lt;br&gt;</P>
      <P>htmlentities( )</P>
      <P>Функция htmlentities( ) преобразует символы в эквивалентные конструкции 
      HTML. Синтаксис функции htmlentities:</P>
      <P>string htmlentities (string строка)</P>
      <P>В следующем примере производится необходимая замена символов строки для 
      вывода в браузере:</P>
      <P>$user_input = "The cookbook, entitled Cafe Francaise' costs &lt; 
      $42.25.";</P>
      <P>$converted_input = htmlentities($user_input);</P>
      <P>// $converted_input = "The cookbook, entitled 'Caf&amp;egrave;</P>
      <P>// Frac&amp;ccediliaise' costs &amp;lt; 42.25.";</P>
      <P>Функция 
      htmlentities( ) в настоящее время работает только для символов кодировки 
      ISO-8559-1 (ISO-Latin-1). Кроме того, она не преобразует пробелы в 
      &amp;nbsp;, как следовало бы ожидать.</P>
      <P>htmlspecialchars( )</P>
      <P>Функция htmlspecialchars( ) заменяет некоторые символы, имеющие особый 
      смысл в контексте HTML, эквивалентными конструкциями HTML. Синтаксис 
      функции htmlspecialchars( ):</P>
      <P>string htmlspecialchars (string строка)</P>
      <P>Функция html special chars( ) в настоящее время преобразует следующие 
      символы:</P>
      <P>&amp; преобразуется в &amp;amp;; " " преобразуется в &amp;quot;;</P>
      <P>&lt; преобразуется в &amp;lt;; &gt; преобразуется в &amp;gt;.</P>
      <P>В частности, эта функция позволяет предотвратить ввод пользователями 
      разметки HTML в интерактивных web-приложениях (например, в электронных 
      форумах). Ошибки, допущенные в разметке HTML, могут привести к тому, что 
      вся страница будет формироваться неправильно. Впрочем, у этой задачи 
      существует и более эффективное решение — полностью удалить теги из строки 
      функцией strip_tags( ).</P>
      <P>Следующий пример демонстрирует удаление потенциально опасных символов 
      функцией htmlspeclalchars( ):</P>
      <P>$user_input = "I just can't get «enough» of PHP &amp; those fabulous 
      cooking recipes!";</P>
      <P>$conv_input = htmlspecialchars($user_input);</P>
      <P>// $conv_input = "I just can't &amp;lt;&amp;lt;enough&amp;gt;&amp;gt; 
      of PHP &amp;amp those fabulous cooking</P>
      <P>recipes!"</P>
      <P>Если 
      функция htmlspecialchars( ) используется в сочетании с nl2br( ), то 
      последнюю следует вызывать после htmlspecialchars( ). В противном случае 
      конструкции &lt;br&gt;, сгенерированные при вызове nl2br( ), преобразуются 
      в видимые символы. </P>
      <P>get_html_translation_table ( )</P>
      <P>Функция get_html_translation_table( ) обеспечивает удобные средства 
      преобразования текста в эквиваленты HTML Синтаксис функции 
      get_htrril_translation_table( ):</P>
      <P>string get_html_translation_table (int таблица)</P>
      <P>Функция get_html_translation_table( ) возвращает одну из двух таблиц 
      преобразования (определяется параметром таблица), используемых в работе 
      стандартных функций htmlspecialchars( ) и htmlentities( ). Возвращаемое 
      значение может использоваться в сочетании с другой стандартной функцией, 
      strtr( ) (см. далее), для преобразования текста в код HTML.</P>
      <P>Параметр таблица принимает одно из двух значений:</P>
      <UL>
        <LI>HTML_ENTITIES; 
        <LI>HTML_SPECIALCHARS. </LI></UL>
      <P>В следующем примере функция get_html_translation_table( ) используется 
      при преобразовании текста в код HTML:</P>
      <P>$string = "La pasta e il piatto piu amato in Italia";</P>
      <P>$translate = get_html_translation_table(HTML_ENTITIES);</P>
      <P>print strtr($string, $translate);</P>
      <P>// Специальные символы преобразуются в конструкции HTML</P>
      <P>// и правильно отображаются в браузере.</P>
      <P>Кстати, функция array_flip( ) позволяет провести преобразование текста 
      в HTML в обратном направлении и восстановить исходный текст. Предположим, 
      что вместо вывода результата strtr( ) в предыдущем примере мы присвоили 
      его переменной $translated string.</P>
      <P>В следующем примере исходный текст восстанавливается функцией 
      array_flip( ):</P>
      <P>$translate = array_flip($translate);</P>
      <P>$translated_string - "La pasta &amp;eacute; il piatto pi&amp;uacute; 
      amato in Italia";</P>
      <P>$original_string = strtr($translated_string, $translate);</P>
      <P>// $original_string = "La pasta e il piatto piu amato in Italia";</P>
      <P>strtr( )</P>
      <P>Функция strtr( ) транслирует строку, то есть заменяет в ней все 
      символы, входящие в строку источник, соответствующими символами строки 
      приемник. Синтаксис функции strtr( ):</P>
      <P>string strtr (string строка, string источник, string приемник)</P>
      <P>Если строки источник и приемник имеют разную длину, длинная строка 
      усекается до размеров короткой строки.</P>
      <P>Существует альтернативный синтаксис вызова strtr( ) с двумя 
      параметрами; в этом случае второй параметр содержит ассоциативный массив, 
      ключи которого соответствуют заменяемым подстрокам, а значения — 
      заменяющим подстрокам. В следующем примере теги HTML заменяются 
      XML-подобными конструкциями:</P>
      <P>$source = array("&lt;title&gt;" =&gt; "&lt;h1&gt;". "&lt;/title&gt; 
      =&gt; "&lt;/h1&gt;");</P>
      <P>$string = "&lt;h1&gt;Today In PHP-Powered News"&lt;/h1&gt;";</P>
      <P>print strtr($string, $source);</P>
      <P>// Выводится строка "&lt;title&gt;Today in PHP-Powered 
      News&lt;/title&gt;"</P>
      <P><A href="http.html://doks.gorodok.net/29003" name=o></A>Преобразование HTML 
      в простой текст</P>
      <P>Иногда возникает необходимость преобразовать файл в формате HTML в 
      простой текст. Функции, описанные ниже, помогут вам в решении этой 
      задачи.</P>
      <P>strip_tags( )</P>
      <P>Функция strip_tags( ) удаляет из строки все теги HTML и РНР, оставляя в 
      ней только текст. Синтаксис функции strip_tags( ):</P>
      <P>string strip_tags (string строка [, string разрешенные_тerи])</P>
      <P>Необязательный параметр разрешенные_теги позволяет указать теги, 
      которые должны пропускаться в процессе удаления.</P>
      <P>Ниже приведен пример удаления из строки всех тегов HTML функцией 
      strip_tags( ):</P>
      <P>$user_input = "I just &lt;b&gt;love&lt;/b&gt; РНР and 
      &lt;i&gt;gourment&lt;/i&gt; recipes!";</P>
      <P>$stripped_input = strip_tags($user_input);</P>
      <P>// $stripped_input = "I just love PHP and gourmet recipes!";</P>
      <P>В следующем примере удаляются не все, а лишь некоторые теги:</P>
      <P>$input = "I &lt;b&gt;love&lt;/b&gt; to &lt;a href = 
      \"http://www.eating.com\"&gt;eat!&lt;/a&gt;!";</P>
      <P>$strip_input = strip_tags ($user_input, "&lt;a&gt;");</P>
      <P>// $strip_input = "I love to &lt;a href = 
      \"http://www.eating.com\"&gt;eat!&lt;/a&gt;!";</P>
      <P>Удаление 
      тегов из текста также производится функцией fgetss( ), описанной в главе 
      7. </P>
      <P>&nbsp;get_meta_tags( )</P>
      <P>Хотя функция get_meta_tags( ) и не имеет прямого отношения к 
      преобразованию текста, зто весьма полезная функция, о которой следует 
      упомянуть. Синтаксис функции get_meta_tags( ):</P>
      <P>array get_meta_tags (string имя_файла/URL [, int включение_пути])</P>
      <P>Функция get_meta_tags( ) предназначена для поиска в файле HTML тегов 
      МЕТА.</P>
      <P>Теги МЕТА содержат информацию о странице, используемую главным образом 
      поисковыми системами. Эти теги находятся внутри пары тегов 
      &lt;head&gt;...&lt;/head&gt;. Применение тегов МЕТА продемонстрировано в 
      следующем фрагменте (назовем его example.html, поскольку он будет 
      использоваться в листинге 8.2):</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;PHP Recipes&lt;/title&gt;</P>
      <P>&lt;meta name="keywords" content="gourmet. PHP, food. code, recipes, 
      chef, programming, web"&gt;</P>
      <P>&lt;meta name="description" content="PHP Recipes provides savvy readers 
      with the latest in PHP</P>
      <P>programming and gourmet cuisine!"&gt;</P>
      <P>&lt;meta name="author" content="WJ Gilmore"&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>Функция get_meta_tags( ) ищет в заголовке документа теги, начинающиеся 
      словом МЕТА, и сохраняет имена тегов и их содержимое в ассоциативном 
      массиве. В листинге 8.2 продемонстрировано применение этой функции к файлу 
      example.html.</P>
      <P>Листинг 8.2. Извлечение тегов МЕТА из файла HTML функцией 
      get_meta_tags( )</P>
      <P>$meta_tags = get_meta_tags("example.html"):</P>
      <P>// Переменная $meta_tags содержит массив со следующей информацией:</P>
      <P>// $meta_tags["keywords"] = "gourmet. PHP. food. code, recipes, chef, 
      programming. Web":</P>
      <P>// $meta_tags["description"] = "PHP Recipes provides savvy readers with 
      the latest in PHP</P>
      <P>programming and gourmet cuisine";</P>
      <P>// $meta_tags["author"] = "WJ Gilmore";</P>
      <P>Интересная подробность: данные тегов МЕТА можно извлекать не только из 
      файлов, находящихся на сервере, но и из других URL.</P>
      <P>Теги 
      МЕТА и их использование превосходно описаны в статье Джо Берна (Joe Burn) 
      «So, You Want a Meta Command, Huh?» на сайте HTML Goodies: <A 
      href="http.html://htmlgoodies.earthweb.com/tutors/meta.html">http://htmlgoodies.earthweb.com/tutors/meta.html</A>.</P>
      <P><A name=p></A>Преобразование строки к верхнему и нижнему регистру</P>
      <P>В РНР существует четыре функции, предназначенных для изменения регистра 
      строки:</P>
      <UL>
        <LI>strtolower( ); 
        <LI>strtoupper( ); 
        <LI>ucfirst( ); 
        <LI>ucwords( ). </LI></UL>
      <P>Все эти функции подробно описаны ниже.</P>
      <P>strtolower( )</P>
      <P>Функция strtolower( ) преобразует все алфавитные символы строки к 
      нижнему регистру. Синтаксис функции strtolower( ):</P>
      <P>string strtolower(string строка)</P>
      <P>Неалфавитные символы функцией не изменяются. Преобразование строки к 
      нижнему регистру функцией strtolower( ) продемонстрировано в следующем 
      примере:</P>
      <P>$sentence = "COOKING and PROGRAMMING PHP are my TWO favorite 
      pastimes!";</P>
      <P>$sentence = strtolower($sentence);</P>
      <P>// После вызова функции $sentence содержит строку</P>
      <P>// "cooking and programming php are my two favorite pastimes!"</P>
      <P>strtoupper( )</P>
      <P>Строки можно преобразовывать не только к нижнему, но и к верхнему 
      регистру. Преобразование выполняется функцией strtoupper( ), имеющей 
      следующий синтаксис:</P>
      <P>string strtoupper (string строка)</P>
      <P>Неалфавитные символы функцией не изменяются. Преобразование строки к 
      верхнему регистру функцией strtoupper( ) продемонстрировано в следующем 
      примере:</P>
      <P>$sentence = "cooking and programming PHP are my two favorite 
      pastimes!";</P>
      <P>$sentence = strtoupper($sentence);</P>
      <P>// После вызова функции $sentence содержит строку</P>
      <P>// "COOKING AND PROGRAMMING PHP ARE MY TWO FAVORITE PASTIMES!"</P>
      <P>ucfirst( )</P>
      <P>Функция ucfirst( ) преобразует к верхнему регистру первый символ строки 
      — при условии, что он является алфавитным символом. Синтаксис функции 
      ucfirst( ):</P>
      <P>string ucfirst (string строка)</P>
      <P>Неалфавитные символы функцией не изменяются. Преобразование первого 
      символа строки функцией ucfirst( ) продемонстрировано в следующем 
      примере:</P>
      <P>&amp;sentence = "cooking and programming PHP are my two favorite 
      pastimes!";</P>
      <P>$sentence = ucfirst($sentence);</P>
      <P>// После вызова функции $sentence содержит строку</P>
      <P>// "Cooking and programming PHP are mу two favorite pastimes!"</P>
      <P>ucwords( )</P>
      <P>Функция ucwords( ) преобразует к верхнему регистру первую букву каждого 
      слова в строке. Синтаксис функции ucwords( ):</P>
      <P>string ucwords (string строка")</P>
      <P>Неалфавитные символы функцией не изменяются. «Слово» определяется как 
      последовательность символов, отделенная от других элементов строки 
      пробелами. В следующем примере продемонстрировано преобразование первых 
      символов слов функцией ucwords( ):</P>
      <P>$sentence = "cooking and programming PHP are my two favorite 
      pastimes!";</P>
      <P>$sentence = ucwords($sentence);</P>
      <P>// После вызова функции $sentence содержит строку</P>
      <P>// "Cooking And Programming PHP Are My Two Favorite Pastimes!"</P>
      <P><A name=q></A>Проект: идентификация браузера</P>
      <P>Каждый программист, пытающийся создать удобный web-сайт, должен 
      учитывать различия в форматировании страниц при просмотре сайта в разных 
      браузерах и операционных системах. Хотя консорциум W3 (http://www.w3.org) 
      продолжает публиковать стандарты, которых должны придерживаться 
      программисты при создании web-приложений, разработчики браузеров любят 
      дополнять эти стандарты своими маленькими «усовершенствованиями», что в 
      конечном счете вызывает хаос и путаницу. Разработчики часто решают эту 
      проблему, создавая разные страницы для каждого типа браузера и 
      операционной системы — при этом объем работы значительно увеличивается, но 
      зато итоговый сайт идеально подходит для любого пользователя. Результат — 
      хорошая репутация сайта и уверенность в том, что пользователь посетит его 
      снова.</P>
      <P>Чтобы пользователь мог просматривать страницу в формате, 
      соответствующем специфике его браузера и операционной системы, из 
      входящего запроса на получение страницы извлекается информация о браузере 
      и платформе. После получения необходимых данных пользователь 
      перенаправляется на нужную страницу.</P>
      <P>Приведенный ниже проект (sniffer.php) показывает, как использовать 
      функции РНР для работы с регулярными выражениям с целью получения 
      информации по запросам. Программа определяет тип и версию браузера и 
      операционной системы, после чего выводит полученную информацию в окне 
      браузера. Но прежде чем переходить к непосредственному анализу программы, 
      я хочу представить один из главных ее компонентов — стандартную переменную 
      РНР $HTTP_USER_AGENT. В этой переменной в строковом формате хранятся 
      различные сведения о браузере и операционной системе пользователя — именно 
      то, что нас интересует. Эту информацию можно легко вывести на экран всего 
      одной командой:</P>
      <P>&lt;?</P>
      <P>echo $HTTP USER_AGENT;</P>
      <P>?&gt;</P>
      <P>При работе в Internet Explorer 5.0 на компьютере с Windows 98 результат 
      будет выглядеть так:</P>
      <P>Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)</P>
      <P>Для Netscape Navigator 4.75 выводятся следующие данные:</P>
      <P>Mozilla/4.75 (Win98; U)</P>
      <P>Sniffer.php извлекает необходимые данные из $HTTP_USER_AGENT при помощи 
      функций обработки строк и регулярных выражений. Алгоритм программы на 
      псевдокоде:</P>
      <UL>
        <LI>Определить две функции для идентификации браузера и операционной 
        системы: browser_info( ) и opsys_info( ). Начнем с псевдокода функции 
        browser_info( ). 
        <LI>Определить тип браузера, используя функцию егед( ). Хотя эта функция 
        работает медленнее упрощенных строковых функций типа strstr( ), в данном 
        случае она удобнее, поскольку регулярное выражение позволяет определить 
        версию браузера. 
        <LI>Воспользоваться конструкцией if/elseif для идентификации следующих 
        браузеров и их версий: Internet Explorer, Opera, Netscape и браузер 
        неизвестного типа. 
        <LI>Вернуть информацию о типе и версии браузера в виде массива. 
        <LI>Функция opsys_info( ) определяет тип операционной системы. На этот 
        раз используется функция strstr( ), поскольку тип ОС определяется и без 
        применения регулярных выражений. 
        <LI>Воспользоваться конструкцией if/elseif для идентификации следующих 
        систем: Windows, Linux, UNIX, Macintosh и неизвестная операционная 
        система. 
        <LI>Вернуть информацию об операционной системе. </LI></UL>
      <P>Листинг 8.3. Идентификация типа браузера и операционной системы 
      клиента</P>
      <P></P>
      <P>&lt;?</P>
      <P>/*</P>
      <P>Файл : sniffer.php</P>
      <P>Назначение: Идентификация типа/версии браузера и платформы</P>
      <P>Автор: В. Дж. Гилмор</P>
      <P>Дата : 24 августа 2000 г.</P>
      <P>*/</P>
      <P>// Функция: browser_info</P>
      <P>// Назначение: Возвращает тип и версию браузера</P>
      <P>function browser_info ($agent) {</P>
      <P>// Определить тип браузера</P>
      <P>// Искать сигнатуру Internet Explorer</P>
      <P>if (ereg('MSIE ([0-9].[0-9]{1,2})', $agent, $version))</P>
      <P>$browse_type = "IE";</P>
      <P>$browse version = $version[1];</P>
      <P>// Искать сигнатуру Opera</P>
      <P>elseif (ereg( 'Opera ([0-9].[0-9]{1,2})'. $agent, $version)):</P>
      <P>$browse_type = "Opera":</P>
      <P>$browse_version = $version[1]:</P>
      <P>// Искать сигнатуру Netscape. Проверка браузера Netscape</P>
      <P>// *должна* выполняться после проверки Internet Explorer и Opera,</P>
      <P>// поскольку все эти браузеры любят сообщать имя</P>
      <P>// Mozilla вместе с настоящим именем.</P>
      <P>elseif (ereg( 'Mozilla/([0-9].[0-9]{1,2})'. $agent, $version)) :</P>
      <P>$browse_type = "Netscape";</P>
      <P>$browse_version = $version[1];</P>
      <P>// Если это не Internet Explorer, Opera или Netscape.</P>
      <P>// значит, мы обнаружили неизвестный браузер,</P>
      <P>else :</P>
      <P>$browse_type = "Unknown";</P>
      <P>$browse_version = "Unknown";</P>
      <P>endif:</P>
      <P>// Вернуть тип и версию браузера в виде массива</P>
      <P>return array ($browse_type, $browse_version);</P>
      <P>} // Конец функции browser_info</P>
      <P>// Функция: opsys_info</P>
      <P>// Назначение: Возвращает информацию об операционной системе 
      пользователя</P>
      <P>function opsys_info($agent) {</P>
      <P>// Идентифицировать операционную систему</P>
      <P>// Искать сигнатуру Windows</P>
      <P>if ( strstr ($agent. 'win') ) :</P>
      <P>$opsys = "windows";</P>
      <P>// Искать сигнатуру Linux</P>
      <P>elseif ( strstr($agent, 'Linux') ) :</P>
      <P>$opsys = "Linux";</P>
      <P>// Искать сигнатуру UNIX</P>
      <P>elseif ( strstr (Sagent, 'Unix') ) :</P>
      <P>$opsys = "Unix";</P>
      <P>// Искать сигнатуру Macintosh</P>
      <P>elseif ( strstr ($agent, 'Mac') ) :</P>
      <P>$opsys = "Macintosh";</P>
      <P>// Неизвестная платформа else :</P>
      <P>$opsys = "Unknown";</P>
      <P>endif;</P>
      <P>// Вернуть информацию об операционной системе</P>
      <P>return $opsys;</P>
      <P>} // Конец функции opsys_info</P>
      <P>// Сохранить возвращаемый массив в списке</P>
      <P>list ($browse_type. $browse_version) = browser_info ($HTTP_USER_AGENT); 
      Soperating_sys = opsysjnfo ($HTTP_USER_AGENT);</P>
      <P>print "Browser Type: $browse_type &lt;br&gt;";</P>
      <P>print "Browser Version: $browse_version &lt;br&gt;";</P>
      <P>print "Operating System: $operating_sys &lt;br&gt;":</P>
      <P>?&gt;</P>
      <P>Вот и все! Например, если пользователь работает в браузере Netscape 
      4.75 на компьютере с системой Windows, будет выведен следующий 
      результат:</P>
      <P>Browser Type: Netscape</P>
      <P>Browser Version: 4.75</P>
      <P>Operating System: Windows</P>
      <P>В следующей главе вы научитесь осуществлять переходы между страницами и 
      даже создавать списки стилей (style sheets) для конкретных операционной 
      системы и браузера.</P>
      <P><A name=r></A>Итоги</P>
      <P>В этой главе был изложен довольно обширный материал. Какой прок от 
      языка программирования, если в нем нельзя работать с текстом? Мы 
      рассмотрели следующие темы:</P>
      <UL>
        <LI>общие сведения о регулярных выражениях в стилях POSIX и Perl; 
        <LI>стандартные функции РНР для работы с регулярными выражениями; 
        <LI>изменение длины строки; 
        <LI>определение длины строки; 
        <LI>альтернативные функции РНР для обработки строковой информации; 
        <LI>преобразование простого текста в HTML и наоборот; 
        <LI>изменение регистра символов в строках. </LI></UL>
      <P>Следующая глава открывает вторую часть книги — кстати, мою любимую. В 
      ней мы начнем знакомиться со средствами РНР, ориентированными на Web, 
      рассмотрим процесс динамического создания содержимого, включение файлов и 
      построение общих шаблонов. В дальнейших главах части 2 рассматриваются 
      работа с формами HTML, базы данных, отслеживание данных сеанса и 
      нетривиальные средства работы с шаблонами. Держитесь — начинается самое 
      интересное!</P></LI></DIV>
<center>
[ <a href="07.php">Назад</a> | <a href="index.php">Содержание</a> | <a href="09.php">Вперед</a> ]
</center><br>
<? include_once '../../sys/inc/tfoot.php'; ?>