PHPの最近のブログ記事

PHP で作られている某社の Web サイトを、うちの古いサーバから新しいサーバに移動したのだが、そしたらデータの登録画面で

Warning: mktime() expects parameter 1 to be long, string given in ~

なんつう Warning が発生し始めた。

ま、Warning なので、そのまま処理は進んでいるようなのだが、どうもデータ的にはボロボロになっているようで、本来表示されるべき場所にデータが表示されない。でも、同じデータをもう一度登録しようとすると「既に登録されています」のエラーになる。
日付が正しく入ってないので、検索条件からこぼれてるんだろうなあ。
(他人が作ったソースを追っかけるのは面倒くさかったので、DB の中身は確認してないけど。)

日頃 PHP を追っかけてないのでよくわからないのだが、ググってみると、どうも mktime の仕様が途中で変わり、パラメータの空値を許さなくなったためのようだ。

確かにソースの該当箇所を見てみると、

$date = mktime($hh,$mm,00,$month,$day,$year);

となってるんだけど、ソース中を調べても $hh には何の値もセットされていない。空値が渡されている。ここを試しに

$date = mktime(00,$mm,00,$month,$day,$year);

とかすると Warning は出なくなるので、やはり空値が問題のようだ。

PHP のバージョンは、古いサーバが 5.0.5、新しいサーバが 5.2.6。どうも、5.1.0 辺りで結構関数の仕様変更があったようなので(あくまで「ようなので」ですが(^^;)、やっぱその影響かなあ。

つーことで、この PHP プログラムを作成した会社に、お客さん経由で「新しい PHP のバージョンに対応した修正を行ってくれ」と依頼したんだが拒絶されたらしい。(^^;
おいおい・・・(^^;

旧サーバはあと2週間くらいで停止させるので、うちの方で直すしかないか・・・
やれやれ・・・(^^;

取りあえず、第一引数が空値なら date(H) をセット。第二引数が空値なら date(i) をセット・・・みたいに直してみればいいかな。

今、ざっと grep してみたら、mktime を使ってて、尚かつ引数に空値をセットしそうなソースが 11本あった。

他人が書いた PHP ソースを 11本も見るのは疲れるのお・・・(^^;

色々事情があって、OpenPNE の「メッセージを送る」画面でメッセージ送信をすると、OpenPNE のユーザのメールアドレスに直接メールを送信する機能を Perl で実装した。

OpenPNE ではメールアドレスは暗号化されているので、OpenPNE のソースを元に、以下のような復号化スクリプトを書いて復号を行った。

#!/usr/local/bin/php
<?php
    $address = $argv[1];
    define('ENCRYPT_KEY', 'hogehoge_key');
    $path ="/www/lib/include";
    set_include_path(get_include_path() . PATH_SEPARATOR . $path);
    include_once 'Crypt/Blowfish.php';
    $blowfish = new Crypt_Blowfish(ENCRYPT_KEY);
    $address = base64_decode($address);
    $address = $blowfish->decrypt($address);
    echo $address;
?>

で、不思議なことに、hogehoge3@exsample.co.jp宛のメールアドレスにはメールが届くのに、hoge@exsample.co.jp宛には届かない。
どちらも、ちゃんと存在しているメールアドレスなのにだ。

原因は、復号されたメールアドレスにあった。
どうも、上記のスクリプトで復号すると、24バイト以下のメールアドレスの後ろに 0x00 のコード(NULL)がセットされてた・・・

一応、後ろにスペースがセットされてたらやだなと思って、Perl 側で、

$address =~ s/\s//g;

な置換はかけてたんだけど、NULL値は \s じゃ引っかからんのね・・・

ということで、

$address =~ s/[\x00]//g;

として不要な NULL値を削ってやったら、問題なくメールが届くようになった。

ああ、ほんまに、ラピッドサイトサーバは maillog が見れないんで駄目駄目サーバだ。
独自のシステムを動かしたい企業は、月数千円の金をケチるのはやめて、WebARENA とかを使うべきである。(・・・て話は、この間もしたな(^^;)

いや、大した話ではないんだけど。

Tools/sequencer を使うと、メーリングリストに投稿したメールの本文に、

Message for test-ml
Sender: owner-test-ml
Precedence: bulk

みたいなものが付いてしまう。

設定で出す出さないが出来ると思うのだが調べている時間がなかったので、Tools/sequencer の該当箇所をコメントにして対応。

199行 print OUT $subject, "\n";
202行 print OUT "Sender: $sender\n";
204行 print OUT "Precedence: $opt_p\n";

あたりね。

Perl で書かれているので楽勝。

ところで、唐突に話は変わるが、UNIX の世界では Perl で書かれたツールも多いので、やっぱ、Perl の習得はインターネットの世界を商売のネタにしている者には必須条件だろう。

よく、「Perl vs PHP」みたいな図式で話をしたがる人もいるが、そもそもそれは同列に並べて比較することが間違っているだろう。

Perl を「普通自動車」とすれば、PHP は「小型自動二輪」じゃないか?
どっちが良いとか悪いとかじゃなく、「やっぱ、普通免許は取っておいたほうが良いよな」の世界ってことだ。
その上で、「二輪免許もあると便利だよな」ということだと思う。

ただ、PHP は「普通二輪」や「大型二輪」ではないと思うけどね。(笑)

まあ、もし、単なる「Web プログラマ」の世界から一歩踏みだしたいと思っているのなら、「俺は Perl なんか嫌いじゃけんね。Perl 覚えるのなら Java 勉強するよ」なんて言ってないで、素直に「Perl を習得することを次のステップに進むための最初の一歩にする」と考えたほうがいいよ。

さっき、「OpenPNE のテンプレートエンジンは Smarty だから」の中で書いた Smarty の例文のつづき。

ログインしてニックネームが取れる状態と、未ログインでニックネームが取れない場合で処理を分けるには、

({if $c_member.nickname})
    ({$c_member.nickname})さん、こんにちは
({else})
    ようこそ!
({/if})

と書けば良いのだが、例えば、ニックネームが取れないときは、無条件に'ゲスト'という名前にしちゃうというのであれば、

({$c_member.nickname|default:'ゲスト'})さん こんにちは

$c_member.nickname が偽(未定義値だったり空だったり)の時、標準で'ゲスト'を出威力せよということだ。
なるほど、いちいちロジック書かなくても良いのは確かに便利だ。
が、これを便利だと思った瞬間に、何となく自分のプログラマ度が下がった気がするのは何故だろう。(笑)

ところで、Smarty のマニュアルを読むと、デリミタ文字は {}(波カッコ)になっているのに、OpenPNE のテンプレートじゃ ({})(丸カッコと波カッコの組み合わせ)になってるんで、なんでやねん?OpenPNE の独自仕様 Smarty ?とか思ったら、

$smarty = new Smarty;
$smarty->left_delimiter = '({';
$smarty->right_delimiter = '})';
...

みたいに簡単にデリミタ文字の設定は変えられるようで。

そりゃそうだよな。

昨日からわからんなりにつついてるんだけど、なるほど、Smarty は強力だ。
テンプレート上で色々と組み込み関数が使えるのが良いな。

ログインしている状態で、ログイン名(ニックネーム)が取れれば「○○さん、こんにちわ」と表示し、未ログイン状態なら「ようこそ!」と表示するのであれば、

({if $c_member.nickname})({$c_member.nickname})さん、こんにちは({else})ようこそ!({/if})

これでOKだ。

なるほど簡単だわ。

他の言語の経験のない Web プログラマが PHP に飛びつくのもわかるような気がする。

俺は使ったことがあんまり無いので(他人が書いたソースを直したことはあるが)わからないのだが、Perl の Template.pm モジュールもこんな感じなんじゃろうか?

ま、Perl プログラマは、自分が必要な機能だけを組み込んだ簡単なテンプレートエンジンをちゃっちゃと書いて、それ使ってるような気がするが・・・
多分、文化的に Smarty を必要としないんだろうなあ。
でも、使ってみると便利だけどな。Smarty(笑)

OpenPNE のマイホームページで出身地等のプロフィール情報を表示してほしいという話があったので対応。
でも、ニックネーム、誕生日等の c_member テーブルにないプロフィール情報はテンプレート用変数がセットされてないんだなあ。

つーことで、

1.webapp/lib/db/member.php に、現住所等の拡張項目を呼び出してくる関数(db_member_c_member_profile4c_member_id)を追加。

2.webapp/modules/pc/page/h_home.php に、

// メンバープロフィール情報
$c_member_profile = db_member_c_member_profile4c_member_id($u);
$this->set('c_member_profile', $c_member_profile);

 という処理を追加。

これで、テンプレート(webapp/modules/pc/templates/h_home.tpl)の中で、({$c_member_profile.pre_addr_pref}) というように表示内容を変数で指定することが可能となる。

同じデザインのフレンド向けホームページの方も同様に修正しとかなきゃ。
こっちは、プロフィール情報呼び出しのキーであるメンバーIDは $u ではなく $target_c_member_id をセットして db_member_c_member_profile4c_member_id を呼ぶ。

ああ、Smarty 使った PHP の開発ってちゃんとやったことがないので、いちいちソースを読んで「なるほど、こういう仕組みかぁ」と動きを把握するしかなくてムチャ面倒くせぇ。(^^;

引き続き、知り合いの会社のサーバ復旧作業のお手伝い中。
ほんとは一気に作業して復旧させちゃいたいんですが、俺も本来の仕事(プログラミングとか)が終わった後でないと対応できないもんで。

で、昨日は、

Warning: mb_convert_encoding(): Unable to detect character encoding in /var/www/hoge.php on line 86

な、エラー(Warning だけど、表示が乱れて使い物にならないので実質エラー)の解消作業。

ま、PHP 使いの人はよく見てる Warning メッセージでしょうが。(笑)

mb_convert_encoding($hogehoge, 'EUC-JP', 'auto')

を、

mb_convert_encoding($hogehoge, 'EUC-JP', 'ASCII,JIS,UTF-8,EUC-JP,SJIS')

に修正したら Warning が出なくなるので、典型的な「mbstring.language = Japanese」が有効になってないパターン。
でも、php.ini を見たら、ちゃんと mbstring.language = Japanese の記述が・・・

つーか、php.ini が Document Root に置いてあるんだけど、ほんと?

phpinfo() で調べてみると、ほら、Configuration File (php.ini) Path は、/usr/local/lib になってんじゃん。

/usr/local/lib 以下に php.ini が無いのを確認し、Document Root の php.ini をコピー。Apache を再起動してチェックしたら、バッチリOKです。

ということで、php.ini の置き場所を間違っていたために、mbstring.language の設定が効いていなかった・・・というオチでした。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPHPカテゴリに属しているものが含まれています。

前のカテゴリはPerlです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

2009年9月: 月別アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら