SixCoreでのPHP個別設定

いろんなレンタルサーバを借りている。レンタルサーバも様々、各社各様設定方法もいろいろあるようだ。現在、株式会社ベットが提供する安価なレンタルサーバでプログラムを開発している。ここの会社には2種類のサービスがあり、それらはXserver(廉価版)とSixCore。たいていの場合は同じ会社であれば、たいてい設定に関するやり方は同じなのだが、この2つの場合はそうではなかった。

phpのエラーを表示させたいのだが、デフォルトでは非表示だ。PHP設定の変更は、一般的には.htaccess内に記述するのだが、この会社のサーバはphp.iniとうファイルを作成してその中に記述することになる。そして、その設定は、ファイルを設置したディレクトリ内のファイルだけに有効となり、下の階層には同様にphp.iniを設置してやらなくてはいけない(一番上の階層に置いた場合はその必要はないみたい)。

同じように、SixCoreの場合でもphp.iniを作成して設置してみた。変化なし。おいおい、と思って調べてみて思い出した。わざわざ.htaccessファイルに「追加設定はここに置きました」というお知らせを書かなくてはいけない。

suPHP_ConfigPath /home/ユーザ名/ドメイン名/php.ini設置ディレクトリ/

はぁ。suPHPなわけですが、わざわざ書かなくちゃいけないんですね。同じような失敗を前にもした記憶があります。ということでメモしておきます。



AWSの署名でSignatureDoesNotMatchエラー

3日間も悩んで、結果すごくおバカなミスだったという話。

Amazon Web ServiceでREST形式でいろいろできる手法に署名(Signature)をつけるよう仕様が変更される。8月15日までは移行期間で、それ以降はRESTに署名をつけないと処理されなくなる。そこで早めに対応しておこうと処理を書いてみた。

$secretKey=’0123456789′; // AWSより提供されたSecret Access Key
$url= ‘http://ecs.amazonaws.jp/onca/xml';
$parameters=array(‘Service’=>’AWSECommerceService’, ‘Version’=>’2009-03-31’………);  //必要なパラメータ
$parameters[‘Timestamp’]=gmdate(‘Y-m-d\TH:i:s\Z’); //タイムスタンプが必要になった
ksort($parameters); //署名の際、クエリの並び順も関係するのでソートしておく
//クエリの組み立て
$query=”;
foreach($parameters as $id => $value){
$query.=’&’.$id.’=’.str_replace(“%7E”,’~’,rawurlencode($value));
}
$requests=parse_url($url);
//署名のための文字列を生成して署名を作る
$string4sign=”;
$string4sign.=”GET\n”;
$string4sign.=$requests[‘host’].”\n”;
$string4sign.=$requests[‘path’].”\n”;
$string4sign.=$query;
$signature=str_replace(“%7E”, ‘~’, rawurlencode(base64_encode(hash_hmac(‘sha256′, $string4sign, $secretKey, true))));
$url.=’?’.$query.’&Signature=’.$signature;

このスクリプトは最終的に動作したもの。しかし最初に書いたスクリプトで$urlにアクセスしても「SignatureDoesNotMatch」。なぜだ。

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

Secret Access Keyが間違っているか、署名方法が間違ってるよ、といわれる。何度も何度も微調整して、他のサイトも参考にしたけど理由がわからなくて、3日間も悩んでしまった。間違っていた箇所は2つ。

(1) ちゃんとエンコードした値を渡す。
$query.=’&’.$id.’=’.str_replace(“%7E”,’~’,rawurlencode($value));

動かなかったスクリプトではちゃんとRFCにそったエンコードをかけていなかった。んで、ここはとりあえず解決。そしてもっと致命的なミスがあった。

(2) Access Keyが違う!。

そもそもなんで違うアクセスキーを使っていたのかがわからない。ていうか、どこでそのアクセスキーを取得したのかもわからない。すべて謎。たぶんどっかのスクリプトをコピペした際に、アクセスキーを書き換えるのを忘れていたんだと思う。「コピペ元の方、ごめんなさい」という感じだ。ま、そもそもAccess KeyとSecret Access Keyの組み合わせが違うんだから絶対に署名があうわけないのだ。

前者のミスは早々に気がついていたのですぐに修正したけれど、それでも動作しないから「記述方法が悪いんじゃないか」と思ったり、署名用の文字列の作り方が悪いんじゃないか、と思ったりで後者のミスに気がつかなかった。というか、そもそも間違えているなんて夢にも思わなかった。

結果的に2つもミスがあったので、ほんと3日間も悩んでいてバカみたいだった。でも、スッキリ。

配列にフィルタリングして必要な値だけ取り出す

2009/05/08 | PHPの基本

配列を処理するならたいていの場合foreachだ。ループ処理するのが簡単。でもPHPでは配列を処理するための関数がいろいろ用意されている。常識的に考えれば、それらの関数を使ったほうが早く動作するはず。

array_filterという関数を見つけた。というか前から興味を持っていた関数だ。配列をループ処理し、各値の要不要を判断して間引いてくれる関数だ。この間引き処理で、foreachを使うよりarray_filterのほうがどのくらい早くなるのか試してみた。

(1) foreachの場合
$filtered=array();
foreach($values as $value){
  if($value[‘age’]>3){
    $filtered[]=$value;
  }
}

(2) array_filterの場合
function age($value){
  if($value[‘age’]>3){
    return true;
  }else{
    return false;
  }
}
$filtered=array_filter($values,’age’);

と二つのサンプルで比べてみた。結果・・・foreachのほうが倍くらい早かった。おいおい。なんでだろ。(2)だと関数を読んでるから遅くなるのかな。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net