2012年01月22日

XHTML5で実体参照を使う方法

HTML5にはXHTML版の記法も用意されていて、XMLが好きな人でも書けるようになっています。が、色々見ていたら「実体参照が使えない」という問題があるようで。。

「<」(&lt;)とか「&」(&amp;)とかの実体参照はXMLの基本仕様に入ってるので問題ありませんが、「コピーライトマーク」(&copy;)や「≫」(&raquo;)、さらには空白(&nbsp;)など、追加の実体参照はXHTML5では使えません。

なにせこの辺の特殊文字はDTDに書かれてるので、外部DTDを指定しないXHTML5では構文エラーになってしまうのです。

そんなわけで、これらの文字を使いたいときは「&#169;」(コピーライトマーク)のように、エンティティコードを直接指定して書くことになります。うおお面倒くさっ!

XHTML5 移行メモ

必死の Web ハッカーへの推奨事項: &lt;、&gt;、&amp;、&quot;、&apos; を除き、名前指定による文字実体参照を使わないこと。

XML 的思索: HTML5 の XML 的な部分

実際、以下のようなXHTMLをContent-Type: application/xhtml+xmlを送りつつブラウザで見ようとするとパースエラーが発生して閲覧できません。

サンプルXHTML5
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>XHTML5 test</title>
  </head>
  <body>
    <header>
      <h1>XHTML5 test</h1>
    </header>
    <section>
      <dl>
        <dt>nbsp</dt>
        <dd>&nbsp;</dd>
        <dt>yen</dt>
        <dd>&yen;</dd>
        <dt>plusmn</dt>
        <dd>&plusmn;</dd>
        <dt>minus</dt>
        <dd>&minus;</dd>
      </dl>
    </section>
  </body>
</html>

うーむ。。yenやminusのような機種依存文字は結構使うし、困りますね。

定義がないなら自分で定義すればいいじゃない

DTDって、確か直接XML中に埋め込めたはず。ということで、必要な実体参照の定義を直接埋め込んでしまえば、パースエラーになりません

