7627


PHP超初心者です。

現在、問い合わせフォームを作っているのですが上手くいかない箇所があります。

[code]

    function Conv2HtmlSpecialChars($value)
    {
        if (is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = Conv2HtmlSpecialChars($v);
            }
        } else {
            $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
        }
    
        return $value;
    
    }
    
[/code]

という関数があります。

そして、PHPファイルの中で、

[code]

    $dataArray = Conv2HtmlSpecialChars($dataArray);
    
[/code]

という使い方をします。

上記の`$dataArray`という配列変数には、例えば、

[code]

    $dataArray['氏名'] = "あいうえお";
    $dataArray['フリガナ'] = "アイウエオ";
    $dataArray['郵便番号'] = "999-9999";
    $dataArray['住所'] = "東京都大田区";
    $dataArray['E-mailアドレス'] = "test_test@example.com";
    $dataArray['お問い合わせ内容'] = "お尋ねしたいことがあります";
    
[/code]

がセットされているとします。

そして実際に、PHPを動かしてみると・・・

[code]

    $dataArray['氏名'] => ""
    $dataArray['フリガナ'] => ""
    $dataArray['郵便番号'] => "999-9999"
    $dataArray['住所'] => ""
    $dataArray['E-mailアドレス'] => "test_test@example.com"
    $dataArray['お問い合わせ内容'] => ""
    
[/code]

というように日本語の文字列が消えて、英数字だけしか残りません。

[code]

    htmlentities($value, ENT_QUOTES, 'UTF-8');
    
[/code]

でキチンと`UTF-8`を指定しているのに、なぜ日本語文字列が消えてしまうのでしょうか？

原因をご存知の方、原因と適切な対処方法をご教授いただきたく存じます。  
もし、上記で私がチンプンカンプンなことを記述していたら、そこもご指定願います。

**開発環境**

  * レンタルサーバー（CentOS 5）
  * PHP（5.2.16）
  * 作業環境（Windows7pro）
  * PHP編集用（NoEditor）

P.S.  
他に誰も開発経験がなくPHPが分かる人が１人もいない中、何とか頑張っています。  
何卒、ご協力よろしくお願い致します。

======================== 以下続報 ========================

問題となっている`Conv2HtmlSpecialChars関数`に以下のようなデバッグを仕掛けました。

[code]

      function Conv2HtmlSpecialChars($value)
        {
    
    echo'<hr /><pre>fuction_Conv2HtmlSpecialChars_Start --> ';var_dump( $value );echo'</pre>';
    
            if (is_array($value)) {
                foreach ($value as $k => $v) {
                    $value[$k] = Conv2HtmlSpecialChars($v);
                }
            } else {
                $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
    
    echo'<hr /><pre>htmlentities_value --> ';var_dump( $value );echo'</pre>';
    
            }
    
    echo'<hr /><pre>fuction_Conv2HtmlSpecialChars_End --> ';var_dump( $value );echo'</pre>';
    
            return $value;
        }
    
[/code]

その結果、以下のように出力されました。  
※文字化けしている箇所は無視してください。

[code]

    fuction_Conv2HtmlSpecialChars_Start --> array(9) {
      ["羂���"]=>
      string(10) "武田　進言"
      ["��������"]=>
      string(16) "タケダ　シンゲン"
      ["�灸梢���"]=>
      string(8) "788-9999"
      ["篏���"]=>
      string(12) "東京都台東区"
      ["�肢����"]=>
      string(12) "03-9999-9999"
      ["E-mail�≪������"]=>
      string(21) "test-test@example.com"
      ["E-mail�≪������(腆肴���)"]=>
      string(21) "test-test@example.com"
      ["��������������絎�"]=>
      string(32) "テストコメント１テストコメント２"
      ["date"]=>
      string(27) "2015/03/03 Tuesday 23:59:29"
    }
    
    fuction_Conv2HtmlSpecialChars_Start --> string(10) "武田　進言"
    
    htmlentities_value --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_End --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_Start --> string(16) "タケダ　シンゲン"
    
    htmlentities_value --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_End --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_Start --> string(8) "788-9999"
    
    htmlentities_value --> string(8) "788-9999"
    
    fuction_Conv2HtmlSpecialChars_End --> string(8) "788-9999"
    
    fuction_Conv2HtmlSpecialChars_Start --> string(12) "東京都台東区"
    
    htmlentities_value --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_End --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_Start --> string(12) "03-9999-9999"
    
    htmlentities_value --> string(12) "03-9999-9999"
    
    fuction_Conv2HtmlSpecialChars_End --> string(12) "03-9999-9999"
    
    fuction_Conv2HtmlSpecialChars_Start --> string(21) "test-test@example.com"
    
    htmlentities_value --> string(21) "test-test@example.com"
    
    fuction_Conv2HtmlSpecialChars_End --> string(21) "test-test@example.com"
    
    fuction_Conv2HtmlSpecialChars_Start --> string(21) "test-test@example.com"
    
    htmlentities_value --> string(21) "test-test@example.com"
    
    fuction_Conv2HtmlSpecialChars_End --> string(21) "test-test@example.com"
    
    fuction_Conv2HtmlSpecialChars_Start --> string(32) "テストコメント１テストコメント２"
    
    htmlentities_value --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_End --> string(0) ""
    
    fuction_Conv2HtmlSpecialChars_Start --> string(27) "2015/03/03 Tuesday 23:59:29"
    
    htmlentities_value --> string(27) "2015/03/03 Tuesday 23:59:29"
    
    fuction_Conv2HtmlSpecialChars_End --> string(27) "2015/03/03 Tuesday 23:59:29"
    
    fuction_Conv2HtmlSpecialChars_End --> array(9) {
      ["羂���"]=>
      string(0) ""
      ["��������"]=>
      string(0) ""
      ["�灸梢���"]=>
      string(8) "788-9999"
      ["篏���"]=>
      string(0) ""
      ["�肢����"]=>
      string(12) "03-9999-9999"
      ["E-mail�≪������"]=>
      string(21) "test-test@example.com"
      ["E-mail�≪������(腆肴���)"]=>
      string(21) "test-test@example.com"
      ["��������������絎�"]=>
      string(0) ""
      ["date"]=>
      string(27) "2015/03/03 Tuesday 23:59:29"
    
[/code]

やはり、

[code]

    $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
    
[/code]

のロジックを通ると値が消えていって英数字のみ通過できるようです。

何故このような動きになるのか、何かひらめいたことがあったらご教授ください。

======================== 以下続報２（解決！） ========================

コードを以下のようにしました。

[code]

    function Conv2HtmlSpecialChars($value)
    {
        if (is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = Conv2HtmlSpecialChars($v);
             }
        } else {
    
               $value = mb_convert_encoding($value, 'UTF-8');
               $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
    
            }
        return $value;
    }
    
[/code]

要するに、

`$value = htmlentities($value, ENT_QUOTES, 'UTF-8');`

の関数で悩んでいたのですが、この関数すぐ上に、

[code]

    $value = mb_convert_encoding($value, 'UTF-8');
    
[/code]

を追加して値を`UTF-8`に変換するようにしました。

この方法が正しいかはよく分からないのですが、この方法で上手くロジックが動作するようになったので、結果オーライにしたいと思います。  
もう少しキレイにコードの記述方法をまとめられたらいいのですが、現在の私の力量ではこれが精一杯です。


CC BY-SA 3.0
2015-03-03T04:27:32.260
7351
2015-03-09T00:42:43.533
2015-03-04T13:27:16.390
7634
7634
question
php centos
htmlentities関数を使うと、なぜ日本語文字列が消えてしまうのか？


おそらく `$dataArray` に格納されたデータの文字コードが UTF-8 以外になっています。

