お早うございます。苦戦しているようですね!でも、悩むことはいいことです。php習得の早道です。
【質問1】ブラウザ上に表示するコードを実行すると,漢字の部分が ” ??? ”になる。何故か?
【質問2】厳格に文字コードを指定して,いちいち文字列をコンバートしてデータベースから出し入れするのが正しいやり方なのでしょうか?
【質問3】キャラクターセットとかエンコード(文字コード)の取り扱い方法について???分からないことだらけです。
【質問4】どのようにすれば多くのブラウザに正しく表示されるプログラムが書けるのでしょうか?
まず、私が知る範囲でphpが文字列を出力するメカニズムを文字コードに限定して説明します。
【前提】下記(2)(3)(4)について、自環境のphp.iniがどうなっているか確認要(phpinfo();でもOK)。
(1) 下記スクリプトはWindowsでSJISで書かれていることを前提
(2) 出力の変換を有効にするために output_handler = mb_output_handler を仮定
(3) 内部エンコーディング mbstring.internal_encoding = EUC-JP と仮定
(4) 出力エンコーディング mbstring.http_output = SJIS と仮定
【説明】
1. スクリプト内で「echo "クレヨンしんちゃん";」(SJIS)を実行
2. phpは、内部エンコーディングがEUC-JP(3)なので"クレヨンしんちゃん"がEUC-JPであると思い、
SJIS(出力エンコーディング(4))に変換する。
3. これは、「mb_convert_encoding("クレヨンしんちゃん", 'SJIS', 'EUC-JP');」に等しく
SJISの"クレヨンしんちゃん"を強引にEUC-JPに変換するので、正しく変換されない。
4. 3.を具体的に見て見る(文字列だとわかりにくいので16進表示で)と、下記となる。
[text] => クレヨンしんちゃん
[text(encoding)] => SJIS
[text(hex)] => 834e838c8388839382b582f182bf82e182f1 → SJIS "クレヨンしんちゃん"の16進表示
[mbstring.internal_encoding] => EUC-JP
[mbstring.http_output] => SJIS
[EUC-JP->SJIS(hex)] => 3f4e3f3f3f3f3f3f3f3f3f3f3f → SJISを無理やりEUC-JPに変換した結果
[EUC-JP->SJIS(text)] => ?N??????????? → 上記を文字列として表示した結果
5. 上記のように文字化け ?N??????????? して表示される(変換できない文字は?になる)。
6. "クレヨンしんちゃん"が EUC-JP なら 834e838c8388839382b582f182bf82e182f1 と変換され、
出力エンコーディングのSJIS通り 834e838c8388839382b582f182bf82e182f1 がブラウザに送られ、
ちゃんと表示される。
【結論】
1. 内部エンコーディングに合わせてスクリプトを記述する。
2. 外部データ(データベース等)は内部エンコーディングと同じにするか、スクリプトで変換する。
3. レンタルサーバだとphp.iniで内部エンコーディングを勝手に設定できないので、
スクリプト内で、(例)「mb_internal_encoding('SJIS');」により内部エンコーディングを変更する。
(これは、スクリプト内だけで有効であり、サーバの設定に影響はない)
4. 出力エンコーディングの設定はあまり考えなくても大丈夫です。サーバから正しいコードで文字列が
送られれば、SJSIでもEUC-JPでもUTF-8でも大抵のブラウザは表示することができます。
ちなみに、サーバは出力エンコーディングで設定されたエンコーディングをhttpレスポンスヘッダの
charsetにセットしてクライアント(ブラウザ)に送ります。ブラウザはこのcharsetにより表示を
切替えます(と思う)。
どうでしょう?以上で全質問にお答えしたと思っておりますが・・・。
p.s
phpでのキャラクタセットやマルチバイトの取扱いについては下記一読をお薦めします。
http://www.php.net/manual/ja/ref.mbstring.php