PHPテンプレートエンジンSkinnyについて

最近行ったサーバの移行。
Ubuntu12.04からUbuntu16.04にしたので、それに伴い、PHPも5.3.10から7.0.18に変わった。想定されることだけど、PHP4時代から使っていたスクリプトの一部が動作しなくなった。細かいことは色々あるけど、一番大きかったのはそれまで使っていたテンプレートエンジンがまるっきり非互換の塊になってしまったこと。
テンプレートエンジンをガリガリ書き直して使い続けても良いんだけど、それはそれでなかなか不安もあったので、何か良いものはないかなと探していて、Skinny(http://skinny.sx68.net/)というのを見つけた。
これもいわゆるテンプレートエンジンで、ビューだけを切り離す用途に特化していて、僕のニーズにバッチリ合うものだった。ビュー層(テンプレート)はSmarty互換らしく、それならそれなりに今後も安心感があるかな、と思えた。
テンプレートエンジンの差し替えを行ったものの、ロジックの8割くらいは流用できたので、非常にスムーズに移行できたと思う。
作者さんに感謝。

Ubuntu16.04にfmlを入れる

新しいサーバ(Ubuntu16.04)でも、これまで使ってきたfmlをなんとかして使いたい。

しかしこれは太古のパッケージを現代のディストリビューションで使う、というやばい話なので、避けられる人は避けた方が良い。

まず、Debian 4くらいに入っていたdebパッケージを入手する(としか書かない)。

とりあえずインストール。

sudo dpkg -i fml_4.0.3.dfsg-2_all.deb

すると、エラーがでてインストールはできない。

Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at /var/lib/dpkg/info/fml.postinst line 229.

なので、-iはあきらめて、unpack&configureする。

sudo dpkg –unpack fml_4.0.3.dfsg-2_all.deb

以下は修正箇所と修正内容。基本的には配列とかhashのdefinedを消すだけ。

sudo vi +229 /var/lib/dpkg/info/fml.postinst

–            if (defined @entry) {
+            if (@entry) {
+238 で同様に
–                 $key ne “_$package” && $key ne “_DB” && defined %entry
+                 $key ne “_$package” && $key ne “_DB” && %entry
+243 で同様に
–                 (defined %entry) &&
+                 (%entry) &&

これでpostinstは修正完了、configureする。間違っていたら再度修正して繰り返し。

sudo dpkg –configure fml

それから、以下のパッチを当てる。

[debian-users:55112] Re: fmlのDebianパッケージ

にあるように、

— 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;

をパッチとして当てたら良い(これは確かめてないけど、たぶん当てないと動かないんでしょう)。

その後、色々動作しなかったが、MLのユーザをlistグループに追加し忘れていたり(移行なら意外とはまる穴かも?)、

# sudo adduser mluser list

makefmlの文法エラーも出た。fmlのテスト機能というのがあるので、

$ makefml test mlname

とやってみると、色々とエラーが出る。要領はおんなじ。

Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at /usr/share/fml/makefml line 6246.

$ vi +6246 /usr/share/fml/makefml
–            if (defined @entry) {
+            if (@entry) {
次、
Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at /usr/share/fml/makefml line 6257.

–                 $key ne “_$package” && $key ne “_DB” && defined %entry
+                 $key ne “_$package” && $key ne “_DB” && %entry
次、
Can’t use ‘defined(%hash)’ (Maybe you should just omit the defined()?) at /usr/share/fml/makefml line 6260.

–                 (defined %entry) &&
+                 (%entry) &&
すると、次は、

Unescaped left brace in regex is deprecated, passed through in regex; marked by <– HERE in m/\$config{ <– HERE \’_ML_\’}/ at /usr/share/fml/makefml line 7003.
Can’t locate getopts.pl in @INC (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at /usr/share/fml/makefml line 139.

(正規表現のエラーが出てるがそれはおいといて)おお、getopts.plがないのか。初情報。少し調べて、以下のパッケージを入れると良いのかも。

sudo apt-get install libperl4-corelibs-perl
なんとこんな名前(perl4ってw)のパッケージが実在することに多少驚きながら、早速入れてみる。すると、fmlがようやく動いた!!

試行錯誤した内容をまとめていますので、不足等あるかもしれませんがご容赦下さい。

2017/6/1追記

上記設定だけでは流れないMLが発生した。

まず、fml.plにlibkern.plと同様の箇所があってエラーが出るので、同じような修正を行った。

— fml.pl.orig 2017-05-26 20:31:48.000576211 +0900
+++ fml.pl      2017-05-26 20:33:04.256837661 +0900
@@ -677,8 +677,8 @@ sub GetFieldsFromHeader
     ### 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;
さらに/usr/share/perl5/jcode.plまでも修正してしまう。これはパッケージlibjcode-perl内のファイルなので、ubuntuに連絡をした方が良いかも。
— jcode.pl.orig       2017-06-01 17:30:16.708268955 +0900
+++ jcode.pl    2017-06-01 17:30:54.168279228 +0900
@@ -681,7 +681,7 @@ sub __z2h_jis {
 sub z2h_euc {

&nbs
p;    local(*s, $n) = @_;
–    &init_z2h_euc unless defined %z2h_euc;
+    &init_z2h_euc unless %z2h_euc;
     $s =~ s/($re_euc_c|$re_euc_kana)/
        $z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1
     /geo;
@@ -690,7 +690,7 @@ sub z2h_euc {
 sub z2h_sjis {
     local(*s, $n) = @_;
–    &init_z2h_sjis unless defined %z2h_sjis;
+    &init_z2h_sjis unless %z2h_sjis;
     $s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
     $n;
 }
ここまででMLは動作しました。まあこんな感じなので、fmlの機能を深く使っているほど、修正箇所が増える感じかもしれません。

CanoScan LiDE 60がWindows7(64bit)だとうまく動かない(解決済み)

以前から使っているキヤノンのスキャナ、CanoScan LiDE 60がWindows7(64bit)だとうまく動かない。これまではWindows XPのPCにつないで利用していたけど、それはやめたいので、調べてみた。

まず、スキャナをつなげる前に、キャノンのサポートページから以下のソフトをインストールする。

・ドライバー(ScanGear CS Ver 11.1.1.1a_64)
・アプリケーション(CanoScan Toolbox 4.9.4.2)

これらをインストールした後スキャナをつないで動かそうとすると、以下のようなエラーが出る。(TWAINソースをオープンできません。接続を確認し、Toolboxを再起動してください。)
 
Image1

以前はこれで諦めていたのだけど、このメッセージを元に調べてみると、このエラーはキヤノンも認識している様子で、以下のページに記載がある。

http://cweb.canon.jp/e-support/faq/answer/canoscan/73841-1.html

「環境変数アップデートツールを実行し、正常にスキャンができるかを確認してください」とある。なんだそれ、と思いながらも指示通りにダウンロード。

・環境変数アップデートツール(sgup.zip)

あとはこのzipを展開して、exeを起動し、対象のスキャナのモデルを選ぶだけ。どうやらドライバの中の CISDS.DS というファイルを差し替えているだけの様子。

そういう不具合があるなら、はじめからドライバの中身を差し替えておいてくださいよ、キヤノン様。

CanoScan Toolboxも、使っていると頻繁に落ちるようなクオリティなので、あんまりやる気は感じられない。

IrfanView4.36をむりやり日本語化してみる

IrfanView4.36に、Japanese.dllが出ていなくて(日本語化できない)、がっかりしている人も多いのではないでしょうか。私もそう。

とりあえず英語のままで利用してるけれど、一部だけでも日本語が出たらいいなということで、4.35用のJapanese.dllの、バージョンの部分をむりやりバイナリエディタで4.36にしてみたら、とりあえず使えています。

具体的にはStirlingを使ってJapanese.dll開いて、Unicodeにして文字列検索で4.35の箇所を全部4.36にしたら良いです。

あとは誰かがこれを元に4.36用のdllを出してくれれば最高なんだけども(お前やれよ、とか言われそう)、これけっこう大変な作業量っぽいので、気軽に「やる」、とは言えないですね。

Windows XPのWindows Updateを成功させる

まず、XPでWindows Updateをかけると、とても高負荷になってしまい、全然先に進まない。これはIEの累積パッチが悪いと、日本のWSUSの公式ブログに記載があった。

つまり、Windows Updateの前に以下のインストールを行っておくことが必要となる。

  • IE8を入れる。ただし更新は入れない。
  • IE8の累積パッチを入れる。2013/11地点ではKB2888505になる。
次に、Windows Updateの中で「Windows Genuine Notification」とやらがいつまでたっても終わらない。なので、とりあえずこのパッチだけはダイアログがでるので飛ばしてしまい、後ほどゆっくり対応するのが良いと思う。

なお、上記パッチは、実行時に以下の2つのサービスを止めるとうまくいく、という記載をどこかのページでみて、実際にやってみるとその通りであった。

  • Automatic Updateの停止
  • DHCPの停止
なんだよそれ、と思うが、まあうまくいけば何でも良いので、細かくは追求しない。理由を知っている人がいれば教えて欲しい。

これら2つをやることで、無事にXPのSP3直後くらいから、現在の最新にUpdateすることが可能になった。

トランペットのマウスピース

この週末に前日練、演奏会本番となわけですが、家が遠いので現地泊。忘れ物をしないように気をつけないと。

マウスピースはLaskeyの65MC(主力)/68MC、あとYAMAHAのEM-1(ネタ用)を連れて行きます。

以下脱線。寝付けないので。

EM-1のリム内径は16.02mm、これはYAMAHAの6Aと7Aの間。小さいですね。どれくらい小さいのか、手持ち+αを内径順に並べてみたら、けっこう面白いです。
  • YAMAHA EM-1 : 16.02mm
  • Bach 7C : 16.2mm (僕には小さい)
  • Bach 5C : 16.25mm (え?)
  • Bach 3C : 16.3mm (え?)
  • YAMAHA 11C4: 16.46mm (僕には小さい)
  • YAMAHA 14B4 : 16.85mm
  • Laskey 65MC : 16.89mm (≓Bach 3C)
  • Laskey 68MC : 16.96mm (68C≓Bach 1-1/2C)
  • YAMAHA 16C4 : 17.00mm
  • Bach 1C, 1-1/2C : 17.0mm
  • Laskey 70からこれを超えてゆく
もちろん内径が全てではありません。リム形状、カップ、スロート、バックボアが異なるので、それぞれ全然違うものです。

YAMAHAの数値は信じてますが、Bachはあてにならない気がします(5C/3Cはもう少し大きいと思うんですが。11C4より3Cが小さい?)。数字だけみると、Laskey 65MCはBach 3Cと似ているようには全然見えませんね。実際に吹くとそんなくらいかな、とは思うんですが。エルクハート以前(ニューヨーク、マウントバーノン)でサイズが違うのかなあ。

で、上の一つの違い、つまり0.1mmとかそこらで、もう全然違います。これはトランペット吹き全員が同意するはず。

僕は1Cクラスだと疲れすぎるので、もう吹いていません。でも、65MCも内径は0.11mmしか違わないのにねえ、みたいな感じです。

結局、何を言いたいのかというと、65MC/68MCくらいからEM-1に差し替えると、感覚が違いすぎて困る(のに使ってる謎)ということを書きたかったような気がします。

いや、前々日に何をしてるんだ。寝なさいよ。

今津荘の跡に行きました

パワースポット(?)、近江今津の今津荘の跡地に行ってきました。

pic1

建物は、障害福祉サービス事業所(ドリーム・あんです/ドリーム・だんだん)へと変わっておりました。

駐車場の木は変わっていませんね。シンボル、という気がします。

pic2

これを見ただけで、懐かしい。

ちょっと引いてみます。

pic3

ああ、この場所、という感じです。

桜が咲いているのですが、確かにこんな場所で音を出していたような。

pic4

この小屋みたいなものも、ありましたよね?

pic5

湖面にはカイツブリ。滋賀の県鳥です(2013/5/7 訂正: 「おそらくオオバン」とのこと。僕は鳥の種類は良く分かりません)。奥様いわく、「陸上を歩いているのは珍しい」とのこと。

pic6

望遠(x6ですが…)でそこそこ遠方からの撮影でしたが、警戒されて逃げられました。

pic7

サーバとのお別れ

2005年3月、就職をきっかけに専用サーバを借りました。
2013/3/31をもって運用終了し、本日ログイン出来なくなりました。途中、ディスクのクラッシュなどがありましたが、概ね8年間、動き続けてくれました。

実機は見たことはありませんが、永年使っていると何となく愛着がわきます。なので、なんだか寂しい気もします。これまでありがとう。お疲れさま。

このサーバで動かしていたものは全てVPSに移行しました。昔の専用サーバより、今時のVPSの方が速いくらいです。ただし負荷が集中すると、遅くなる時もある感じです。共用なので仕方がないですね。
CPUだと、専用サーバはNorthwoodのCeleron2.0GHzでしたが、VPSはWestmere(Nehalem)のXeonなので、隔世の感があります。(すでに一世代前のプロセサですが、そう大きく変わらないでしょう。)

いまのOS(Ubuntu 12.04LTS)のサポートが切れる2017年には、また移行を考えないといけません。

その頃はどんな感じになっているでしょう。今とあまり変わらず、Haswellの次世代くらいのXeon+仮想化でしょうか。それとも、ARM高集積サーバが主流になってたりするでしょうか。そういうことを考えると楽しいですね。

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が出なくなりました。
 

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で動くかどうかは試してません。