Home > note > php

php Archive

  • 2009.01.24 Sat

php : php4環境下でutf8の全角スペースは正規表現でmatchしない?

sugar.hacca.jpをご覧のみなさま、あけましておめでとうございます。遅い。遅すぎる。
最近はもっぱらデザインの案件やリスティング広告の案件をやっていましたので、なかなかこのブログに書くことがありませんでした。しかしながらひと月以上も更新していないでいると、なんだかむずがゆくなってきたので、以前書きかけて未公開のまま置いておいた記事を苦し紛れにアップしようと思います。
仕事先であるNPO法人彩都メディア図書館蔵書検索システムを構築中につまづいた、PHP4の正規表現に関する内容です。

何年も前から使われてきたFileMakerの蔵書データベースをphp+Mysqlで再構築しました。まずFileMakerでエクスポートしたcsvファイルがダブルクォーテーションやカンマをエスケープ処理していないものだったので、それを修正するのに手間取りましたが、その後は検索機能をはじめとしてページングなどが割とスムーズに構築できました。
ただ、複数条件(AND検索)の実装にあたり、スペースやカンマが入力されたときに区切り文字として認識する、というのに一苦労ありましたのでまとめておきたいと思います。

$titlespace=mb_convert_kana($search['title'],’s’);
$titlespace=mberegi_replace(“ ”,”,”,$titlespace);
$titlespace=mberegi_replace(” “,”,”,$titlespace);
$titlespace=mberegi_replace(“,”,”%’ and title like ‘%”,$titlespace);
$title_where=”title like ‘%”.$titlespace.”%’”;

はじめはだいたいこんな感じで、「半角・全角のスペースが$titlespaceに入力されていたら半角カンマに置換し、さらにカンマを条件追加のsql文に置き換える」という流れを考えてました。ところが、これではなぜか全角スペースの場合だけうまく動きませんでした。
調べてみると、php4+文字コードがUTF-8の場合、正規表現で全角スペースをちゃんと認識できないようです。だめじゃん・・・と思いつつ調べていると

Perl 互換の正規表現の修飾子に u を入れることで UTF-8 を扱うことができますので、preg_replace() を使用すれば対処可能です。
http://ml.php.gr.jp/pipermail/php-users/2005-August/026964.html

という情報を見つけました。Perlはほとんど知りませんでしたので目から鱗。
この情報を参考に、2行目をこう書き換えるとうまくいきました。

$titlespace=preg_replace(“/ /u”,”,”,$titlespace);

めでたしめでたし。このバグ(?)はPHP5では修正されているそうです。

  • 2008.07.01 Tue

php : mb_convert_encodingを使うのに苦労した話

仕事でサイトのお問い合わせフォームをつくることになったので、ネットからフリーのPHPスクリプトを落とし、カスタマイズして設置しようとしたのですが、こんなエラーがでてしまいました。

Fatal error: Call to undefined function: mb_convert_encoding()

どうやらmb_convert_encoding()関数が引っ掛かっているらしい。とりあえずの対処として、mb_convert_encoding()の部分を一度削除してプログラムが動くかどうか試してみたところ、フォームからメールは一応届いたので、この関数がネックになっていることは間違いなさそうです。しかし、届いたメールはメールソフト側で表示エンコードを変更しなければ文字化けしてしまっていますので、やはりこの関数は使いたい・・・。
エラー文をみると、これはPHPにマルチバイト文字列を扱う関数「mbstring」が設定されていないためだと思われます。今回利用しているサーバーは先日契約したばかりの専用ホスティングサーバーだったため、PHPはインストールだけして初期設定のままだったことに原因がありました。

そこで、php.iniをチェックすると、案の定mbstringに該当する行(extension=php_mbstring.dll)がコメントアウトされています。よし、ではここを修正して・・・と思ったのですが、FTPにrootでログインできないのでphp.iniをいじる権限がありませんでした。ならば.htaccessを利用して!と思い、調べてあれこれ試したのですが、書き方が悪かったのか、どれもうまく動きませんでした。(2008/11/09追記:このころはTelnetでログインできるということすら知らなかった・・・。いまだにコマンドラインでのコンフィグは緊張してしまいますw)
結局、サーバーにPHPを再インストールすることにしました。今回のサーバーはPHPのインストールにvinstallコマンドが使えるものでしたので、インストール中にオプションとしてMultibyteモジュールにチェックをいれ、再インストール。

すると難なく使えるようになったのでした。自分でPHPとか入れてしまうと、この手のエラーには結構頻繁に出くわすのかもしれませんね。いい勉強になりました。

  • 2008.07.01 Tue

php : 1行目でheader already sent エラーになる場合

PHPの勉強としてログイン機構を作成していたのですが、IDとパスワードの認証が成功して次の画面に遷移するのに「Header(“Location:○○”);」と書いたところ、

Warning: Cannot modify header information – headers already sent by (output started at hoge.php:1) in hoge.php …

というエラーが出てしまいました。

調べてみたところ、定番のミスとしては「Header();の前にHTMLタグやprint、echoなどの出力がある」というものがあるようです。
そこで、print文で出していたエラーメッセージを変数の中に入れて、Header文の後に出力させるように変更。
しかしまだ同じエラーが出る。
include();やrequire();で読み込んでいるファイルも調べ、出力をしないように変更しましたが、なお状況は変わらず・・・
ほとほと困っていたところに、株式会社マイネット・ジャパンの平島浩一郎さんのブログの記事を見つけました。

phpでheaderが出力できなくてハマった件
http://blog.mynet.co.jp/hirashima/2006/08/phphedaer.html

どうやら、テキストエディターによっては1行目に「BOM文字」と呼ばれる記号が自動で挿入されるということがある模様。私が使用していたのはTeraPadだったので、それまでの保存文字コード「UTF-8」から「UTF-8N」に変更し、保存したところ、きちんとHeader();が機能するようになりました。
このとき、include();やrequire();先のファイルも同様にBOM文字なしの形式で保存してくださいね。

Home > note > php

Return to page top