当方環境(CentOS6,PHP5.6)で確認したところ、文字コードが UTF-8 でないものを `htmlentities()`
に通したら空文字となりました。  
`htmlentities()`
の[公式ドキュメント](http://php.net/manual/ja/function.htmlentities.php)を見てみると以下のように書いてありました。

> 入力文字列の中に、指定した encoding で無効な符号単位シーケンスが含まれる場合は、 ENT_IGNORE あるいは  
>  ENT_SUBSTITUTE フラグが設定されていない限りは空文字列を返します。

ただし、`ENT_IGNORE` 定数は `PHP5.3 から、`ENT_SUBSTITUTE` 定数は PHP5.4
から使用可能ですので、Web_beginner さんの環境では使用できません。

なので、`$dataArray` のデータ (POSTされたデータでしょうか？) を UTF-8 にすると、正常にデータとして変換できると思います。

* * *

## 補足

検証に使ったコードは以下の通りです。  
以下のコードは UTF-8 の文字エンコーディングで記述されています。

[code]

    include dirname(__FILE__).DIRECTORY_SEPARATOR.'data.php';
    
    function Conv2HtmlSpecialChars( $value )
    {
        if (is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = Conv2HtmlSpecialChars($v);
            }
        } else {
            $value = htmlentities($value, ENT_QUOTES);
        }
    
        return $value;
    
    }    
    var_dump( Conv2HtmlSpecialChars($dataArray) );
    
[/code]

include で読み込んだ `data.php` に以下の定義がしてあります。  
`data.php` の文字エンコーディングは Shift_JIS を指定しました。

[code]

    $dataArray['氏名'] = "あいうえお";
    $dataArray['フリガナ'] = "アイウエオ";
    $dataArray['郵便番号'] = "999-9999";
    $dataArray['住所'] = "東京都大田区";
    $dataArray['E-mailアドレス'] = "test_test@example.com";
    $dataArray['お問い合わせ内容'] = "お尋ねしたいことがあります";
    
[/code]

表示結果が、以下の通りです。  
![文字が消えた再現のスクショ](https://i.stack.imgur.com/R8UD2.jpg)

data.php を UTF-8 に変換すると、ちゃんと表示されました。  
![文字がちゃんと表示された再現のスクショ](https://i.stack.imgur.com/EdmES.jpg)

* * *

# 追記

デバッグコード中の値を表示している箇所の一番最初の `Conv2HtmlSpecialChars_$v_Start` と、最後の
`htmlentities_$value` の出力は配列ではない場合があります。

`Conv2HtmlSpecialChars_$v_Start` は例でいえば "竹田 徹夜" だったり "222-3333" だったりするはずです。  
また、`htmlentities_$value` の値は `htmlentities()` からの返り値のはずなので、絶対に配列にはなりません。

その為、誤った index のデータを表示しているような気がします。

このように配列か文字列か動的に変化してしまう変数を見る場合は  
`echo'<hr /><pre>Conv2HtmlSpecialChars_$v_Start --> ';var_dump( $value
);echo'</pre>';`  
ぐらいにしておいたほうが良いと思います。

* * *

追記2 ：本回答のまとめとなります。

当初回答したとおり、やはり文字化けが原因だと思われます。  
文字化けした場合、場合によっては ASCII 制御コードなどが紛れ込んでしまう(誤って解釈されてしまう)
可能性もあり、様々な意図しない挙動を示すことがあります。  
なので、ここはまず文字化けしないように環境を整える必要があります。  
(実際、私の環境では UTF-8 で揃えて以前つけたスクリーンショットのように正常にデータが表示・処理されておりますので)

  1. HTML 上の form タグにて `accept-charset="UTF-8"` を記述してみて頂けますでしょうか？
  2. HTML の meta タグにて、`<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />` を指定してみてください。
  3. PHP ファイル、HTML ファイル等、基本的にどんなファイルであれ UTF-8N (BOMなしです) で保存してください。
  4. PHP の内部エンコーディングや出力エンコーディングを UTF-8 にしてください。  
参考：[以前の質問 対処法 1. PHP
の設定ファイルを変更する](https://ja.stackoverflow.com/a/7256/7926)をご覧ください

以上となります。


CC BY-SA 3.0
2015-03-03T04:46:11.460
7353
2015-03-04T01:38:37.660
2017-04-13T12:52:38.920
-1
7926
7351
answer


自己解決をしたので、質問に追記した内容のコピペになりますが、以下の通り報告します。

コードを以下のようにしました。

[code]

    function Conv2HtmlSpecialChars($value)
    {
        if (is_array($value)) {
            foreach ($value as $k => $v) {
                $value[$k] = Conv2HtmlSpecialChars($v);
             }
        } else {
    
               $value = mb_convert_encoding($value, 'UTF-8');
               $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
    
            }
        return $value;
    }
    
[/code]

要するに、

[code]

    $value = htmlentities($value, ENT_QUOTES, 'UTF-8');
    
[/code]

の関数で悩んでいたのですが、この関数すぐ上に、

[code]

    $value = mb_convert_encoding($value, 'UTF-8');
    
[/code]

を追加して値を`UTF-8`に変換するようにしました。

この方法が正しいかはよく分からないのですが、この方法で上手くロジックが動作するようになったので、結果オーライにしたいと思います。  
もう少しキレイにコードの記述方法をまとめられたらいいのですが、現在の私の力量ではこれが精一杯です。

------------------ その後の見解 ------------------  
PHP.iniというのがあるのを知ったのですが、これを・・・

[code]

    mbstring.language=Japanese
    mbstring.internal_encoding="UTF-8"
    mbstring.http_output="UTF-8"
    
[/code]

というように設定しておけば済む話だったようです。  
なんともむなしい独り相撲でした。


CC BY-SA 3.0
2015-03-09T00:42:43.533
7627
2015-03-09T00:42:43.533
7634
7351
answer