Jul 20

На этот пост меня сподвигла неправильная (на мой взгляд работа fillin-фильтра в Symfony). Итак, поехали.

DOM - это мощный компонент PHP для работы с Document Object Model. Почитать о его возможностях можно здесь (php manual). Я же хочу заострить внимание на том, что это расширение, в отличии от SimpleXML, например, может работать как с HTML, так и с XML.

DomDocument - один из классов компонента DOM, который отвечает за полный XML или HTML-документ.

И вот хотелось бы поговорить и показать, как этот DomDocument работает с кодировками и символами, отличными от латиницы.

Для начала - небольшое отступление: DomDocument я создаю вот так: new DomDocument('1.0', 'UTF-8'), указывая в качестве кодировки (”The encoding of the document as part of the XML declaration.”) UTF-8, так как, судя по моему опыту - указание кодировки здесь не дает вообще ничего.

Рассказывать тут особо нечего, поэтому я приведу код и результаты, а потом их проанализирую.

Весь текст в скриптах в кодировке UTF-8.

Код класса “тестов”

class Test_DomDocument_HTML_Charset {
  protected $dom;

  protected $html =
        '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
        <html>
        <head>
          <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
          <title>Тестовая страничка</title>
        </head>
        <body>
          <p>Привет</p>
        </body>
        </html>';

  protected $html_without_charset =
        '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
        <html>
        <head>
          <title>Тестовая страничка</title>
        </head>
        <body>
          <p>Привет</p>
        </body>
        </html>';

  protected function checkTestFunction($function)
  {
    return (strpos($function, 'test') === 0);
  }

  public function execute($callback) {
    $functions = get_class_methods(get_class($this));
    $functions = array_filter($functions, array($this, 'checkTestFunction'));
    foreach($functions as $function) {
      $this->setUp();
      $result = $this->$function();
      $callback($result, $function);
      $this->tearDown();
    }
  }

  protected function setUp() {
    $this->dom = new DomDocument('1.0', 'UTF-8');
  }

  protected function tearDown() {
  }

  /**
   * Возвращает кодировку документа.
   * Используется документ, в котором не указана кодировка.
   *
   * @return string
   */
  protected function testWithoutCharset() {
    $this->dom->loadHTML($this->html_without_charset);
    return $this->dom->encoding;
  }

  /**
   * Возвращает документ, после обработки его DomDocument'ом.
   * Используется документ, в котором не указана кодировка.
   *
   * @return string
   */
  protected function testWithoutCharsetHtml() {
    $this->dom->loadHTML($this->html_without_charset);
    return $this->dom->saveHTML();
  }

  /**
   * Возвращает кодировку документа.
   * Используется документ, в котором указана кодировка.
   *
   * @return string
   */
  protected function testWithCharset() {
    $this->dom->loadHTML($this->html);
    return $this->dom->encoding;
  }

  /**
   * Возвращает документ, после обработки его DomDocument'ом.
   * Используется документ, в котором указана кодировка.
   *
   * @return string
   */
  protected function testWithCharsetHtml() {
    $this->dom->loadHTML($this->html);
    return $this->dom->saveHTML();
  }

}

Код, показывающий результаты

function echoHTMLResult($result, $function)
{
  echo "<h3>$function</h3>\n";
  echo '<pre><code>';
  if(is_string($result))
    $result = str_replace('<', '&lt;', str_replace('>', '&gt;', $result));
  var_dump($result);
  echo '</code></pre>';
}
<?php $test = new Test_DomDocument_HTML_Charset(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
  <title>Тестовая страничка</title>
</head>
<body>
<?php $test->execute('echoHTMLResult') ?>
</body>
</html>

Результаты

Выводы

Как можно понять из результатов - кодировка документа при использовании HTML определяется исключительно через тег meta, а точнее - через charset, который там указан:

<meta http-equiv="Content-type" content="text/html; charset=UTF-8">

При отсутствии указанного тега/charset’а в нём - $dom->encoding будет равен NULL (что можно с успехом использовать).

В общем-то всё, в ближайшие дни еще будет статья про кодировку в XML-документах, где всё немного интереснее.

written by FX Poster \\ tags: , , ,

Jul 18

Не думаю, что кто-то реально заинтересуется, но всё-же. Написал я где-то полгодика назад менюшку в админке в одном проекте на Symfony. После этого менюшка эта перекочевала еще в несколько проектов, тоже в бэкэнды.

Вот так она выглядит:

Менюшка

А вот и её код:

#nav, #nav * {
  margin: 0;
  padding: 0;
}

#nav {
  overflow: hidden;
  background-color: #FFFFCC;
  border: 1px solid #73B65A;
  margin: 10px 0;
  zoom: 1;
}

#nav li {
  float: left;
  display: block;
}

#nav li a {
  padding: 2px;
  margin: 0 5px;
  display: block;
  height: 100%;
  color: #000000;
  text-decoration: none;
  border-top: 3px solid #FFFFCC;
  border-bottom: 3px solid #FFFFCC;
  float: left;
}

#nav li a:hover {
  border-bottom: 3px solid #73B65A;
}
<ul id="nav">
  <li><a href="...">Гостевая книга</a></li>
  <li><a href="...">Прайс</a></li>
  <li><a href="...">Login</a></li>
</ul>

Пример.

Авось кому-нибудь пригодится.

PS. Менюха на оригинальность и инновационность не претендует!

written by FX Poster \\ tags: , ,

Mar 09

Ну вот это и произошло. :) XHTML оказался никому не нужным. Подробнее можно прочесть тут.

written by FX Poster \\ tags: