tmpl2.class.incが最近のPHPでNotice(Undefined offset)を吐くので修正した

私の管理しているサイトで利用している、PHPのテンプレートクラス(PHP4テンプレートクラスライブラリ)が、サーバ移行でPHPのバージョンが上がったためか、Noticeを吐くようになったので、対処したメモ。もしかしたら、参考になる人もいるかもしれないので、公開します。 上記のテンプレートクラスについて簡単に書いておくと、PHP上でテンプレート的なものを簡単に実現してくれる仕組み。PerlでいうHTML::Templateに似てます。 かなり規模の小さいページであっても、ロジックとビューは切り離した方が、メンテナンスする際には便利。というわけで、上記のライブラリは大変便利に利用させて頂いております。 今回の問題は、サーバを更新した際に起こりました。PHPのバージョンが変わったことに起因していると思います。もしかしたら設定で変えられる範囲内かもしれないけど、そこまでは見ていません。 移行前の環境: Ubuntu8.04LTS(PHP 5.2.4-2ubuntu5.27)移行後の環境: Ubuntu12.04LTS(PHP 5.3.10-1ubuntu3.6)移行後の環境で上記のテンプレートクラス(tmpl2.class.inc)を走らせると、以下のようなNoticeが出ます。 PHP Notice: Undefined offset: n in /var/www/virtualhosts/domain/tmpl2.class.inc on line nnn 配列の範囲外参照が起こっているようです。 Noticeは画面には出ないみたいで、気づかない場合も多いでしょう。コマンドライン(php-cli)で動かしたりすると見えます。これも設定次第でしょうが。 そのライブラリのソースを見てみると、一番分かりやすいのがこの部分。 for ( $j = 0 ; $loopbuf[$j] ; $j++ ) ループの継続条件として、配列の範囲外を参照したときに「偽」になる、という動きに依存したコードになっています。 CとかJavaで育った人は、おそらくこういうコードは書かない(範囲外で例外が飛んだりするし)と思うのですが、PHPでこれまで何も問題なく動いていたということは、PHPの文化として許容範囲のコードだったのでしょう。かつては。 私が知る限り、PHP4の時代から、後方互換性についてはあんまり意識されていないメンテナンスが多かったように思います。もちろんプログラミング言語なんて、多かれ少なかれそういう物なのですが、「ちょっとそこを変えないでよ」という問題で頭をかかえたり、PHPを捨てて他の言語に移った人も少なくないでしょう。今回の問題もその一環だと想像しています。 この問題を修正することはそう難しくありません。例えば以下のように修正すればよいです。 for ( $j = 0 ; $j < count($loopbuf) ; $j++ ) これで、配列の範囲外への参照はなくなります。 あと、もう一カ所直しました。基本的には同じ感じで修正しています。(ただし、これはちょっと言語依存的なやり方です。評価の短絡をしているものと信じて&&でつなげています。) 修正前 for ( $i = 0 ; is_array( $this->loopitem[$loopmode][$i] ) ; $i++ ) 修正後 for ( $i = 0 ; $i < count($this->loopitem[$loopmode]) && is_array( $this->loopitem[$loopmode][$i] ) ; $i++ ) 利用の仕方によっては、他にも直す箇所がでてくるかもしれませんが、私の利用している範囲ではこの2カ所に手を入れることで、上記のNoticeが出なくなりました。

2013年3月26日 · 1 分

Javaプログラム内でCPU利用時間を取得する

