• ベストアンサー

文字集合範囲外の文字とパーセントエンコード

先日,以下の記事を読みました。 http://shimax.cocolog-nifty.com/search/2007/12/phphtmlspecialc_26bb.html で,以下のように書かれています。 >その際、サイト訪問者がEUCの補助漢字の大御所?「森鷗外」を入力したとします。すると、「鷗」の字は、「%26%2340407%3B」にURLエンコードされますから、それをデコードすれば、「鷗」になります。 これを当方環境で再現させることができないのです。 試しに, <?xml version="1.0" encoding="EUC-JP"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>SpecialChar TestCase 1</title> </head> <body> <p>ほげ</p> <form action="20071225-1.php" enctype="x-www-urlencode" method="post" accept-charset="UTF-8"> <p><input type="text" name="hoge" /></p> <p><input type="submit" name="fuga" /></p> </form> </body> </html> と書いたXHTMLのファイル(EUC-JP)と <?php $rawstring = $HTTP_RAW_POST_DATA; $queries = split("&",$rawstring); $queryhashtable = split("=",$queries[0]); header("Content-Type:text/plain;charset=UTF-8"); print($queryhashtable[0] . ":" . $queryhashtable[1]); ?> というファイル(UTF-8,だがBOMなしなのであまり関係ない)を作成し, XHTML側でhogeに対し鷗を入力し,送信したところ hoge:%E9%B7%97 となりました。 検証においては Windows XP SP3 RC1(v3264) Apache 2.2.6 PHP 6(200712250730) Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b3pre) Gecko/2007122905 Minefield/3.0b3pre IE 7.0.5730.11 でいずれも同じ結果になりました。 URI自体を決めるのはブラウザ側だと思うのでPHPであることは全く関係がない気もしますが,何が違うんでしょう? #ブラウザの挙動がおかしいのであれば PHPを責めるべきではないと思う。 個人的にはこのほうがうれしい挙動ですが,気になっています。 #直接ブログにコメントしないのは, >どなたか、「&」を「&amp;」に変換する意味を、実例を挙げて、しっかりと説明できる人おられますでしょうか? もし、おられたら、コメントをやさしいトーンでお願いします。 との内容からかけ離れているから聞きづらくて(汗 #accept-charset外したらMinefieldとIEに挙動の差が見られたが, #数値文字参照などにはなっていない

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

Firefox2.0 Opera9.0、IE7にて参照サイトの通りに再現しました。 XHTML1.0Trainsitional、euc-jp、UTF-8 出力はeuc-jpおよびutf-8、言語はPerlとPHPを使用。 euc-jpの場合はPerl、PHPともに%2340407から&amp;#40407;に変換され、文字化けとなりました。 utf-8では日本語は%nn%nn%nnの3バイト分で表現される為、文字化けはありませんでした。 これは、Perlやほかの言語でも問題になりますね (何も考えずに、慣例的に&を&amp;に変換してましたが、、、orz) なお、UTF-8にすることで、%E9%B7%97の出力も確認しています。 accept-charset属性にあわせてUTF-8で送信しているのもありますが、 php.iniなどで、入力文字コードをUTF-8に変換する設定とか、してませんか? PHPの出力はiso-8859-1でも十分表現できる範囲だと思いますし、 文字コードの指定を可能な限り外してみるとか、 euc-jpで統一させるとかにしてみてはいかがでしょうか。 &を&amp;に変換するのは、 Q & A と入力した時に、Q &amp; A に変換しないと、"HTMLとしてダメ"なだけですね。(念のため全角文字にて) htmlspecialcharsという名前の通り、HTMLの文法に合わせる為であって、 セキュリティーの為じゃないと思います。 > %B2%AA 鴎 ですね。BBS投稿時に文字が消えないか心配ですが。 > 参照サイト > (「IE7と補助漢字(「森鴎外」と「森鷗外」)」) 1つ目の例の「おう」の文字です。 表示可能な文字に変換してから送信しているような感じですね。

himajin100000
質問者

お礼

蛇足その1: 再現自体はできたので,解決していますが,気になったので。 >何も考えずに、慣例的に&を&amp;に変換してましたが、、、orz 今回のように,補助漢字をIEで表示させる件は地道にやるしかないかもしれませんが,個人的には,あまり手作業でやることを好みません。 ========以下,ほぼ自分のBlogのQ3480604の内容の繰り返し======= http://oshiete1.goo.ne.jp/qa3480604.html のsuzuki-_-さんのケースでは, &を実体参照にしそこねてますが,それはさておき, innerHTMLを用いています。 ソースコードがShift_JISで書かれていたら Shift_JISの文字集合外の文字を入力し,送信された場合に正しく表示されません。ソースコードがShift_JISでも数値文字参照等を用いて Unicode文字集合内の文字を表示できることから考えても好ましくは思いません。 標準にないinnerTextを使うことを嫌って 「textContentがなければ」という条件文をつけてはいますが, 私の書き方であれば,そのような文字が入力されても表示できます。 #innerTextでは文字列を渡せば改行が反映されますが,textContentではwhite-space:preがないと改行やらは入力通りにならない #suzuki-_-さんのコードとの違いの一つとして 「連続する半角空白などの空白文字類もレンダリングされるため, 教えて!gooのようにソースコードのインデントが消滅したりしない」というのもあります。 #まぁ今思えばtextContentでなく,出力先のノードのchildNodesを removeChildで全て取り除いて,document.createTextNodeしてappendChildすれば もっと短くなっただろうとは思うのだけれど。 ====================================== http://shimax.cocolog-nifty.com/search/2007/12/phphtmlspecialc_26bb.html >ただ、ここで不思議なのは、「&copy;」を入力したユーザーが本当に確認画面で「©」ではなくて、(略) RLOに関する検討を十分にしていませんが, 基本的に私個人は&copy;とそのまま表示されることを支持します。 私がQ3480604で掲示したコードもその通り動くはずです。

