PHP -> Tips

PHPの文字化け対策

概要

PHP をSJIS(Shift-JIS)環境において日本語を使用する際、
特定の文字の後ろに \ が付加される文字化けが起こる事がある。
これは文字コードの組み合わせによるものであり、避けて通る事はできない。

設定ファイル php.ini の magic_quotes_gpc=on にすると以下の文字が
\(バックスラッシュ)でエスケープされる

・'(シングルクォート)
・"(ダブルクォート)
・\(バックスラッシュ) 日本語だと\

ここで問題になるのは、\(バックスラッシュ)の文字コードである。

\(バックスラッシュ)の Shift-JIS 文字コードは "5C"だが、

漢字の2バイト目のコードが "5C"のものがこの規則にしたがって
エスケープされてしまう。

たとえば、バックスラッシュをエスケープする場合、
\5,000 の場合 \\5,00 となる

漢字の2バイト目のコードが "5C" の場合、

申告書の場合 申\告書 のように文字化けする。

申の文字コードは "905C" なので 5C の後ろに 5C が付加されてしまう。


magic_quotes_gpc=off にすればいいわけだが、
magic_quotes_gpc=on にすることにより 
完全ではないがSQLインジェクションを防ぐことができるので
セキュリティ上、多くのレンタルサーバでは on になっている事が多い。



文字化けする代表的なものは以下の通りである。

ソ十申貼能表予 等

例:パソコン (文字化け後)→ パソ\コン

対策

設定値の違いによる対策について、

1.magic_quotes_gpc=Offの場合
2.magic_quotes_gpc=Onの場合

magic_quotes_gpc=Offの場合

GET,POST で文字列を送信する場合は addslashes() でエスケープする必要がある

GET送信->受信時の手順

 1.addslashes()でエスケープする
 2.urlencode()でエンコードする。
 3.GET,POST で送信
 4.GET,POST で受信
 3.urldecode()でデコードする。

magic_quotes_gpc=Onの場合

GET POST で受信した文字列を表示する場合は stripslashes() で \ を取り除く必要がある。

GET送信->受信時の手順

 1.urlencode()でエンコードする。
 2.GET,POST で送信
 3.GET,POST で受信
 4.urldecode()でデコードする。
 5.stripslashes()で\を取り除く。

使用例(応用)

入力フォームのデータ(日本語)を MySQLデータベースに登録する。

目的
・日本語の文字化けを防ぐ。
・SQLインジェクション対策。

使用する関数

mysql_real_escape_string();     mysql_query で使用するために文字列をエスケープする
stripslashes();                 addslashes でクォートされた文字列のクォート部分を取り除く 
mysql_affected_rows();          一番最近の操作で変更された行の数を得る
登録例:1

$conn = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

 php.ini の値:magic_quotes_gpc="on" の場合は、TRUE となる。
値がわかっているのであればこの条件文は省略できる。
phpinfo(); 関数でサーバの設定値を確認することができる。

if(get_magic_quotes_gpc()) {
	$name  = mysql_real_escape_string(stripslashes($_POST['name']),$conn);
	$email = mysql_real_escape_string(stripslashes($_POST['email'],$conn));
	$phone = mysql_real_escape_string(stripslashes($_POST['phone'],$conn));
}else{
	$name  = mysql_real_escape_string($_POST['name'],$conn);
	$email = mysql_real_escape_string($_POST['email'],$conn);
	$phone = mysql_real_escape_string($_POST['phone'],$conn);
}

$sql = "insert into users values('$name','$email','$phone')";

mysql_query($sql, $conn);

if (mysql_affected_rows($conn) > 0 ) {
	echo "OK";
}

登録例:2

$conn = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

 magic_quotes_gpc="on"である事が前提

$name  = stripslashes($_POST['name']);
$email = stripslashes($_POST['email']);
$phone = $_POST['phone'];

登録例:とは別の記述法
$sql = sprintf("insert into users (`name`, `email`, `phone`) VALUES ('%s', '%s', %s)",
                    mysql_real_escape_string($name, $conn),
                    mysql_real_escape_string($email, $conn),
                    $phone);

mysql_query($sql, $conn);

if (mysql_affected_rows($conn) > 0 ) {
	echo "OK";
}



先頭へ

      Document-Folder          一覧
HP-UX
HULFT
JAVA
JP1
JavaScript
Linux
MAC
PHP
Perl
Python
Ruby
SOA
Solaris
Unix全般
Windows
XML
エクセル
スタイルシート
セキュリティー
データベース
ネットワーク
パソコン
ブラウザ
プログラム構文
仮想化
          RSS-Folder
ニュース
   アットマーク・アイティ(@IT)
   シンクイット(ThinkIT)
   インターネットコム
   インターネットウォッチ
   日経IT-Pro
   日経パソコン
   CNET Japan
   ZD-NetJapan
   MYCOM
   RBB-Today
ベンダー
   日本IBM
   日本HP
   サンマイクロシステムズ
   NEC
   富士通
   日立
ソフトウェア
   マイクロソフト
   トレンドマイクロ
   オラクル
   サイボウズ
   Mozilla
   野村総合研究所
   (その他ソフトウェア企業)
更新履歴 一覧
 07/08 PERF
プログラム構文
 07/07 PERF
プログラム構文
 06/25 オブジェクトプログラミング2
Perl>サンプル
 07/12 クローン作成
仮想化>vCenter
 07/12 vyatta設定
ネットワーク>vyatta
 07/12 vyattaインストール
ネットワーク>vyatta
 07/12 リポジトリサーバ
Linux>サーバ構築
 07/05 VMwareのインストール
仮想化>VMware
 07/05 PXEブート
仮想化>KVM
 07/01 DHCPでのPXEブート
仮想化>KVM
 06/27 qcow2仮想DISK作成
仮想化>KVM
 06/13 NWの設定
仮想化>VMwareEsxi
 06/13 IPアドレスの変更
仮想化>VMwareEsxi
 06/12 自動ssh
Unix全般>シェル>Bash
 06/12 diffプログラミング
Python
Google