e-Taxソフトが新しいソフトウェアのインストールを構成中です。

e-TaxソフトをWindows 7 Home Premium 64bit(FMV AH700/5A)にインストールしたところ、プログレスバーは100%まで進んだが、「e-Taxソフトが新しいソフトウェアのインストールを構成中です。」と表示したまま5分待っても終わらない。

CPU利用率は60%から25%へ下がり、HDDアクセスランプも付いていないので、インストール処理は終わっているかもしれないと思い、[キャンセル]ボタンをクリックしたが、反応なし。タスクマネージャからeTaxソフトインストーラを終了した。

スタート>すべてのプログラムに「eTaxソフト」フォルダが作成されていたが、コントロールパネル>プログラムのアンインストールの一覧に「e-Taxソフト」が見当たらない。

スタート>すべてのプログラム>eTaxソフト>eTaxソフトのアンインストールをしようとするが、「初期インストールには使えません」と表示されてしまう。

ファイルコピーはしたが、レジストリにインストール情報の登録するところでつまずいているようだ。

再度インストーラを実行すると「別のインスタンスが存在します」と表示されてしまうので、Windows再起動。

いろいろ試してみた。

インストーラexeで右クリック>管理者として実行…
結果:NG

インストーラexeで右クリック>プロパティ>互換性タブ>Windows Vista SP2
(参考 http://naked30s.com/how-to-install-e-tax-software-successfully/)
結果:NG

ノートPCにつないでいる外部モニタを外した。
結果:NG

セキュリティソフトを無効にした。
結果:NG

再起動してF8、セーフモードとネットワークで起動、インストーラexeを実行
結果:OK
途中「レジストリに登録できませんでした ??data.dll」と表示されたが、いつのまにかインストール完了まで進んだ。

リーダブルコードcakePHP版?find()の引数並びにarray()を記述しない

cakePHPの公式サイトには次のようなサンプルコードがある。引数並びにarray()を記述している。

この書き方のメリットは、下記の書き方と比較するとわかりやすい。array()を$paramsなどの変数に代入していないので前後の変数との関連を考えなくてもいいこと(下記 A,C)、この1まとまりの処理の途中に無関係なコードを記述できないこと(下記B)だと思う。

しかし実務では次のデメリットのほうが大きいと思う。

1つ目は、引数並びが長すぎて読む気力が萎えてしまうこと。find()の閉じ括弧までが長すぎて、頭の中のスタックのプッシュ量が多い感じがする。

2つ目はデバッグしにくいこと。printデバッグしたくても、引数並びのarray()のままではvar_dump()できない。eclipse+xDebugでトレースする場合も、引数並びのarray()を表示することはできない。ソースファイルがあれば関数へステップインすると表示できるが、組み込み関数の場合はステップインもできない。

次のようにしたほうが読みやすくデバッグもしやすいと思う。

さらに、array要素を1行1要素にすると、gitで直前のリビジョンとdiffしたとき変更箇所がわかりやすい。

アクション内で$this->XXX->find()を何回も呼んでいて行数が多いと感じたら、それぞれのfind()呼び出しをモデルのメソッドにするといいと思う。モデルのメソッドにすれば1行で呼び出すことができ、前後の変数との関連はないし、一連の処理の途中に無関係なコードの記述もできない。

なお、viewの$this->input()の2つ目の引数は、ロジックとは関係がないhtmlタグやcssなどが多く、引数並びにarray()を記述したほうが読みやすいと思う。

関連:リーダブルコード 8章 巨大な式を分割する

gitのブランチの名前の付け方

かつてSubversionを使っていたときは、ほとんどブランチを使ったことがない。慣例にしたがってtrunk、branches、tagsを用意するものの、trunkだけを使っていた。ブランチとタグの違いを理解していなかった。ブランチ操作を難しいものと思い込んでいたし、「変更履歴」と「以前の状態と比較できる」だけで満足していた。

gitを使うようになってからブランチ/マージを試してみたら、あっけないほど簡単だった。日常的にmasterブランチと開発ブランチを使うようになった。

するとブランチの名前の付け方を考えるようになった。最初はmasterとwork。次の段階では、チケット番号をつけてwork_1234 や ticket_1234で作業するようになった。この程度のざっくりとした運用で問題はないのだが、標準的なブランチ名の付け方や運用方法があるなら、知りたいと思っていた。

素晴らしい記事を発見した。ブランチは5個あるが、各ブランチの目的と運用方法が明確で迷うことはないと思う。

O-Showさんの日本語訳
http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html

Vincent Driessenさんの原文”A successful Git branching model
http://nvie.com/posts/a-successful-git-branching-model/

中央リポジトリ(例 github)

・master 現在の製品バージョン。
・develop 次回リリースの開発用。

開発者リポジトリ

・feature-* 新規機能の開発用。developから分岐し、developへマージする。
・release-* 次回リリースの準備用。developから分岐し、developとmasterへマージする。
・hotfix-* 現在の製品バージョンのバグフィックス用。masterから分岐し、developとmasterへマージする。

※このブランチモデルをベースにしたgit-flow というプラグインもある。

整ったコードの7か条

「ビューティフルコード」 32章 働くコードの「整ったコードの7か条」を紹介する。
#は、投稿者(青木)の意見。

32章の著者 Laura Wingerd、Christopher Seiwald

原文
http://www.perforce.com/resources/white-papers/seven-pillars-pretty-code

サンプルコード
ftp://ftp.perforce.com/jam/src/make.c

■既存のスタイルに溶け込むこと
コードを変更するとき、既存のスタイルで書くこと。

「本のよう」であること
1行の長さを短くする。短い行ほど理解しやすい。 経験的に80文字がよい。

コードをブロックに分けること
コードにコメントをつけること

# サンプルコードはstep 1、step 2と大ブロックに分け、step 1の中をstep 1a、step 1b と小ブロックに分けている。

ごちゃごちゃにしないこと

繰り返し参照される変数名を短くする。
元のコードをコメントで残すのではなく削除する。元のコードはSCMを見ればよい。
何を変更したかをコメントしない。変更履歴はSCMを見ればよい。

# gitやバグ管理ツールを使うと、不要コードや不要コメントを思い切って削除できるようになる。

似たものは似ているように見えるようにすること

インデントを克服すること
インデントが深いと読みにくくなる。
しかし、最大の落とし穴は「入れ子」であり、「入れ子」になったコードは理解しにくい。

# 「入れ子」が深いと、頭のスタックがオーバーフローしてしまう。

Another HTML-lint htmllint.cgiをCentOS/5.5に設置する

Another HTML-lint
http://openlab.ring.gr.jp/k16/htmllint/htmllinte.html

Another HTML-lintはHTML文法チェッカーの老舗であり、Perlソースが公開されている。VMWare上のCentOS/5.5(32bit版)への設置手順を説明する。

[動作環境]

・Windows7上のVMWareにCentOSをインストールした。
・CentOSのIPアドレスを 192.168.0.4 とする。
・WindowsのWebブラウザで、http://192.168.0.4/ にアクセスすると「Apache 2 Test page powered by CentOS」と表示されること。

(1) Windows上の作業

●htmllint.zipをダウンロードする。(記事投稿時2011-11-28 16:17版)

●zipファイルを解凍すると、htmllint/ の下にディレクトリ階層なしで全ファイルが展開される。

●htmllintenv を htmllint.env へコピーまたはリネームする。

●htmllint.cgi、taglist.cgi の先頭行(perlパス)を編集する。

編集前

編集後

(2) WindowsのWinSCPで、CentOSへアップロード

●/var/www/cgi-bin/htmllint/htmllint.cgi の位置へ全ファイルをアップロードする。

●htmllin.cgi、taglist.cgi のアクセス権限を755 に設定する。

○WindowのWebブラウザで、http://192.168.0.4/cgi-bin/htmllint/htmllint.cgi を開き、「Another HTML-lint error!」と表示されるか?

サーバエラー → (1) と (2) へ

○WindowsのWebブラウザで、http://192.168.0.4/cgi-bin/htmllint/htmllint.html を表示できるか?

できない →(3)へ

○htmllint.htmlのURL欄に「http://www.yahoo.co.jp」を入力し[check]する。結果が表示されたか?

「調整中です」 →(4)へ

(3) CentOSでsshログイン作業

CentOSインストール直後は、/cgi-bin/ 下は *.cgi、*.pl以外は表示できない。htmlやcssを表示できるように/etc/httpd/conf/httpd.confを編集する。

編集前

編集後

●webサーバを再起動する。

○WindowのWebブラウザで、http://192.168.0.4/cgi-bin/htmllint/htmllint.html を表示できるはず。

(4) CentOSでsshログイン作業

gccとPerlモジュールをインストールする。いろいろ聞かれたら yes または y を入力して進める。

○WindowsのWebブラウザで、http://192.168.0.4/cgi-bin/htmllint/htmllint.html を表示し、URL欄に「http://www.yahoo.co.jp」を入力し[check]する。結果を表示できるはず。

デプロイ先を切り替えてgit aws.pushする

【環境】

PC: Windows7、git、AWS Elastic Beanstalk Command Line Tool
サーバー: AWS ElasticBeanstalk

AWS ElasticBeanstalk(以下EBT)はロードバランサーとオートスケーリングサーバのパッケージである。コマンドプロンプトのgit aws.configでデプロイ先を設定し、git aws.pushでデプロイする。

デプロイ先が一つだけなら最初に1回だけgit aws.configをすればいいのだが、デプロイ先として本番環境、ステージング環境、開発環境など複数ある場合、毎回aws.configするのは面倒である。ここではデプロイ先を切り替えてgit aws.pushする方法を説明する。

環境1
AWSアカウント1>EBT>Application=hoge1-app>Enevironment=hoge1-env
環境2
AWSアカウント2>EBT>Application=hoge2-app>Enevironment=hoge2-env

【方法1】

環境1用のgitフォルダD:\hoge1、環境2用のgitフォルダD:\hoge2と別々に用意する。リモートリポジトリを経由してD:\hoge1とD:\hoge2を同期する。

D:\hoge1で開発作業、commit
D:\hoge1で環境1へgit aws.push

D:\hoge1でリモートリポジトリへpush

D:\hoge2でリモートリポジトリからpull
D:\hoge2で環境2へgit aws.push

※リモートリポジトリ
インターネットを介して複数人で作業する場合はgithubが便利である。無料プランは非公開リポジトリを作成できないが、有料プランにすると非公開リポジトリを作ることができる。
一人gitでLAN内作業の場合は、共有ドライブ(ローカルドライブでもよい)が手軽である。エクスプローラ右クリック>Git Create repository here>[Make it Bare]のチェックを付けると、リモートリポジトリが作成される。Git syncのRemote URLに共有フォルダのパス(Z:\gitrepos\hogeなど)を指定すればよい。

【方法2】

1つのgitフォルダ(以下、hogeとする)でデプロイ先を切り替える。

git aws.configは、hoge\.elasticbenstalk\configに設定内容を保存し、git aws.pushはこのconfigにしたがってデプロイする。

hoge\.elasticbenstalk\config

[global]
ApplicationName=hoge1-app
CredentialFile=C:\Users\taro\aws_credential_file
DevToolsEndpoint=git.elasticbeanstalk.ap-northeast-1.amazonaws.com
EnvironmentName=hoge1-env
Region=ap-northeast-1

そこで環境ごとのconfigファイルを用意しておき、バッチファイルでconfigにコピーし、git aws.push する。

まずconfigをコピペして、環境1のconfig-hoge1-env、環境2のconfig-hoge2-envを作成する。AWSアカウントが複数ある場合は、それぞれのaws_credential_fileも用意しておく。

hoge\.elasticbenstalk\config-hoge1-env

[global]
ApplicationName=hoge1-app
CredentialFile=C:\Users\taro\aws\account1\aws_credential_file
DevToolsEndpoint=git.elasticbeanstalk.ap-northeast-1.amazonaws.com
EnvironmentName=hoge1-env
Region=ap-northeast-1

hoge\.elasticbenstalk\config-hoge2-env

[global]
ApplicationName=hoge2-app
CredentialFile=C:\Users\taro\aws\account2\aws_credential_file
DevToolsEndpoint=git.elasticbeanstalk.ap-northeast-1.amazonaws.com
EnvironmentName=hoge2-env
Region=ap-northeast-1

次にバッチファイルを作成する。

hoge\git_awspush_1_hoge1-env.bat

copy .elasticbeanstalk\config-hoge1-env .elasticbeanstalk\config
git aws.push

hoge\git_awspush_2_hoge2-env.bat

copy .elasticbeanstalk\config-hoge2-env .elasticbeanstalk\config
git aws.push

環境1へデプロイしたいときは、hoge\git_awspush_1_hoge1-env.batを実行(またはダブルクリック)し、環境2へデプロイしたいときは、hoge\git_awspush_2_hoge2-env.batを実行(またはダブルクリック)する。

PHP5.3でMySQL接続エラー(old_passwords=1)

【環境】

接続元: PHP 5.3.20 (WebサーバA、新規)
接続先: MySQL 5.0.95 (MySQLサーバB、運用中)

【現象】

次のエラーが表示されてMySQLサーバに接続できない。
Warning (2): mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords flag from your my.cnf file [CORE\cake\libs\model\datasources\dbo\dbo_mysql.php, line 374]

xampp_1.5.4a(PHP5.1.4) → MySQLサーバB 接続OK
xampp_1.7.7(PHP5.3.8) → MySQLサーバB 接続ERR
コマンドプロンプトのmysqlコマンド → MySQLサーバB 接続OK
WebサーバA → 別のMySQLサーバ(MySQL5.5) 接続OK
つまりPHP5.3とMySQLサーバBの組み合わせで接続できない。新規のWebサーバAをPHP5.2やPHP5.1にすることはできない。

【原因】

PHP5.2から5.3になったとき、mysqlドライバ部分がmysqlndライブラリに変更された。mysqlndライブラリは41バイトのパスワードフォーマットを使用し、古い16バイトのパスワードフォーマットを使うとエラーを生成する。
http://php.net/manual/ja/migration53.incompatible.php

接続先のMySQLサーバのmy.cnfには old_passwords=1 が設定してあった。SELECT PASSWORD();を実行してみると16バイトのハッシュが表示された。またmysql.UserテーブルのPasswordカラムはchar(41)だが、保存されているデータは16バイトであった。

【検討】

新規のMySQLサーバの場合は、my.cnfのold_passwords=0にしてMySQLサーバを再起動し、DBユーザを新規作成したりパスワードを再設定すればよい。

ところがMySQLサーバBは運用中であり、DBユーザも登録されている。なるべく再起動せずにすむ方法、既存のDBユーザに影響しない方法を実施したい。本番サーバで操作する前に実験サーバで次の2つの確認をした。以下、WebサーバAから接続するDBユーザを ‘taro’@’%’、パスワード ‘1234’ とする。

【実験1】

1-1. old_passwords=0にしてMySQLを再起動し、既存のDBユーザ(16バイトハッシュ)で接続できるか?

mysqlコマンド 接続OK
PHP 5.2 接続OK
PHP 5.3 接続ERR

1-2. DBユーザ taro’@’%’のパスワードを設定する。

SET PASSWORD FOR taro@'%' = PASSWORD('1234');

1-3. DBユーザ ‘taro’@’%’ (41バイトハッシュ)で接続できるか?

mysqlコマンド 接続OK
PHP 5.2 接続OK
PHP 5.3 接続OK

【実験2】

2-1. 別のMySQLサーバ(old_passwords=0)を用意し、41バイトハッシュを生成した。

SELECT PASSWORD('1234');
*A4B6157319038724E3560894F7F932C8886EBFCF

2-2. 対象のMySQLサーバはold_passwords=1のままで、DBユーザのパスワードを41バイトハッシュにするために次のSQLを実行した。

SET PASSWORD FOR taro@'%' = '*A4B6157319038724E3560894F7F932C8886EBFCF';
を実行する。

2-3. mysql.userテーブルを表示して41バイトハッシュになっていることを確認した。

SELECT * FROM user WHERE Host='%' AND User='taro';

2-4. DBユーザ ‘taro’@’%’ (41バイトハッシュ)で接続できるか?

mysqlコマンド 接続OK
PHP 5.2 接続OK
PHP 5.3 接続OK

【まとめ】

実験1では、old_passwords=0 にしても既存のDBユーザの接続に影響がないことがわかった。
実験2では、old_passwords=0にしなくても、41バイトハッシュを設定することができた。

本番のMySQLサーバでは実験2の方法を実施した。

検索ワードをUTF-8からEUC-JP変換してnamazu検索する

namazu.cgiはUTF-8の検索ワードに対応していないので、UTF-8ページの検索フォームからnamazu検索すると、検索ワードが文字化けしてしまい、正しく検索できない。http://www.namazu.org/FAQ.html#set-server-encoding に、namazu.cgiはUTF-8の入力に対応していないと記述がある。

次の案1と案2を作成した。案2はphp.iniでallow_url_fopen = Onの必要があり、必要条件の少ない案1を採用した。

案1: 検索フォームからnamazu.phpへ送信し、namazu.phpで検索ワードをUTF-8からEUC-JPに変換し、namazu.cgiへリダイレクトする。
案2: 検索フォームからnamazu.phpへ送信し、namazu.phpで検索ワードをUTF-8からEUC-JPに変換し、namazu.cgiへhttpリクエストし、内容を返す。

他に次のような記事もあった。試していないが、参考のため残しておく。

php用のnamazu.so拡張モジュールを使う。
・2013-02-14 RHEL6でnamazuをインストールしてPHPから使う
http://www.mogumagu.com/wp/wordpress/?p=1217
・2010-02-06 namazu.soの作り方
http://zkangaroo.blogspot.jp/2009/03/namazuso.html

formタグのaccept-charset指定、jsでdocument.charset指定。
・2009-01-12 UTF-8のページでnamazuを使う
http://blog.digital-assist.net/?p=21

以下、案1について説明する。

(1) namazu.phpに保存してください。

$path(赤太字)を本来のnamazu.cgi の設置パスに修正してください。

(2) namazu.phpをサーバに設置してください。

動くならnamazu.cgiと同じディレクトリがわかりやすい。cgi-bin下でphpが動かない場合は、/namazu.php などに設置してください。

(3) utf-8ページの検索フォームのaction(赤太字)をnamazu.phpの設置パスに編集してください。

AWS RDS MySQLのtime zoneをcakePHPで設定する

【環境】

AWS RDS MySQL 5.5

【現象と要望】

AWSのRDSでMySQLサーバを起動し、日本時間2013-04-02 15:01 :00に “SELECT NOW();” を実行すると、”2013-04-02 06:01:00″と表示される。これを日本向けに”2013-04-02 15:01:00″と表示させたい。

【対応】

phpMyAdmin>変数を表示すると、time zoneはUTCであり、上記の「06:01:00」は正しい表示結果である。

time zoneを’Asia/Tokyo’または’+09:00’に設定すれば解決しそうだが、AWS Management Console>RDS>DB Parameter Groupsを見ると、default_time_zoneは変更不可と表示されている。

対応方法の一つとして、MySQLサーバ接続ごとに、またはSQL実行ごとに「SET @@time_zone=’+09:00′ 」を実行する方法がある。

cakePHP 1.2での対応例を紹介する。

※ソースそのままではなく記事用に編集してあるので、もしエラーが発生したら自分で対応してほしい。

【対応例】

(1) app/config/database.php

DATABASE_CONFIGのdriverの値をmysql_customに変更し、time_zoneを追加する。

(2) app/models/datasources/dbo_mysql_custom.php

ファイルを新規作成する。

AWS ElasticBeansTalkでのcakePHPのFULL_BASE_URL定数

【環境】

AWS ElasticBeansTalkのPHP 5.3サーバ
LoadBalancerでSSLを設定し、80→80、443→80とした。
cakePHP 1.2 アプリケーション。

【現象】

https://???.elasticbeanstalk.com/blogs/first にアクセス

アクション内で $this->redirect(‘/blogs/second’);

https://???.elasticbeanstalk.com/blogs/second へリダイレクトするはずが、
http://???.elasticbeanstalk.com/blogs/second へリダイレクトしてしまう。

【原因】

レスポンスヘッダを確認すると、
Location: /blogs/second
ではなく、
Location: http://???.elasticbeanstalk.com/blogs/second
であった。
webブラウザからLoadBalancerへ443ポートアクセスしても、LoadBalancer配下のサーバには80ポートアクセスであり、環境変数 HTTPS は設定されない。そのためcakePHPはhttpアクセスと判断し、httpから始まるURLをFULL_BASE_URL定数を定義してしまう。

【対策例1】

cakePHPがFULL_BASE_URL定数を定義してしまう前に、アプリケーションでFULL_BASE_URL定数を定義する。

app/webroot/index.php の
「if (!include(CORE_PATH . ‘cake’ . DS . ‘bootstrap.php’)) {」
より先頭側に次のスクリプトを挿入する。

【対策例2】

.htaccess で、環境変数HTTPS を設定する。アプリケーション内で環境変数HTTPSを参照している全ての箇所でHTTPSと判断させることができる。

SetEnvIf x-forwarded-port  “^443$” HTTPS=on
SetEnvIf x-forwarded-proto “^https$” HTTPS=on