himajin100000
質問者

補足

php.iniについて テキストエディタでUTF-8をEUC-JPに全て置換しても再現できず。うーむ。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

回答No.7

> エラー出されることなく「#PCDATA」の部分と「CDATA」の部分が混ざっていると あー、、、 これは、「これ1つあれば完璧」な方法はないのではないでしょうか。 <p><?php echo $str; ?></p> <input type="text" value="<?php echo $str; ?>"> <textarea><?php echo $str; ?></textarea> <script>var str='<?php echo $str; ?>';</script> <pre><?php echo $str; ?></pre> どこに出力(表示)するデータなのかで改行や&などの文字の扱いも違いますし、 それに合わせて1つ1つ判断、変換していかないとダメだと思います。(めんどくさいですが) 問題になるのは、「鷗」という文字列を&amp;#40407;に変換するのか、「おう」の文字を表示するのか、とくにNGワードを考慮しての判断方法でしょうね。 > accept-charsetの「しなければならない(must)/してもよい(may)」 一番問題になるのは、今でこそOSレベルで多言語に対応していますが、そのブラウザやOSにて、その文字コードを扱えない場合でしょう。 CGI(サーバー側)が決めうちにしてしまうと、投稿文が文字化けするの必至ではないでしょうか。 (表示そのものは翻訳サイトを通じるなど、何らかの手段を講じれば可能ですし。) ひらがなの伸ばし記号(波線の「ー」)が〜に変換されるのも、これと同じ理屈なんだろうなぁ。

himajin100000
質問者

お礼

締め切った後にちょっとしたことを考えたのでメモ。 html側を us-asciiな文字だけで書き, ブラウザにus-asciiとして認識してもらうよう, meta要素でus-asciiとして宣言。 #ここではレンタルサーバ利用等でサーバの設定が変更できないという想定。・・・A #それが出来るのなら,最初からUTF-8で作ればいい。 us-ascii外の文字は全て数値文字参照で表現されるのでは? 処理を分ける必要がなくなる(笑)! #「&#x40407;という文字列を表現したい場合と 「鷗」を表現したかった場合の区別ができないのは 変わらないかも。 EUC-JPもASCII文字の部分は同じなので ファイルをEUC-JPで提出しろ、と言われてもその辺はクリア・・・かな?・・・B >こんなややこしいことを考えないためにも、EUC-JPではなくUTF-8でサイトを構築すべきであるという結論ももちろんありでしょうが、必ずしもそうできない場合もありますから というようなケースがAやBのケースしか思いつかないんだよな

himajin100000
質問者

補足

>あー、、、 これは、「これ1つあれば完璧」な方法はないのではないでしょうか。 textareaをCDATAとみなした場合 <script type="text/javascript"> //<![CDATA[ var str = document.getElementById("textarea1").value; var paragraph = document.createElement("p"); paragraph.appendChild(document.createTextNode(str)); //paragraph.textContent = str;でもOK //上の記述は,paragraphに子要素があるかないかで違うと思う。 document.getElementById("output").appendChild(paragraph); var image = document.createElement("img"); image.setAttribute("src","hoge.png"); image.setAttribute("alt","さんぷる"); image.setAttribute("title",str); document.getElementById("output").appendChild(image); //]]> </script> と同様の処理をPHP側で行い,SaveXML textareaに「<><><>""」が入力されている場合 結果予想図 <p>&lt;&gt;&lt;&gt;&lt;&gt;""</p> <img src="hoge.png" alt="さんぷる" title="&lt;&gt;&lt;&gt;&lt;&gt;&quot;&quot;" /> #この辺の変換を考えなくていいところがDOMのいいところだなあ・・・ 引数の与え方は,同じ文字列を気兼ねなく使いまわせます。 preについても同様です。一番厄介なのが,XHTMLとHTMLで扱いが違うscript要素。body要素以下にも置けるのがそれなりに厄介だ。尤もユーザーにscript要素を入力されてもValidatorでエラー通知しますけど。 >CGI(サーバー側)が決めうちにしてしまうと、 コアとなるシステムは決め打ちします。 A(コア) ← Minefield A(コア) ← B(IE用の入出力を担当し,Aのデータへと変換) ← IE みたいにして,Bで受け持つ形で作ることを望みます。 Aで自動判別したいとは全く思いません

全文を見る
すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

お知らせメールが飛び飛びにしか来てなくて、気がついたときは解決済み。 いやまあそれで問題ないんですけど。 今回の件ではこちらも勉強になりました。 質問者(himajin100000)さんとtalooさんに感謝します。 でまあ特に追加していうこともないのですが、ひとつだけ。 htmlspecialchars なんですが、これは「表示して問題ないHTMLドキュメント」にするためのものじゃなかったかと。 ちと微妙な表現ですが、これはセキュリティ云々ということではなくて、 '<', '>', '&' といったものはHTMLの見た目(など)を制御するタグに用いられる 文字なので、表示できる形として変換するためということです。 XSS等に対処するための「サニタイズ」するためのものではないと。 一次資料が見つからないので妄想入ってるかもしれませんが(^^;

himajin100000
質問者

お礼

#5補足で言いたいこと述べちゃって言うことがなくなってしまった(汗 と、とりあえず「ありがとうございました」

全文を見る
すると、全ての回答が全文表示されます。
回答No.5

> ・・・ってことはIEでのみ発生する現象であり,悪いのはそんな形式で送ってくるIEってことかな? > (であれば,一つのブラウザのバグのためにわざわざPHP側が歩み寄る義務はなく HTMLにおいては、どの文字コードで送信しなければならない、と言う規定はなかったと思いますよ。 つまり、UTF-8のフォームから、Shift_JISやeuc-jpで送信しようが、"UTF-7"で送信しようが、HTML/XHTMLとしては規格通りな訳で... もしそう言う規定があったとして、 私は、ブラウザ(やスパム投稿プログラム)が、規定通りでない方法で送ってきても、可能な限り、PHP(CGIアプリケーション)でなんとかすべきだと思います。 私は「可能な限りどんなブラウザでも」を意識してますが、 その辺は考え方がちがうので、、、IEを除外、でもいいんじゃないでしょうか。 osCommerceやwikiの派生版(らしいもの)でも、文字コードを考えていなさそうなのを見かけます。 (英語圏ではいわゆる半角文字しか使わないので、UTF-8だろうがiso-8859-1だろうが、関係ないと言うのもありますけどね。) 蛇足ですが、 -moz-opacityや_marginなどのスタイルシートでもそうですが、 W3Cの規格に合致しない実装(ブラウザ独自仕様)をバグと言うつもりはないです。 > http://shimax.cocolog-nifty.com/search/2007/12/php_f864.html > 12月31日追記部分 サニタイジングするときは、全てを非許可とした上で、許可しても良い物のみリストアップしなければなりません。(IPAだったかatmark itにも書かれています) HTMLタグで考えた場合、特定のタグのみ非許可とした場合、 作者が知らないブラウザ独自タグや新しく定義されたタグが、セキュリティー上問題であっても許可となってしまうことがあります。 htmlspecialcharsが全てのエンティティーを変換するのは、このような理由に基づくと、 www.php.netだったかに書いてありました。 また、wordpressはあえてhtmlspecialcharsを使用して、許可文字のみ再変換しています。 実態参照や数値参照のみ有効にするのであれば、 &xxx;と&#nnn;(nは数字)という並びの&のみ再変換しておけば良いのではないでしょうか? (参照サイトにもありますが、NGワードがあれば、数値参照でのNGワードのリストアップも必要になると思います) ただし、投稿者が、「&lt;」という文字列を送信し、 &amp;lt; に変換されることを期待しているのか、変換されずに < が表示されることを期待しているのか、 プログラマーはそれを判断することはできないと思います。 特にHTML関係のBBSでは、タグを説明する時に、実態参照を「そのまま」表示することを期待することが多いです。 > ANo.4お礼 $str=str_replace("¥n", "¥¥n", $str); $str=str_replace("¥"", "¥¥"", $str); $str=str_replace("'", "¥¥'", $str); $str=str_replace("¥¥", "¥¥¥¥", $str); echo "var txt='$str';"; ですかね。 HTMLでは、HTMLとしてそのままでは使えない文字をエンコードしますし、 JavaScriptやECMAScriptで文字列の中にそのままでは入れられない文字、 改行コード、クォーテーションマーク、エスケープコードだけだと思いますが、 それをエスケープさせておけばいいと思います。(¥r¥n、¥r、¥nはあらかじめ統一済み) > CGI側でBase64やパーセントエンコードした文字列にして > Ecmascriptにそのまま渡す。渡された文字列をEcmascript側でデコードする,とかいう手段。どうなんでしょうね? 何でもありなら、XMLHttpRequestを使うとか、MD5とか、、、 MD5はdel.icio.usのJSONPで、JavaScriptからCGIアプリケーションにURLを渡す時に使われています。 長文で、さらになんか元の質問からはなれてきてるような、、、失礼しました。 ご参考まで。

himajin100000
質問者

お礼

============= >何でもありなら、XMLHttpRequestを使うとか、MD5とか、、、 MD5はdel.icio.usのJSONPで、JavaScriptからCGIアプリケーションにURLを渡す時に使われています。 勉強しなきゃなあとは思いつつ,時代の進歩が早いので自分ではあまり確認しておりませんorz >元の質問からはなれてきてるような 確かに(笑)。俺は放っておくとガンガン話しそうだし明日には締め切る。 こういうのを「入力側の抵抗を押さえた上で」 どういう風に構築するか,ってのは,結構普段から考えている

himajin100000
質問者

補足

>HTMLにおいては、どの文字コードで送信しなければならない、と言う規定はなかったと思いますよ。つまり、UTF-8のフォームから、Shift_JISやeuc-jpで送信しようが、"UTF-7"で送信しようが、HTML/XHTMLとしては規格通りな訳で... この辺? http://www-ise3.ist.osaka-u.ac.jp/miura/?HTML%20form%CD%D7%C1%C7%20accept-charset%C2%B0%C0%AD%A4%CE%B5%BF%CC%E4%C5%C0 >その辺は考え方がちがうので、、、IEを除外、でもいいんじゃないでしょうか。 主張は理解できます。俺は構築するとなったらおそらくIE除外をしたがるでしょう。(あるいはIEのみ不完全であることを述べた上でワンクッション置く) >HTMLタグで考えた場合、特定のタグのみ非許可とした場合、 作者が知らないブラウザ独自タグや新しく定義されたタグが、セキュリティー上問題であっても許可となってしまうことがあります。 サーバ側プログラムであればValidatorにかける・・・という思考で俺は動く。 #言語非依存な時に「CGI側」って使うようにしているが 用法間違っている気がしなくもないので今回は「サーバ側」 >サニタイジングするときは、全てを非許可とした上で、 >許可しても良い物のみリストアップ >実態参照や数値参照のみ有効にするのであれば、 >&xxx;と&#nnn;(nは数字)という並びの&のみ再変換しておけば良い 俺が違和感を感じるのはこの辺に温度差があるからなんだろうなあ・・・・。 俺はtextareaがあったら,「#PCDATA」か「CDATA」の入力欄としてしか認識できない。 なので,エラー出されることなく「#PCDATA」の部分と「CDATA」の部分が混ざっていると入力していて非常にイライラする。 #改行を含む文字列をはてなダイアリーのコメントで入力し, CAPTCHAの文字列を敢えて間違えてみると,入力欄にはbr要素がorz そういう風に一貫性が取れてないのもイライラします。 んで,俺はDOMに慣れきっているせいか,結構DOM万歳なところがある。 ===================== 俺が実装するとしたら・・・・・。 マーク付けは有効 textContentを取得して,検索する。 (ため,取り除く文字列があらかじめわかっている必要がある。 http://www.w3.org/TR/unicode-xml/ 等は参考になる可能性が高いだろう) ちなみに,ユーザーの入力ミスにより,文法違反でありDOMツリーが生成できないとわかったら システム側では手を加えず,エラーを出してユーザーに通知。 ただし,textContentにより出力された文字列のある位置の文字について, 子要素等を介さず直接その文字を持つ要素を探り当てる手段があるかは検討事項。 #RLOはユーザーが実体参照・数値文字参照を入力するという手順経由で入力されているとは 限らない(その形でソースコードに入っているとは限らない)ので,本気で取り除きたかったら実体参照・数値文字参照だけ元に戻す,では多分駄目。 攻撃側としては htmlの文法を無視していることを前提に, aaa&#x202E;bbb を記述したテキストファイルを拡張子.htmlで保存して ブラウザで文字列を表示させて,コピペ,ってのも多分手としてはあり。 もちろん,パーセントエンコードした文字列を使って telnetクライアントで地道に送ってもよし。 #ちなみに,ある特定の要素,属性,文字実体参照のマーク付けを認め,それ以外のマーク付けが使われている時は【エラーを出す】(ただし,数値文字参照は制約を課すことはできない)というのは自力でスキーマを作ってValidatorを噛ますかな。(DTDでもXML Schemaでも良し。XHTML 1.1等を使うならモジュール化されているから特定のモジュールを内部サブセットでINCLUDEをIGNOREに書き換えるなりして。) あらかじめ告知してある場合,その範囲に限り,システム側でXSLT等使って勝手に作業をしていいと思っている。 イベント系の属性は全て取り除く。(DTDやXSLT) script要素は存在できないようにする a要素のhref属性に仕込まれるjavascriptスキームによるコードは ユーザーの能動的なクリック等が必要とされるため,自己責任として基本的に対処しない。 万が一対処するとしても,IANAのスキームに定義されてないから,というような理由になるかな。 data: uriが心配な気もするけど。 個人的な好みの問題でXHTML 1.0 Strictだろうから iframe要素,frame要素,frameset要素は存在できない。 img要素,object要素,については別途検討かな。不可にするかも。 id属性やclass属性に使われるトークンについては 特定の接頭辞をシステム側が使うものとして,それらをあらかじめ告知した上でXSLTで取り除く といったところだろうか。

全文を見る
すると、全ての回答が全文表示されます。
回答No.4

あっと、失礼しました。 > ANo.1回答 > hoge:%8F%EC%BF これを再現させないとダメなんですね。 こっちはまだできていませんが、気になったこととして、 WinXP SP3、Firefox3、Opera9.5を使われてるんですね。 私のところは同SP2、Firefox2、Opera9.0/9.2なんですが、コード体系が違うのかもしれません。 そうなると、私のところでは再現は不可能ですね。 まぁ、送信される文字コードはHTMLでどのように指定していても、結局ブラウザ依存ですから、 何らかの形で必ずUTF-8なりEUC-JPなりに変換してから出力や保存しなければなりませんから... euc-JPmsで%8F%EC%BFが何の文字なのかちょっとわかりませんが(^^; UTF-8と同様に文字化けせずに表示できていれば、大丈夫じゃないでしょうか。

参考URL:
http://ja.wikipedia.org/wiki/EUC-JP
himajin100000
質問者

お礼

蛇足2: 実は,この質問を出す前,これとは別件で質問を出してました・・・が, 「疑問には思ったもののそのまま調べず放置してかなり経つ質問」が自分には他に4つあり,質問制限5つにひっかかるので削除していました(汗) http://oshiete1.goo.ne.jp/qa3611556.html http://oshiete1.goo.ne.jp/qa3613677.html からの流れで, 「$teststr = "\\";とか $teststr = "\n";とか考えてなかったー (PHPでは $teststr = " "; が出来るが,Ecmascriptでは出来ない。) 他に忘れているケースない? ミスらないように標準化された方法があればそっち使いたいんで 知ってたら教えてー」って。 置換して対処しているんですが・・・ #CRLFとLFをそれぞれエスケープするのがアレだったな。 まだ検討しないといけないのがある。 $teststrに Ecmascriptとして出力するときに利用する文字集合に含まれない文字を利用した文字列を$teststr ="\x9AD9";とか指定したらやっぱりアウト。 さっき飯食っているときに頭の中に思い浮かんだのが, CGI側でBase64やパーセントエンコードした文字列にして Ecmascriptにそのまま渡す。渡された文字列をEcmascript側でデコードする,とかいう手段。どうなんでしょうね?(デコードしたら改行が含まれるものでも多分平気!) #「補助漢字」は,EUC-JPに含まれる文字であるため,いづれの方法も数値文字参照ではなく文字そのものが出力されてしまい「IEで上手く表示する」という目的には全く役に立たない。 #補助漢字がどうとかRLOがどうとかいうケースは結局考えなかったなー。文字としては正しいし。 #とりあえず解決したし,補足やらお礼やら使って言いたいことは言えたので,このまま回答者側から言いたいこと(脱線可)がなければ明日締め切ろうかなと思う。 #Q3603911も考えてみると結構面白いゾ。

himajin100000
質問者

補足

Blogの方に気づいてもらえたようで, meta要素を挿入して実験を行ったところ,無事再現できました。 #もちろん,入れる前から符号化方式がEUC-JPであることは確認していたのですがね。 http://shimax.cocolog-nifty.com/search/2007/12/php_htmlspecial_4c35.html >【IEやFirefoxで】POSTすると数値文字参照になります http://shimax.cocolog-nifty.com/search/2007/12/phphtmlspecialc_26bb.html >IE【をはじめとするブラウザ】が数値文字参照・文字実体参照で送っていることは、PHP開発者の方も十分に知っておられる って書いてあったので準拠してそうな規格を探してました(汗) #Minefieldって途中からロケーションバーが変わっているので後でFx2でもやろうかと。 ( http://d.hatena.ne.jp/nyama/20070708/1183864631 ) ・・・ってことはIEでのみ発生する現象であり,悪いのはそんな形式で送ってくるIEってことかな? (であれば,一つのブラウザのバグのためにわざわざPHP側が歩み寄る義務はなく http://shimax.cocolog-nifty.com/search/2007/12/phphtmlspecialc_26bb.html で何故PHP側を批判しているのかが理解できなかったんです。) #今回の検証に用いたブラウザに関してはaccept-charsetで何とかするとして・・・ 検索してみると http://www.google.co.jp/search?hl=ja&q=accept+charset IEはaccept-charset属性に対応してないという記述が多く, IE6では対応できないかもしれないなあ

全文を見る
すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

> accept-charset外したら > Minefield >hoge:%8F%EC%BF これは補助漢字を指示している euc-jpですね。 うーん、確かにどうすれば数値参照で出てくるのかわかりませんね。 #自分も再現できません > IE 7 > hoge:%FAt これは shiftjis(cp932)ですかね? > Safari 3.0.5(525.3) > hoge:%B2%AA え? これは…なんだろう?

himajin100000
質問者

お礼

補足欄が全然足りないorz 蛇足2です。talooさん向けの要素が強いです。 しかも続きが回答4のお礼に続きますorz 補足やらお礼やらの位置が上だったり下だったり統一されてなくて読みにくいかもしれません。もうしわけありません。 DOMDocument->encodingを出力したい符号化方式にして DOMツリーを生成して DOMDocument->saveXML()の返り値を取得すると漏れなく【XML宣言付き】で, 数値文字参照に変換された文字列が得られる。 ちなみにDOMDocument->createTextNode(hoge)によって生成したノードを DOMDocument->appendChildして出力することもできる。 (ところで,documentElementを作成したりしなくても出来るんですが,正しいんでしょうか?) #ただし,libxmlの挙動でmeta要素が埋め込まれることは考慮すること。 http://pastaseca.blog119.fc2.com/blog-entry-42.html だが・・・ DOMDocument->SaveXML(node)は常にUTF-8で出力されるから XHTMLをEUC-JPで出力したいって時には役に立たない。

himajin100000
質問者

補足

#1お礼続き [SQL] sql.safe_mode = Off [ODBC] odbc.allow_persistent = On odbc.check_persistent = On odbc.max_persistent = -1 odbc.max_links = -1 odbc.defaultlrl = 4096 odbc.defaultbinmode = 1 [MySQL] mysql.allow_persistent = On mysql.max_persistent = -1 mysql.max_links = -1 mysql.default_port = mysql.default_socket = mysql.default_host = mysql.default_user = mysql.default_password = mysql.connect_timeout = 60 mysql.trace_mode = Off [MySQLi] mysqli.max_links = -1 mysqli.default_port = 3306 mysqli.default_socket = mysqli.default_host = mysqli.default_user = mysqli.default_pw = mysqli.reconnect = Off [mSQL] msql.allow_persistent = On msql.max_persistent = -1 msql.max_links = -1 [OCI8] [PostgresSQL] pgsql.allow_persistent = On pgsql.auto_reset_persistent = Off pgsql.max_persistent = -1 pgsql.max_links = -1 pgsql.ignore_notice = 0 pgsql.log_notice = 0 [Sybase] sybase.allow_persistent = On sybase.max_persistent = -1 sybase.max_links = -1 sybase.min_error_severity = 10 sybase.min_message_severity = 10 sybase.compatability_mode = Off [Sybase-CT] sybct.allow_persistent = On sybct.max_persistent = -1 sybct.max_links = -1 sybct.min_server_severity = 10 sybct.min_client_severity = 10 [bcmath] bcmath.scale = 0 [browscap] [Informix] ifx.default_host = ifx.default_user = ifx.default_password = ifx.allow_persistent = On ifx.max_persistent = -1 ifx.max_links = -1 ifx.textasvarchar = 0 ifx.byteasvarchar = 0 ifx.charasvarchar = 0 ifx.blobinfile = 0 ifx.nullformat = 0 [Session] session.save_handler = files session.use_cookies = 1 session.use_only_cookies = 1 session.name = PHPSESSID session.auto_start = 0 session.cookie_lifetime = 0 session.cookie_path = / session.cookie_domain = session.cookie_httponly = session.serialize_handler = php session.gc_probability = 1 session.gc_divisor = 100 session.gc_maxlifetime = 1440 session.referer_check = session.entropy_length = 0 session.entropy_file = session.cache_limiter = nocache session.cache_expire = 180 session.use_trans_sid = 0 session.hash_function = 0 session.hash_bits_per_character = 4 url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset=" [MSSQL] mssql.allow_persistent = On mssql.max_persistent = -1 mssql.max_links = -1 mssql.min_error_severity = 10 mssql.min_message_severity = 10 mssql.compatability_mode = Off mssql.secure_connection = Off [Assertion] assert.bail = Off [COM] [mbstring] mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_input = UTF-8 mbstring.http_output = UTF-8 mbstring.encoding_translation = Off mbstring.detect_order = auto mbstring.substitute_character = none; mbstring.func_overload = 1 [FrontBase] [gd] [exif] [Tidy] tidy.clean_output = Off [soap] soap.wsdl_cache_enabled=1 soap.wsdl_cache_dir="/tmp" soap.wsdl_cache_ttl=86400 ================================== [自作プログラム - C#(慣れるため)] namespace P20080101A { class P20080101A { public static void Main(string[] args) { /* アルファベットだけなのでコードページ65001でも何でもいい */ System.IO.StreamReader reader = new System.IO.StreamReader("php.ini",System.Text.Encoding.GetEncoding(65001)); System.IO.StreamWriter writer = new System.IO.StreamWriter("php_ini" + "log.txt",false,System.Text.Encoding.GetEncoding(65001)); while(!reader.EndOfStream){ string str = reader.ReadLine(); System.Console.WriteLine(str); if ( (str.Length > 0) && (str.Substring(0,1) != ";")){ writer.WriteLine(str); } } writer.Flush(); reader.Close(); writer.Close(); } } }

全文を見る
すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

> <form action="20071225-1.php" enctype="x-​www-urlencode"​ method="post" accept-charset="UTF-8"> >header("Content-Type:text/plain;charset=UTF-8"); これだとリンク先の方の試験と状況が変わってしまうのでそれが問題では? 上記のように設定した場合、入力元がなんであれブラウザはUTF-8文字列に 変換して送りつけてきますよね? UTF-8でなら件の字は問題なく表すことができるので、数値表記にされないんじゃないかと思います。 って読み返してみたら > #accept-charset外したらMinefieldとIEに挙動の差が見られたが, > #数値文字参照などにはなっていない ってありますね。 むう。 ついでに & がhtmlspecialchars関数での変換対象なのは、& が(HTMLで)特別扱いすべき キャラクタだからとしかいいようがないような。 つまりあのような目的に htmlspcialchars関数を使うのが間違いじゃないかと。

himajin100000
質問者

お礼

未検証です。長いのでお礼欄も併用させてもらいます php.iniを自作プログラムで抽出 [PHP] engine = On short_open_tag = On precision = 12 y2k_compliance = On output_buffering = Off zlib.output_compression = Off implicit_flush = Off unserialize_callback_func= serialize_precision = 100 disable_functions = disable_classes = expose_php = On max_execution_time = 30 ; Maximum execution time of each script, in seconds max_input_time = 60 ; Maximum amount of time each script may spend parsing request data memory_limit = 128M ; Maximum amount of memory a script may consume (128M) error_reporting = E_ALL & ~E_NOTICE display_errors = "stderr" display_startup_errors = On log_errors = On log_errors_max_len = 1024 ignore_repeated_errors = Off ignore_repeated_source = Off report_memleaks = On report_zend_debug = 0 track_errors = Off error_prepend_string = "<p>" error_append_string = "</p>" arg_separator.output = "&" arg_separator.input = "&" variables_order = "EGPCS" register_argc_argv = On auto_globals_jit = Off post_max_size = 8M auto_prepend_file = none auto_append_file = none default_mimetype = "" default_charset = "" always_populate_raw_post_data = On unicode.semantics = on unicode.runtime_encoding = utf-8 unicode.script_encoding = utf-8 unicode.output_encoding = utf-8 unicode.from_error_mode = U_INVALID_STOP unicode.from_error_subst_char = 3f doc_root = "C:\Data\httpd\data" user_dir = extension_dir = "./" cgi.force_redirect = 0 cgi.rfc2616_headers = 1 file_uploads = On upload_max_filesize = 2M allow_url_fopen = On allow_url_include = Off from="john@doe.com" user_agent="PHP" default_socket_timeout = 60 [Date] [filter] [iconv] iconv.input_encoding = UTF-8 iconv.internal_encoding = UTF-8 iconv.output_encoding = UTF-8 [sqlite] [xmlrpc] [Pcre] [Syslog] define_syslog_variables = Off [mail function] SMTP = localhost

himajin100000
質問者

補足

#質問タイトル間違えた。「補助漢字」なので「文字集合範囲外」ではない 当方の検証では accept-charset外したら Minefield hoge:%8F%EC%BF IE 7 hoge:%FAt Opera 9.5 Build 9716 hoge:%8F%EC%BF Safari 3.0.5(525.3) hoge:%B2%AA となりました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 文字列の一部を取り出したいのですが、文字化けしてしまいます。

    文字列の一部を取り出したいのですが、文字化けしてしまいます。 コードは以下のとおりです。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <?php $str = "日本語日本語UTF-8"; print mb_substr($str, 0, 3); ?> </body> </html> おそらく2バイト文字の途中で切っているので文字化けするのだと思いますが、 対象方法が分かりません。 ご存知の方がいらっしゃいましたら、すみませんが教えてください。

    • ベストアンサー
    • PHP
  • 文字コードについて

    <?xml version="1.0" encoding="Shift_JIS" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja" id="sixapart-standard"> <head> <meta http-equiv="Content-Type" content="text/html" charset="Shift_JIS" /> </head> というように文字コード指定をしているのですが、なぜか文字コードがUTFになり、shift jisにすると文字化けしてしまいます。 どなたかアドバイスお願いいたします。

    • ベストアンサー
    • HTML
  • XHTMLの文字コードのEUC-JPの文字化け

    いつもはHTML4.01で作業をしていて XHTMLはどうも不慣れなせいか 今、外注が作成したHPを修正していて 文字コードをEUC-JPにどうしても変更しなければならないのですが それがうまくいかず、文字化けが発生してます。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> を <?xml version="1.0" encoding="euc-jp"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=euc-jp" /> このように設定したら文字化けが発生しました。 どのように設定したら文字化けがなくなりますか?

  • 初歩的な質問で恐縮ですが、教えてください。

    すみませんが、教えてください。 入力フォームでデータが送れなくて、困っています。 下のコードに問題点はあるのでしょうか? 自分では、分からないので、よろしくお願いいたします。 test1.php------------------- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> </head> <body> <form method="post" enctype="multipart/form-data" action="./test2.php"> <input type="text" name="fmTitle" ><br /> <input type="submit" value="次へ" > </form> </body> test2.php-------------------------- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> </head> <body> <?= $fmTitle . "<br />" ?> </body>

    • ベストアンサー
    • PHP
  • なぜ文字化けしないのでしょうか?

    Windows Me(shift_jis)とFedoraCore4(utf-8)のPCのブラウザに以下のFedoraCoreのPCに配置してあるgomi.php(utf-8で記載)を表示させて 入力欄に「お元気ですか。」と日本語を入れてもその応答が文字化けしません FC4はutf-8なのでshift_jisのWindows Meでは文字化けするはずですがしませんがどうしてでしょうか? gomi.php -------------------------------------------------------- <?php $in=isset($_POST['in'])?$_POST['in']:'bad'; echo '<?xml version="1.0" encoding="utf-8"?>'; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/> <title>test</title> </head><body> <p><?= $in ?></p> <form method="post" action="<?= $_SERVER['PHP_SELF'] ?>"> <input type="text" name="in"/> <input type="submit" value="送信"/> </form> </body></html>

    • ベストアンサー
    • PHP
  • perl5.8のエンコードで悩んでます

    perl5.8のエンコードで悩んでいます。 5.6環境下でjcodeなどを使用したいろいろな処理は普通にできるのですが、そろそろ5.8での文字処理もちゃんとできないとあぶないかなと思い、練習していましたが…なんとも挙動が解らないときがあります…。 よければご教授いただけると幸いです。 まず基本的な練習として、POSTされた文字データを受領するものを作ってみました。 <<送信元 post1.html>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <p>POST実験</p> <form id="form1" method="get" action="post2.cgi"> <p>data1 <input name="data1" type="text" /> </p> <p>data2 <input name="data2" type="text" /> </p> <p> <input type="submit" name="button" value="送信" /> </p> </form> </body> </html> <<受領部 post2.cgi>> #!/usr/bin/perl #モジュール利用宣言 use CGI; #CGIモジュール use strict; #表記の正規化を強制 use warnings; #警告表示 use CGI::Carp qw(fatalsToBrowser); #エラー報告有効 #エンコーディングの指定 #use utf8; #この部分を有効にすると入力内容が文字化け #use encoding 'UTF-8';#これも同様に入力内容が文字化け #データの受領と変数名整理 my $input_data = new CGI; my $in_data1 = $input_data->param('data1'); my $in_data2 = $input_data->param('data2'); #入力チェック my $message_data = ""; #変数初期化 if($in_data1 eq "" && $in_data2 eq ""){$message_data = "入力部に空欄があります";} else{$message_data = 'Data1は'.$in_data1.'Data2は'.$in_data2.'です';} #ヘッダ発行 print "Content-type: text/html\n\n"; #html表示 print <<END_OF_HTML; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <p>サシスセソはSJISで化けるカタカナ。<br>入力内容は${message_data}</p> </body></html> END_OF_HTML exit; 両ファイルともTeraPadを利用して、文字コードはUTF-8N、改行はLFにしています。 しかし、use utf8;と書くと、入力文字が化けてしまいます。 (コメントアウトすると普通に表示されます) ちょっと漠然としていて申し訳ないのですが、なぜ化けるんでしょう…。 いろいろ調べてみたんですが、binmode STDOUT, ":encoding(utf-8)";とかをつけても特に変化がありません…。 しかし変わりすぎてキツい…でも今は5.8仕様の文字処理ができないとあぶないのかなぁ…。

  • 文字エンコーディングについて

    <?xml version="1.0" encoding="euc-jp"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="ja" dir="ltr" xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" /> これは、私が使っているブログテンプレートのソースの最初の部分です。 このテンプレートに、 <script type="text/javascript" src="http://mcnv.net/bp/js/hitomojibp.js#tag_id=3270" charset="UTF-8"></script> のブログパーツって使えますか? プラグインにソースを貼ってみたんですけど表示されません。 原因は何なのでしょうか。 原因がわからないので、文字エンコーディングがおかしいのかな? と思っただけなので、違ったら指摘お願いします。

  • CakePHP文字化けについて

    お世話になります。基本的な質問で申し訳ないのですが、CakePHPのインストールをしたのですが、ブラウザ経由の文字化けが発生しており、困っております。 \app\webrootに以下のHTMLファイルを設置し、ブラウザ経由でアクセスしたのですが、エンコードUTF-8でアクセスすると文字化けが発生してしまいます。エンコードをShift-JISに指定しなおしたところ問題なく表示されるのです。charset=utf-8を指定しているにも関わらず、Shift-JISで表示されるのはどうしてですか。また、UTF-8で正常に表示するには、追加で設定が必要になるのでしょうか。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    <title>Hello</title> </head> <body> <p>これは、テストページです。</p> </body> </html>

    • 締切済み
    • PHP
  • <title>~<title>部分にPHP読み込み

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <title>●●●●●●</title> <meta http-equiv="content-script-type" content="text/javascript" /> </head> <body> ~ 上記<title>●●●●●●</title>部分の、●●●●●●にtitle.phpの内容を挿入したく、 <?php require("title.php"); ?> と記述したのですが、エラーが出てしまいます。 title.php単体では正常に文字が表示されます。 どのように記述したら良いか、どなたかご教授いただけないでしょうか。 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • XHTMLのIEでの表示

    PHPを使ってXHTMLを出力しています。 下記のようなソースを使った場合、IE系ブラウザでXMLツリーが表示されてしまいます。IE8beta2、IE7、IE5で確認しています。 Google Chrome、Opera、FireFox 3ではこのような問題は起きていません。 どのようにすれば解決できるでしょうか。XML宣言を除けば一応表示はされたのですが。後方互換モードのことなどもIE7で改善されたとのことなので、混乱しています。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title></title> <body> </body> </html>