2008/10/06

phpでEUC検索時の文字化け

「mbstring.encoding_translation」がonの状態では、送信時に自動で内部エンコーディングに変換されているはずです。そして、「mbstring.http_input」が特に指定されていないため、1文字のような短い値だけでは文字コードが上手く検出できず、変換に失敗します。(検索ボタンをクリックした場合は「検索」という文字も送信されるため文字コードの検出に成功する)

「mbstring.encoding_translation」をfalseにしてしまって入力と出力のエンコードを自分でしてしまうのが確実。

設定を変更できないなら古典的方法ですがhiddenで十分な長さの文字を渡してやれば良い。

2008/10/02

EUCページにFLASHでEUCエンコーディングの文字表示

MySqlはEUC、PHPもEUCでまとめているのに
フラッシュはUTF-8とShift-Jisしか判別しないようで、、

MySqlに格納されてるデータを、EUCのページに
Flashで表示すると当然ながら日本語は文字化けする。

しかも表示するページはEUC。

DB(EUC-JP)=>FLASH(UTF-8,Shift-Jis)=>表示(EUC-JP)

UTF-8のデータをEUC-JPに変換
mb_convert_encoding($str , "EUC-JP", "UTF-8");

さてどうする
変数を代入している件にいれてみる
echo("".mb_convert_encoding(mysql_field_name($rs,$i),"EUC-JP")."");

2008/10/01

SJISからEUCへ変換

プログラムを組んでいると、ぶつかるのが文字コード。データベースとPHPを利用していると、データベースの文字コードとPHP書類のコードや出力する際のエンコードをすべて合わせていかないと文字化けします。日本語はEUC-JPが強いのですが、実際はshift-jisで書かれたものも多く、そこにフォームなどのcgiが絡んでいるとPHPでShift-Jis⇔EUCの変換を行う必要がある場面が多々あると思います。

こういう場合はこいつで解決。

mb_convert_variables("SJIS", "EUC-JP", $_POST);
mb_convert_variables("SJIS", "EUC-JP", $_GET);

↑これで$_POSTと$_GETの両方をEUCからSHIFT-JISに変換できます。

↓これはその逆

mb_convert_variables("EUC-JP", "SJIS", $_POST);
mb_convert_variables(
"EUC-JP", "SJIS", $_GET);
出力エンコードを変更する関数は以下の関数です。

mb_http_output('SJIS');
mb_internal_encoding('SJIS');

その他のサーバーの細かい設定には「ini_set()関数」を使用します。

2008/09/30

shift_jisでの5C問題回避法(PHPのみ)

PHPの場合、php.ini内に「Magic Quotes GPC」というオプションがあります。
これはデフォルトでONになっています。
こいつが何をするかといえば、自動でエスケープ文字を取り除くんです。
OFFにしておけばPHP内で害はないのですが、i-modeサイトを作りたい場合や、
MYSQLに検索かけに行く場合などはまた変換かかってエスケープされますので同じです。
URLのエンコード/デコード時にもこの問題がでるはずです。

たとえば「ソ」は「83 5C」です。
Magic Quotes GPCをONのまま「ソ」で検索しようとしたら5Cが取り除かれて
「83」だけで検索にいきます。もちろん「83」な文字はないのでヒット件数はゼロです。

SHIFT_JISの「ソ」をきちんと「ソ」として認識してもらうには「ソ¥¥」と打てば
一番最後¥のだけがエスケープされるので「ソ」と認識してもらえます。

では、PHPでどうやればいいかというと以下のようにします。

get_magic_quotes_gpc()はget_magic_quotes_gpcの値が
何で設定されているかを取得してくれる標準関数です。
「find_word」という名前で画面内のテキストボックスからある値を取得するとします。
addslashes()はエスケープ文字を追加してくれる関数です。

if (!get_magic_quotes_gpc()) {
 $find_word = (($_POST['find_word']));
} else {
 $find_word = (addslashes($_POST['find_word']));
}


addslashesを入れるだけで回避方法は単純な事なのですが、
PHPの理屈がわかっていなかったので非常に難しかったです。

5C文字は「ソ」以外にもあります。以下の40文字です。
SHIFT_JISを使っている場合、一見普通に動いているようにみえても
以下の文字を使ったときに正常な結果が得られないのなら
5C問題が解決されていないという事になります。

— ソ Ы 噂 浬 欺 圭 構 蚕 十 申 曾 箪 貼 能 表 暴 予 禄
兔 喀 媾 彌 拿 杤 歃 濬 畚 秉 綵 臀 藹 觸 軆 鐔 饅 鷭

2008/09/27

文字コード

MySqlデータベースでREINSのデータを不動産検索サイトに
流し込むプログラムを改変していてcsvデータが流し込めない事態に!
なにかエスケープすべき文字があるかと探してみたが見当たらず、

防衛庁に勤めるアキバ系友人にcsvについて質問したところ
『csvはノイズが入るけんテキストの方が確実よ~』
『ノイズ?聞いたことねえ』けどご指摘のテキスト案で開眼。
文字コードを確認して問題を発見。
エクセル書類はshift-jisなのでphpmyadminなどでアップする際はsjisで送信
調べるとsjisとSHIFT-JISは同じことらしいが?なにが違うんだろ??

テキストで開いて改行チェックと文字コードの欠点を発見。
いわゆる"5C系"の文字をエスケープするとのこと。
http://ja.wikipedia.org/wiki/Shift_JIS#.E6.AC.A0.E7.82.B9

北大阪の不動産屋なので能勢とかを入れなきゃならんので
エスケープしまくらんといかん。
めんどくさいし更新のたびの作業となるとミスが多そう。

なので

プログラム全部とhtml書類とデータベースをすべてEUCに書き換えました。
日本語使うプログラムはEUC_JPもしくはUTF-8
ってのが暗黙の?ルールなので。

2008/08/28

ターミナルコマンド

//Documentsフォルダ内の.jpgで終わるファイルを探す
find Documents -name "*.jpg"

「場所も名前も名前も思い出せないけど、最近作ったWord書類」ならば

//Documentsフォルダ内の30日以内に作られた、ファイル名が.docで終わるファイル find Documents -name "*.doc" -ctime -30

// 書類フォルダ全部をバックアップ
tar cvzf Documents.tar.gz Documents

// 解凍 (上書きされるので注意)
tar xvzf Documents.tar.gz


ファイル中の文字列から探す

// Documentsフォルダ内の、文字列を含むファイルを探す
grep "macintosh" Documents/*

// Documentsフォルダ以下のサブディレクトリすべてをたどって探す。
grep -r "macintosh" Documents/*

// 単語を含む(word)
grep -w "macintosh" Documents/*

// 大文字・小文字を無視する(ignore)
grep -i "Macintosh" Documents/*




2008/08/27

Mysqlのソケット

「Can't connect to local MySQL server through socket」エラーについて

■ このような場合に参考にして下さい
MySQLのクライアントソフト(mysql,PHP,Perl他)からMySQLサーバーに接続しようとすると
「Can't connect to local MySQL server through socket '/tmp/mysql.sock'」
のようなエラーが出て接続に失敗する。


■ 対処方法の前に
まずはじめに、エラーメッセージは次の意味を持ちます。

「ソケット'/tmp/mysql.sock'を通じてローカルのMySQLサーバーに接続することが出来ません」ソケットとはプロセスやネットワーク間の通信機構のことで、MySQLではこのソケットを通じてサーバーとクライアントとが接続されます。ソケットというとポート番号を指定して利用する方法が思い浮かびますが、ここでは/tmp/mysql.sockというファイルが出てきています。

これはUNIXドメインソケット(ファイルシステムソケット)と言って、UNIX系OS特有のソケットで、ローカルシステム内での通信を行う場合に用いられます。このソケットの実態はファイルでサーバー・クライアント間の通信は、実際は、このファイルの入出力を通じて行われます。


■ 対処方法
このエラーが発生する原因には以下の3つが考えられます。

▽ MySQLサーバーが起動していない

MySQLサーバーが生存していないとこのエラーが出ます。
ps ax | grep mysqld
などのコマンドで確認して下さい。


▽ MySQLサーバーで使っているUNIXソケットとクライアントソフトで使っているUNIXソケットのパスが違う

当然、サーバーとクライアントは同じソケットファイルを参照しなければならないのですが、
関連する各ソフトのインストール方法が異なる場合は、違うソケットが参照される場合があります。
(例えば、MySQLはソースからインストール、PHPはRPMでインストールというように)
この場合、MySQLサーバーは/tmp/mysql.sockを利用しているのにPHPでは/var/lib/mysql/mysql.sockに接続しに行こうとする、というような事態になり接続が成立しません。

解決方法としては、MySQLサーバーに合ったソフトをインストールするのが一番良いのですが、
次のような方法も考えられます。

(1) MySQLサーバーで使うソケットをクライアントに合わせる

これは/etc/my.cnfの[mysqld]→socket項目を編集して行います。


[mysqld]

# socket=/var/lib/mysql/mysql.sock

socket=/tmp/mysql.sock

この場合、MySQL標準クライアントプログラムのソケットも変えておいた方が良いでしょう。

同じく/etc/my.cnfの[client]→socket項目を編集します。

[client]
socket=/tmp/mysql.sock


(2) クライアント側で接続先のソケットを指定する

例えばPHPの場合、

if(!$con=mysql_connect("localhost","mysql","passwd")){

if(!$con=mysql_connect("localhost:/var/lib/mysql/mysql.sock","mysql","passwd")){

      Perlの場合、

$dbh=DBI->connect("DBI:mysql:tsumiki:localhost","mysql","passwd",
  {RaiseError=>0,PrintError=>1,AutoCommit=>1});

$dbh=DBI->connect("DBI:mysql:tsumiki;host=localhost;port=/var/lib/mysql/mysql.sock",
  "mysql","passwd",{RaiseError=>0,PrintError=>1,AutoCommit=>1});

のようにポート番号を指定する個所でソケットファイルへのパスを指定することが出来ます。

▽ なんらかの理由でソケットファイルが削除されている

最後に、ソケットファイルが削除されている場合があります。

この場合、MySQLサーバーを一旦シャットダウンして再起動をかけるとソケットファイルが復元されます。
※ MySQL標準のクライアントプログラムはオプション--hostでIPアドレスを指定すると、非ソケットファイル経由での接続が行われます。

例えば次のようなコマンドでMySQLサーバーをシャットダウンして下さい。

mysqladmin --host=192.168.10.100 shutdown

もし、これでもソケットファイルが作成されない場合は
ソケットファイル格納ディレクトリのパーミションの問題が考えられます。
ソケットを作成できない場合はMySQLのエラーログが出力されるのでそれを参考にして下さい。

Can't connect to local MySQL server through socket '/tmp/mysql.sock'

の場合再発防止のためにソケットファイルを保護しておく

まず/temp以下を保護する。
ルートユーザもしくはスーパーユーザでログインして
chmod +t /tmp
念のため権限をチェックします。
ls -ld /tmp

ソケットのパスは/etc/my.cnfに記述

ソケットが通信ができているかのテストは
mysqladmin --socket=/path/to/socket version

2008/08/17

Leopard既存のmysqlアンインストール

$ sudo rpm -q mysql
mysql-5.0.45-7.el5 ←存在確認
$ sudo rpm -e --allmatches --nodeps mysql
--allmatces
PACKAGE_NAME に一致するすべてのバージョンのパッケージを削除する。
--nodeps
パッケージをアンインストールする前に依存性のチェックをしない。
$ sudo rpm -e mysql-server-5.0.45-7.el5
$

Leopardでweb制作環境その弐

MySQLを導入バージョンは mysql-5.0.67 osx x86
面倒なのでパッケージをDLスタートアップツールも入っており
環境設定からも起動停止できるおまけ付き。

インストールされた位置は
/usr/local/mysql

シンボリックリンックで表示されている

説明ファイルを読むとmysql.socketのデフォルトの位置は
/tmp/mysql.sockなので⌘shift+Gで移動確認
シンボリックリンクを作る(⌘L)
php.iniの設定でソケットの位置と合わせる
php.iniの場所は/etc/php.ini

my.cnfで対応するsmall,midium,largeとあるがlargeでいってみる
cp /usr/local/mysql/support-files/my-large.cnf /etc/my.cnf
cd /etc/
vi my.cnf


スタートアップアイテムの在処
/Library/StartupItems/MySQLCOM


/etc/hostconfigでMYSQLCOM=-YES-と記述

mysqlの設定ファイル
/etc/hostconfig


パスワードの設定

オーナーパーミッションを設定
sudo chown -R mysql:mysql /usr/local/mysql/*


Mysql稼働確認はターミナルで
/usr/local/mysql/bin/mysql -u root -p 改行


Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.xx x86

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

となればOK

2008/08/14

php.ini

phpの環境設定の編集〜
どこだ?
/etc/php.ini

Leopardでweb制作環境その壱

新しいマシンをゲットしたので作業環境を書き留めておくことにする。
まずphpを使えるようにする。
OSX 10.5 Leopardにはapache2とphp5がデフォルトで入っているので
apache2の設定で使えるようにする

場所はおそらく/etc/apche2/httpd.confなので
ターミナルで確認
cd /etc/apache2/


ls -l

ディレクトリの中のリストと権限を表示
-rw-r--r-- 1 root wheel 17613 8 14 12:16 httpd.conf

つまり権限は644なので書き換えれるように権限を変更
sudo chmod 777 httpd.conf

テキストエディタで書類を開いて編集する(ここではmi)
open -a mi httpd.conf


探すのが面倒なので⌘fでphp5と入力すると以下のような行が
#LoadModule php5_module libexec/apache2/libphp5.so

行頭の#(コメントアウト)を消して保存
LoadModule php5_module libexec/apache2/libphp5.so


権限を元に戻して
sudo chmod 644 httpd.conf

web共有からphpファイルを確認
設定を確認できるようにinfo.phpファイルを作成