エラーにならないサンプル
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html [
<!ENTITY nbsp "&#160;">
<!ENTITY yen "&#165;">
<!ENTITY plusmn "&#177;">
<!ENTITY minus "&#8722;">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>XHTML5 test</title>
  </head>
  <body>
    <header>
      <h1>XHTML5 test</h1>
    </header>
    <section>
      <dl>
        <dt>nbsp</dt>
        <dd>&nbsp;</dd>
        <dt>yen</dt>
        <dd>&yen;</dd>
        <dt>plusmn</dt>
        <dd>&plusmn;</dd>
        <dt>minus</dt>
        <dd>&minus;</dd>
      </dl>
    </section>
  </body>
</html>

参考:6. エンティティ宣言 1 | TECHSCORE(テックスコア)

よーし、これで実体参照が使えますね。名前とコードの対応表はHTML4の定義を見るといいですよ。

Character entity references in HTML 4

本当にこれ使っていいの?

Mac版のFirefox、Opera、Chrome、Safari(いずれもstable最新)、Windows7のIE9は問題なく動いているようでした。IE8未満はそもそもContent-Type:application/xhtml+xmlを認識してくれないので仕方ないですね。IE対応は面白い話じゃないので省略。

PHPのDOMモジュールでXMLをパースしようとしたところうまく行かず。。。orz エンティティが空っぽにされてしまいました。

直接埋め込みの実体参照をちゃんと扱えるかどうかは実装によるようです。なので使っていいかというと、動作検証をきっちりやることが必要だと思います。

タグ:HTML
posted by Hiraku at 14:13 | Comment(0) | TrackBack(0) | HTML | このブログの読者になる | 更新情報をチェックする

2012年01月20日

RecursiveTreeIteratorでtreeコマンドを実装する

Qiitaに投稿した内容なんですが、もうちょい詳しく書いてみます。

treeコマンドというのは、ディレクトリの一覧をアスキーアートでわかりやすく表示してくれるコマンドです。

$ tree -d php-XML_Builder/ 
php-XML_Builder/
|-- lib
|   `-- XML
|       `-- Builder
`-- test
    `-- coverage

OSによっては標準で入っていないことがあるので、Iteratorの勉強がてら、これをPHPで実装する方法を考えてみました。

RecursiveTreeIterator

と言っても、treeコマンドのために生まれてきたようなRecursiveTreeIteratorというクラスが既にあり(PHP5.3以降)、これを使えばかなり簡単に実装できます。

■処理の流れ

  1. RecursiveDirectoryIteratorで目的のディレクトリをイテレーターにする
  2. 必要に応じてRecursiveFilterIteratorでフィルターする
  3. RecursiveTreeIteratorで再帰構造を平準化する
  4. 一重のforeachでループしながら出力する
続きを読む
タグ:iterator SPL PHP
posted by Hiraku at 00:34 | Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2012年01月08日

入れ子のArrayObjectをarrayに直す方法

またどうでもいいネタ。PHPのArrayObjectは便利なのでよく使うのですが、配列に直したいと思うことがあります。

$a = new ArrayObject(array(
  1,
  new ArrayObject(array(
    'a',
    'b'
  )),
));

//↑を
//↓みたいに変換したいなあ・・・
$a = array(
  1,
  array(
    'a',
    'b'
  ),
);

(array)でキャストしたりArrayObject::getArrayCopy()を使えばできそうに見えますが、子要素がそのままになってしまいます。

$b = (array)$a;

//キャストでは子要素がそのまま。こんな感じになっている
$b === array(
  1,
  new ArrayObject(array(
    'a',
    'b',
  )),
);

子要素も全部変換するやり方を考えてみます。

続きを読む
タグ:PHP
posted by Hiraku at 17:57 | Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2011年12月24日

PHPとgoto文 (PHP Advent Calendar 2011 24日目)

PHP Advent Calendar 2011の24日目です。 前日はbornknow108さんのPHPでIPMessangerでした。

何を書いてもいいとのことなので、PHPの黒歴史ことgoto文についてまとめてみます。

goto文とは

goto文は、プログラム中の任意の位置にジャンプする構文です。処理を先に進めたり、戻ったりすることができます。

echo 1;
goto third;
echo 2;
third:
echo 3;

//→13と表示され、2は表示されない

gotoはとても低レベルな命令であり、これとif文さえあればほとんどの論理構造は書けてしまいます。要は強力すぎるため、gotoを多用して書くと大変読みにくいプログラムができあがります。

この件はDijkstra先生の論文「Go To Statement Considered Harmful」で有名になりました。プログラマーなら誰もが一度は「gotoは有害である(使うべきではない)」というgoto有害論を聞いたことがあるのではないでしょうか。

続きを読む
タグ:PHP
posted by Hiraku at 19:01 | Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2011年12月23日

trait時代のライブラリ設計を予想してみる #php5_4

この記事はPHP5.4 Advent Calendar 2011の23日分です。

trait自体はすでに10日目の@tpyamamotoさんによるTRAITでデザインパターン再考でも取り上げられていますが、目玉機能なのでもう一回ネタにしちゃいます><

おさらい:traitとは

相変わらず公式マニュアル充実しまくっているのでそちらを見た方がいいのですが、抜粋するとこんな感じ。

  • PHP5.4の目玉機能
  • 多重継承を安全に行えるよう導入された概念
  • traitはプロパティ・メソッドを持てる
  • traitは定数を持てない
  • trait自体はインスタンス化できない
  • classを継承してtraitを作ることはできない
  • interfaceを実装してtraitを作ることはできない
  • traitを継承してtraitを作ることが可能
  • classは複数のtraitを継承して実装を再利用できる
  • traitはclassではないのでタイプヒントに使えない

traitが単なるクラスの多重継承より安全なのは、名前衝突時に別名をつけられたり、そもそもクラスと別概念なのでタイプヒントに悪影響を及ぼさなかったりといった特徴によるものです。

多重継承が解禁されたことにより、フレームワークの設計を根幹から変えてしまう可能性を秘めています。

続きを読む
タグ:PHP
posted by Hiraku at 09:51 | Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする