目次
htmlspecialchars ?
htmlspecialchars は、 PHP の文字列関係の関数のひとつで & " ' < > (アンパサンド、ダブルクオート、シングルクオート、小なり、大なり)の各文字をそれぞれ & " ' < > の文字に変換することができるようです。
HTML には、特殊文字というものがあって、 & " ' < > の各文字も、その特殊文字にあたるようです。 HTML のタグ、タグ属性値など、 HTML の構造的な部分で使用する重要な文字なので、この 5 文字を変換する関数が作られているのかもしれません。
<html> <!-- 重要な部分で < > が使用されています。 HTML の主要な部分です。 -->
<body>
<!-- 重要な部分で < > が使用されています。スタイルシートの部分です。下のスタイル設定は a タグの 1 個目を非表示にするというものです。 -->
<style>
a:nth-of-type(1) { display : none; }
</style>
<a href="https://pulogu.net/">pulogu.net</a> <!-- リンク先はさておき、重要な部分で " が使用されています。これはリンクの部分です。 href 属性の値を "" で囲んでいます。 -->
<a href="javascript:void(window.location.href='https://pulogu.net/');">pulogu.net</a> <!-- 意外な部分で ' が使用されています。リンクをクリックすると JavaScript が実行される部分です。 -->
</body>
</html>
HTML の特殊文字は他にもあるようで、以下のリンクにのっていますが、私が数えたところ、 1,500 個ほどありました。今回、変換する & " ' < > の文字は、変換する関数が準備されているくらいなので、特殊文字の中でも更に特殊な 5 文字なのでしょう。
- 8 The HTML syntax ? HTML5
- https://www.w3.org/TR/2014/REC-html5-20141028/syntax.html#named-character-references
htmlspecialchars の話しに戻りたいと思います。 htmlspecialchars で変換された & " ' < > の文字を HTML ページのソースとして入力して、ウェブブラウザで表示すると & " ' < > と表示されます。 & から ; までで 1 つの文字として解釈されて表示されるようです。
ウェブブラウザで & " ' < > と表示されるということは、元の変換前の文字に戻っています。それと、元の変換前の 1 文字から、なぜ長い文字に変換しているのか。としばらくのあいだ、変換の理由がわからないままでした。
その後、小なり、大なりの文字( < > の記号 )は HTML のタグとして使用されているので、そのままソースに書いておくと HTML のタグとして処理されてしまい、 <> 内に書く文字によっては、ウェブブラウザの表示崩れの原因になるかもしれないということを知りました。
HTML のタグとして機能しない <> の文字を書く場合は、 &○○○; 形式への変換が必要なのでした。変換する代わりに、ウェブブラウザで <> と表示されていても、 HTML タグとしては機能しないようです。
プログラム分野の用語で、特定の文字が持つ機能を無効にする処理のことを、エスケープとかサニタイズ(無害化)というらしいです。ウェブブラウザ表示用に <> をエスケープしたり、データベース保存用にシングルクオート( ' の記号 )をエスケープしたりするようです。
ここまでで話しました htmlspecialchars 関数と同じようなことを、 JavaScript の正規表現の検索と置換を使用して行うことができないかと思い、作ったのが当ページの変換フォームです。
変換フォーム
プライバシーポリシー
下記フォームの入力内容、実行結果は、当サイト管理人および外部に送信される仕組みで作成していません。ただ、何があるか分からないので、念のため、重要な情報は入力しないほうが良いと思います。
変換例
入力する文字 :
<a href="#">リンク</a> <b>太字</b> <style>a{ color : blue; }</style> <script>alert( 'メッセージ' );</script>
出力される文字 :
<a href="#">リンク</a> <b>太字</b> <style>a{ color : blue; }</style> <script>alert( 'メッセージ' );</script>
変換する特殊文字の表
特殊文字 | 変換後の文字 |
---|---|
& (アンパサンド) | & |
" (ダブルクォート) | " |
' (シングルクオート) | ' |
< (小なり) | < |
> (大なり) | > |
今回、変換した上記 5 つの文字ですが、読み方がよくわからないので、 Windows 10 のアクセサリに最初から入っていた、「文字コード表」アプリケーションで少し調べてみました。
まとめると以下の表になりました。
Unicode (ユニコード)というのがよくわかりませんが、 Excel の表で例えると、何行目の何列目はこの文字とする、と決まっている一覧表があって、そのセルのアドレス番号のようなものだと思っています。
その一覧表は、国際的な仕様として定められているようです。今回の特殊 5 文字、英語、日本語、世界の国々の文字も入っているようなので、同じ表をみていれば言語が違えど文字が正確に伝わるようです。
半角の小なり( < の記号)と、全角の小なり( < の記号)は見た目が似ていますが、 Unicode で表すと、半角の方は U+003C になり、全角の方は U+FF1C になります。
- Unicode一覧 0000-0FFF - Wikipedia
- https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF
特殊文字 | 文字コード表アプリケーションでの読み方 | Unicode |
---|---|---|
& アンパサンド | Ampersand | U+0026 |
" ダブルクオート | Quotation Mark | U+0022 |
' シングルクオート | Apostrophe | U+0027 |
< 小なり | Less Than Sign | U+003C |
> 大なり | Greater Than Sign | U+003E |
変換の理由
タグとして解釈されてしまう
例えば、ホームページ作成ソフトのビジュアル編集画面ではなく、ウィンドウズのメモ帳などのテキストエディタで HTML ページを一から手打ちで作成していたとして、その記述方法を誰かに教えたいとします。
またもや例になりますが、
「 html で文字を太字で表示したい場合は <b>太字にしたい文字</b> のように、太字にしたい文字を <b></b> タグで囲んでください。」
と説明するとします。
それでは実際にやってみます。メモ帳に以下のテキストを入力して、「 test.html 」という名前で任意の場所に保存。保存したファイルをダブルクリックしてウェブブラウザで表示してみます。
HTML のコード :
<html> <body> html で文字を太字で表示したい場合は <b>太字にしたい文字</b> のように、太字にしたい文字を <b></b> タグで囲んでください。 </body> </html>
そうすると以下のキャプチャー画像のように表示されます。
「 <b></b> タグで囲んでください。」と書きたいはずが、その部分には何も表示されず、「太字にしたい文字」は、すでに太字になってしまっています。
「 <b></b> 」が html のタグとして処理されてしまい、その機能を果たしているようです。
タグを無効に
ここで特殊文字の変換が必要になります。
先ほどの「 test.html 」をメモ帳で開いて「 <b>太字にしたい文字</b> 」と「 <b></b> タグで囲んで… 」の部分を、それぞれ「 <b>太字にしたい文字</b> 」と「 <b></b> タグで囲んで… 」に書きなおして保存。 <html> <body> は html のタグとして解釈されてほしいのでそのままにしておきます。
これを再度ウェブブラウザで表示してみます。
<html> <body> html で文字を太字で表示したい場合は <b>太字にしたい文字</b> のように、太字にしたい文字を <b></b> タグで囲んでください。 </body> </html>
すると今度は、次のキャプチャー画像のように「 <b>太字にしたい文字</b> 」「 <b></b> タグで囲んで… 」と意図した通りに表示されています。
html のタグの記述として使用されている < と > の文字を < と > に変換することで html のタグとして認識されなくなりました。
ソースコード
HTML
HTML のコードのポイントとしては、「 & を &amp; に変換します。」と書いている部分でしょうか。これをブラウザで表示すると、「 & を & に変換します。」と表示されます。これは、& を & と書くためです。
HTML のコード :
<form> <div class="form-group"> <label for="page-1554-moto">元文字列</label> <textarea id="page-1554-moto" class="form-control" rows="5" placeholder="ここに元文字列を入力します。(例)& " ' < >"></textarea> </div> <div class="form-group"> <label for="page-1554-kekka">結果文字列</label> <textarea id="page-1554-kekka" class="form-control" rows="5" placeholder="ここに結果を表示します。(例)&amp; &quot; &#039; &lt; &gt;"></textarea> </div> <div class="form-group"> <label>変換対象</label> <div class="checkbox">
<label> <input id="page-1554-amp" checked="checked" type="checkbox" /> & を &amp; に変換します。<!-- & を & に変換します。と表示されます。 --> </label> </div> <div class="checkbox"> <label> <input id="page-1554-quot" checked="checked" type="checkbox" /> " を &quot; に変換します。 </label> </div> <div class="checkbox"> <label> <input id="page-1554-039" checked="checked" type="checkbox" /> ' を &#039; に変換します。 </label> </div> <div class="checkbox"> <label> <input id="page-1554-lt" checked="checked" type="checkbox" /> < を &lt; に変換します。 </label> </div> <div class="checkbox"> <label> <input id="page-1554-gt" checked="checked" type="checkbox" /> > を &gt; に変換します。 </label> </div> </div>
<div class="form-group"> <button id="page-1554-jikkou" class="btn btn-default" type="button">実行する</button> </div>
<div class="form-group"> <button id="page-1554-sairiyou" class="btn btn-default" type="button">結果文字列を元文字列として再利用する</button> </div>
<div class="form-group"> <button id="page-1554-prekakomu" class="btn btn-default" type="button">結果文字列を <pre></pre> タグで囲む</button> </div>
</form>
JavaScript
JavaScript のコードのポイントとしては、& の置換から始めているところです。下記のコードでは、 & " ' < > の順に変換していますが、これが逆の順序になると &gt; &lt; &#039; &quot; & のように & が二重に変換されてしまいます。
JavaScript のコード :
jQuery( function( $ ){
$( "#page-1554-jikkou" ).click( function(){
var m = $( "#page-1554-moto" ).val();
if( m !== "" ){
if( $( "#page-1554-amp" ).prop( "checked" ) ) m = m.replace( /&/g , "&" ); // & の変換から始めている。
if( $( "#page-1554-quot" ).prop( "checked" ) ) m = m.replace( /"/g , """ );
if( $( "#page-1554-039" ).prop( "checked" ) ) m = m.replace( /'/g , "'" );
if( $( "#page-1554-lt" ).prop( "checked" ) ) m = m.replace( /</g , "<" );
if( $( "#page-1554-gt" ).prop( "checked" ) ) m = m.replace( />/g , ">" );
$( "#page-1554-kekka" ).val( m );
}
} );
} );
jQuery( function( $ ){
$( "#page-1554-sairiyou" ).click( function(){
$( "#page-1554-moto" ).val( $( "#page-1554-kekka" ).val() );
} );
} );
jQuery( function( $ ){
$( "#page-1554-prekakomu" ).click( function(){
$( "#page-1554-kekka" ).val( "<pre>" + $( "#page-1554-kekka" ).val() + "</pre>" );
} );
} );
参考情報
あとがき
HTML のソースコードをブログに載せるのに、 & " ' < > と表示する方法がはっきりとわかっていなくて最初時間がかかったので、その方法を最初から順を追って書いておきたいと思います。
最終的には、 & の変換を 2 回実行しないと、 & " ' < > と表示されなかったのでした。
ステップ 3 までありますがよければご覧ください。
Step 1. 本文入力と表示
例えば、下の枠取りされたエリアが Windows のメモ帳の入力画面だとします。そこに HTML のコードを入力してみます。 <body></body> 内の本文は、 & " ' < > にしました。
メモ帳に入力するコード :
<html>
<body>
& " ' < >
</body>
</html>
上のテキストを「 test2.html 」という名前で保存して、ウェブブラウザで表示してみると、以下の画像のようになります。 test2.html をダブルクリックすれば既定のブラウザで表示されると思います。
本文が入力したまま表示されていますが、ブラウザでソースを見てみると、本文として入力した < のタグが赤色の文字で表示されていて、何かの注意を表しているようです。
赤文字になったのは、今回の表示に使用したウェブブラウザ Mozilla Firefox に限っての機能かもしれませんが、注意的に見えます。
Step 2. 特殊文字 1 回目の変換と表示
次は、 & " ' < > を & " ' < > に変換したものを本文としてみます。ここが 1 回目の特殊文字変換です。
先程の test2.html をメモ帳で開いて以下のテキストに変更してみます。
メモ帳に入力するコード :
<html>
<body>
& " ' < >
</body>
</html>
test2.html を上書き保存して、ウェブブラウザで表示してみます。
今度は、 &○○○; 形式で入力した文字が 1 文字として表示されています。初回の表示と変わりがないように思いましたが、ブラウザでソースを見てみると、 < の赤文字はなくなっています。
※ & " ' < > の部分は朱色で表示されています。特殊文字を朱色で表示するようです。
ただ、 <html> の部分は赤文字になっています。これは別の何かの注意なのだと思います。
Step 3. 特殊文字 2 回目の変換と表示
ここまでで 1 回、特殊文字の変換をかけていますが、ウェブブラウザでは、 & " ' < > と表示されています。ということで、もう 1 回、 2 回目の特殊文字の変換を行ったテキストを本文として変更してみます。
1 回目の特殊文字変換で & " ' < > となっているので、 2 回目の変換では、 & " ' < > の中の & のみが該当し変換されます。 & が & に変換されます。
test2.html をメモ帳で開いて以下のテキストを入力します。
メモ帳に入力するコード :
<html>
<body>
&amp; &quot; &#039; &lt; &gt;
</body>
</html>
test2.html を上書き保存して、ウェブブラウザで表示してみます。今度の表示は少し違います。
そうすると、 & " ' < > と表示されています。
ここが少しわかりにくいところですが、メモ帳に入力した & が & と表示されています。
この時のブラウザのソースを見ると以下のようになっています。 & の部分が朱色で表示されています。この部分のみが特殊文字になっているようです。
ソースコードをソースコードのまま表示する時に、どう書けば良いのかがわからずに、時間がかかりました。
以上、閲覧ありがとうございました。
- [ Amazon.co.jp アソシエイト ] JavaScript 関係の本
- https://amzn.to/48EoeGM