Linux上のJava1.5以降なら、OperatingSystemMXBeanを使うと、プログラムのCPU利用時間(ナノ秒単位)を取得できる。 OperatingSystemMXBean osBean = (OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();System.out.println(“CPU Time: " + osBean.getProcessCpuTime() / 1000000000 + " secs”); こんな感じ。Windowsで動くかどうかは試してません。

2013年3月1日 · 1 分

Ubuntu12.04LTSにfmlを入れる

MLは標準のmailmanで運用しようと思ったけど、どうもML用にサブドメインを切らないとうまくない様子。これだと、これまでのfmlとの互換性がいまいち。 仕方ないので、fmlを入れましょうか。 まあPerlスクリプトだし何とかなるだろう。よい子は真似してはいけないと思うけど、参考にする奇特な人もいるだろうからエントリにする。 まず、古いDebian(たぶんetch/4.0)からfmlパッケージ(4.0.3.dfsg-2)を持ってきて入れる。 インストールスクリプトが、なんか警告を吐いている defined(%hash) is deprecatedけど、これは気にしない(後述)。 次に、[debian-users:55112]で武藤さんが作成されているパッチを宛てる。 — libkern.pl.old 2010-12-30 08:12:13.000000000 +0900+++ libkern.pl 2010-12-30 08:12:18.000000000 +0900@@ -616,8 +616,8 @@ ### Header Fields Extraction $s = $Envelope{‘Header’}."\n";- $* = 0; # match one line- if ($s =~ /^From\s+(\S+)/i) {+ # $* = 0; # match one line+ if ($s =~ /^From\s+(\S+)/is) { # XXX NO REACH HERE (1999/10/27 by fukachan) # $Envelope{‘UnixFrom’} = $UnixFrom = $1; $s =~ s/^From\s+.*//i; で、先ほどの警告は、Perl5.12から出るようになったらしく、 if ( defined(%hash) ) { …}みたいなコードがあれば出てしまう。これは単に以下のように書きなおす(definedを消すだけ)。if ( %hash ) { …} /usr/share/fml/makefmlでいきなり遭遇したので、diff -uしたものを貼っておく。 — makefml.orig 2013-02-19 18:05:20.619777999 +0900+++ makefml 2013-02-19 19:50:33.175776879 +0900@@ -6252,12 +6252,12 @@ } if ((($] !~ /5.\d\d\d/) &&- $key ne “_$package” && $key ne “DB” && defined %entry+ $key ne “$package” && $key ne “DB” && %entry ) || (($] =~ /5.\d\d\d/) && $key ne “$package::” && $key ne “DB::” &&- (defined %entry) &&+ (%entry) && ($dumpPackages || $key !~ /::$/) && ($key !~ /^</ || $dumpDBFiles) && !($package eq “dumpvar” && $key eq “stab”)まあ、こういう感じで直していけば良い。 その他、こういう警告も出ている。 Legacy library getopts.pl will be removed from the Perl core distribution in the next major release. Please install the separate libperl4-corelibs-perl package. It is being used at /usr/share/fml/makefml, line 139. 「next major release」までは動くと言っているのだから、Ubuntu12である以上たぶん大丈夫だろう。 というか、一からビルドした方が気楽かもしれない。パッケージシステムの意味がかなりない。さらに、これから地雷を踏みまくるのかもしれない。 後々、追記することになるかもしれません。

2013年2月19日 · 1 分

Ubuntu12.04LTSのqmail

Ubuntu12.04LTSにはqmailパッケージ(universe)が存在するので、旧来のqmail-srcパッケージ(multiverse)ではなく、 qmailを入れてみた。たぶん前者はnet-qmailで、後者はDJBのqmail+patchかな。 Ubuntu8.04LTSのqmail(qmail-srcからbuildしたもの)といくつかの違いがあって、はまっていたのでメモしておく。 Maildirを使う /var/lib/qmail/control/defaultdelivery を以下の通り変更。 ./Maildir/ 再起動の方法 sysvinitでもupstartでもなく /usr/bin/qmailctl というのを使う(かなり悩んだ)。 #  qmailctl restart  そんなの知らないよ、ほんとに。 ログの出力内容と場所 標準では /var/log/qmail に、独特のファイル名 & 独特のタイムスタンプでログを吐く。@4000000050ec01243503ffa4 status: local 0/10 remote 1/20@4000000050ec021b06849e04 delivery 84: success: 111.87.239.132_accepted_message./Remote_host_said:_250_Ok:_queued_as_F0C1216F/@4000000050ec021b0685ab8c status: local 0/10 remote 0/20@4000000050ec021b094ef904 end msg 2100129こういう、一目で時刻が分からない、謎な形式は本当にやめて頂きたい。 あと、mail.logに吐いてもらった方が標準的で良いかと思い /var/lib/qmail/rc を以下の通り修正。 qmail-start "`cat /var/lib/qmail/control/defaultdelivery`" splogger qmail すると、以下の通り、普通に出る。これなら読める。 Feb 18 20:05:01 host qmail: 1361185501.323090 status: local 0/10 remote 1/20Feb 18 20:05:01 host qmail: 1361185501.494435 delivery 2: success: 111.87.239.132_accepted_message./Remote_host_said:_250_Ok:_queued_as_62FA0179/Feb 18 20:05:01 host qmail: 1361185501.494581 status: local 0/10 remote 0/20Feb 18 20:05:01 host qmail: 1361185501.494607 end msg 2097550 (hostはhost名)本当にqmailって変わってるよなあ。この機会にPostfixに乗り換えたい気持ちは大きかったけど、互換性の問題もあって、仕方なく入れたものの、すでに半分嫌になっているというところ。 

2013年2月18日 · 1 分

国家資格

もともと好奇心旺盛で、勉強するのが好きな方なので、色々と資格を取ってきた。 資格を取ったから、どうということはない。ただ、知識がないよりはある方がいいだろうとも思うので、結構な数の資格を持つに至ってしまった。 そのうち、国家資格とかに類するものは以下の通り。 第二種情報処理技術者 1996/12/13 (通商産業大臣: 佐藤信二)第一種情報処理技術者 1998/7/3 (通商産業大臣: 堀内光雄)テクニカルエンジニア(ネットワーク) 2004/12/16 (経済産業大臣臨時代理: 島村宣伸)テクニカルエンジニア(情報セキュリティ) 2006/6/13 (経済産業大臣: 二階俊博)情報セキュリティアドミニストレータ 2006/12/11 (経済産業大臣: 甘利明)テクニカルエンジニア(データベース)  2007/6/11 (経済産業大臣: 甘利明)システムアナリスト 2008/12/15 (経済産業大臣: 二階俊博)技術士一次試験 2006/12/26 (文部科学大臣: 伊吹文明)ちなみに父親も同業者であり、第一種情報処理技術者を持っているが、その合格証書に通産大臣「中曽根康弘」と書いてある。なかなかうらやましい。 最近合格していたら経済産業大臣「枝野幸男」だったみたいで、それなら欲しかったかもしれない。 こうしてまとめると、最近何にも合格してない。お金を払えば「技術士補(情報工学)」を名乗れるので、確定申告のついでにやってこようかな。

2013年2月6日 · 1 分

入院、退院しました

お子様が1/5に救急搬送され、入院していた。 本日、1/15に退院した。 基本的には「風邪をこじらせた」という状態だと思うけど、乳児の容態は本当に急変するものなんだと実感。 最初の対応を受けた、豊能広域こども急病センターでは、トリアージ、迅速な酸素吸入をしてもらった。てきぱきとした医師、看護師ふくめ、スタッフの対応は本当に素晴らしかった。 連れて行った地点で体調が悪そうだったので、長時間の点滴くらいは必要だろうと思っていたが、まさかそのまま救急搬送されて入院するとは思わなかった。 3ヶ月にしては、大きめのうちのお子様。 「保育器に入りません。24時間の連れ添いは可能ですか。」(え ということで、入院しているのはお子様なのだけど、奥様も常時一緒にいることになった。 ここ数日は、酸素吸入も不要となり、ステロイド等の投薬も無くなった。状態も悪くないので、入院していても、家にいるのとあまり変わりない。ということで、本日をもって退院することになった次第。 (退院前日。だいたい元気。) こども急病センターのスタッフ、入院先の吹田市民病院(大津市民だが…)のスタッフには感謝。そして、常時連れ添いという非常にハードな10日間を過ごした奥様には本当に頭が下がる。お疲れ様です。

2013年1月13日 · 1 分

ネクスティアの「健康チャレンジ制度」の罠

おこさま誕生に伴い、ある程度の保険に入るべく色々資料を眺めたり。 基本的には死亡保障、掛け捨てのみで良い。あと、補償額は10年くらいで見直せたらいいかな(逓減でも良い)。さらに、ネット生保に拒否感もない。掛け金は安いほうが良いに決まっている。 とすると、だいたいこの3つが候補になる。 ライフネット 家族への保険 ネクスティア カチッと定期  オリックス  Bridge で、金額等を子細に見ていくと、 若いうちはライフネットが安い 年齢が上がると、オリックス < ネクスティア < ライフネット という感じになるかな ネクスティアには「健康チャレンジ制度」というものがあって、健康であれば(再度保険に入れるような状態なら)、割安で継続できる、ということが書いてある。 ただし、これってよく見ると、 普通に継続すると、新規契約よりかなり割高になる。 健康チャレンジ制度で申し込むと、 新規契約よりちょっと安いだけ。20円とか。 ということがわかる。これって、若干罠っぽく思えてしまうね。優良誤認、とまではいかないかもしれないけど、普通の人の期待する内容とは違うんじゃないか。 試算は簡単なので、疑問のある人は見てみたら良いです。 まあ10年後のことなんかさっぱり分からない(それらの生保会社があるかどうかも含め)し、今一番安いライフネットにでも賭けておくか、というのがとりあえずの結論。

2012年11月30日 · 1 分

GmailのPOP3サーバは変です

Gmailは、POP3でメールを取ってくる機能がある。 これを使うと、普通のメーラーでメールを読めて便利。しかも、万一の際のバックアップにもなる。 # 送信(SMTP)も同様で、きちんと設定すればメーラーから送信もできる。 で、以前から気付いてはいたけど、Gmailのモノは普通のPOP3サーバと違っていて、「メールをサーバに残す」ということができない。メールを取得したら(たぶん)消すように作られているみたい。 つまり複数のメーラーで、同じメールを受信しようとしても、できない。 Becky2のプロトコルログを見ると、 1回目の接続 >>> Connecting to “pop.gmail.com” (SSL/TLS) [2012/10/18 22:21:18] <<<+OK Gpop ready for requests from xxx.xxx.xxx.xxx mi2pf44702387pbb.25USER 略@gmail.com+OK send PASSPASS ********+OK Welcome.STAT+OK 90 2916698LIST+OK 90 messages (2916698 bytes)1 3280(略)90 13320.UIDL+OK1 GmailId13a3f0059c8b1ce1(略)90 GmailId13a73f1acf2172c2.RETR 1+OK message follows(略)RETR 90+OK message followsQUIT+OK Farewell.2回目の接続 >>> Connecting to “pop.gmail.com” (SSL/TLS) [2012/10/18 22:22:35] <<<+OK Gpop ready for requests from xxx.xxx.xxx.xxx qu6pf44702630pbc.32USER 略@gmail.com+OK send PASSPASS ********+OK Welcome.STAT+OK 0 0QUIT+OK Farewell. RETRしかしていないのに、次回は見事に消えていますね(ぉぃぉぃ)。 というわけで、GmailのPOP3サーバは変です(この機能、あることだけでも有り難いんだけどね)。

2012年10月18日 · 1 分

Ubuntu12.04LTSのPostgreSQLでEUC_JPのデータベースを作る

まず、Ubuntu12.04LTSにPostgreSQLを導入する。 メタパッケージpostgresqlを入れれば、postgresql-9.1とかが入ってくるので簡単。そのあと、昔と同じ手順で、EUC_JPのデータベースを作ろうとしたら失敗した。こんな感じ。 createdb -T template0 -E EUC_JP dbname createdb: database creation failed: ERROR: encoding EUC_JP does not match locale en_US.UTF-8 DETAIL: The chosen LC_CTYPE setting requires encoding UTF8. 軽くググると、initdbしなおすのだ、とか面倒そうなことが書いてあって、それは面倒だ。さてどうしたものか、とTwitterにつぶやいたところ @PostgreSQL_JP 様からアドバイスを頂けました。ありがたいことです。本当に助かりました。 結論から書くと、以下のようにすれば良い様子。 createdb -T template0 -E EUC_JP –locale=C dbname 昔(PostgreSQL7とか8の前半)と現在では、色々変わっていることも多そうなので、ちゃんと勉強し直した方がよいかもしれません。 「徹底入門」も第3版になって9.0対応になっているみたい(たしか初版は持っている)。

2012年10月5日 · 1 分

育児休暇は、夫婦同時に取れます(取ります)

もうすぐ父親になる予定です。 まだ全然実感はないのだけど、産まれてきたらきっとドタバタと大変になるんでしょう。先輩パパママの皆さんには、色々教えてもらうことと思います。よろしくお願いします。 そして、僕は10月から育児休暇を取ります。夫婦とも、半年くらいは休暇を取って、まず育児にしっかり取り組みたいなと思ってます。 という話をすると、「え、育児休暇って夫婦同時にとれるの?」と聞かれることが結構多いので、久々のエントリとして書くことにしました。 前提として、まず民間の会社員を想定します。公務員のことは分かりません。 以前は主婦がいる場合や、夫婦のどちらかが休暇を取って育児に専念できる場合には、育児休暇を取れない規則を定めることが許されていました。 ですが、平成22年(2010年)6月から施行された法改正によって、この規則は定めることができなくなりました。したがって、1歳に満たない子を養育する場合には、夫婦ともに育児休暇を取得することができます。ただし、1年以上雇用されていること、などの条件を定めることは今でも許されています。 また、通称「パパママ育休プラス」という制度も新設されました。 詳しくは、厚生労働省の育児・介護休業法の改正についてを参照してください。まずは「 改正法の概要」を読むと、大まかに改正点が分かると思います。(他の資料も結構読みやすくて、感心しました。) ただ、いわゆる「有給が取れない」などというのと同じことで、「法的に取得できる」ことと「実際に取得する」ことは全然違うことです。「いやあ、うちではあり得ないな」と感じる人もいることと思います。実際、僕もそういう空気は感じました。空気を読まない、というわけではなく、前例を作りたい、という気持ちもあり(本音を書くと、育児と仕事を両立できるような体調ではないということもあり)、今回休暇を取る決意を固めました。 というわけで、こういう事例もあるんだよ、というお話でした。 あと、何冊か立ち読みした中で、結局この本を買いました。知りたい内容がコンパクトにまとまっていて読みやすかったです。

2012年8月19日 · 1 分