2009年1月26日月曜日

PHPの DateTimeZoneオブジェクトで時差のある時間を計算

日本の時間でDateTimeオブジェクトを生成して、時差のある地域の現地時間を求める方法。

setTimeZone('EST') とかできそうだけど、わざわざDateTimeZoneオブジェクトを生成しないといけない。

//日本の現在の時刻とアメリカ東海岸の現地時刻の比較
$dt = new DateTime('now');
echo $dt->format('r'); //日本の時間(デフォルトはAsiz/Tokyoにしてあるので)
echo "<hr />\n";
$dt->setTimeZone(new DateTimeZone('America/New_York'));
echo $dt->format('r'); //アメリカ東海岸の時間

//向こうの現地時刻から日本の時刻に変換する場合
$dt = new DateTime('2008-12-09 23:22:44', new DateTimeZone('America/New_York'));
$dt->setTimeZone(new DateTimeZone('Asia/Tokyo'));
echo $dt->format('r');
このあたりのマニュアル、分かり辛い。

また、夏時間も自動で考慮してくれるようだ。
for ($i = 1; $i < 13; $i++) {
 $dt = new DateTime("2008-$i-11 0:00");
 echo '[日本] ' . $dt->format('Y-m-d H:i:s');

 $dt->setTimezone(new DateTimeZone('America/New_York'));
 echo ' [EST] ' . $dt->format('Y-m-d H:i:s');

 echo ' [offset] ' . ($dt->getOffset() / 60 / 60) . '時間<br />';
}
(結果)アメリカのサマータイムって3月から10月なんだ。
[日本] 2008-01-11 00:00:00 [EST] 2008-01-10 10:00:00 [offset] -5時間
[日本] 2008-02-11 00:00:00 [EST] 2008-02-10 10:00:00 [offset] -5時間
[日本] 2008-03-11 00:00:00 [EST] 2008-03-10 11:00:00 [offset] -4時間
[日本] 2008-04-11 00:00:00 [EST] 2008-04-10 11:00:00 [offset] -4時間
[日本] 2008-05-11 00:00:00 [EST] 2008-05-10 11:00:00 [offset] -4時間
[日本] 2008-06-11 00:00:00 [EST] 2008-06-10 11:00:00 [offset] -4時間
[日本] 2008-07-11 00:00:00 [EST] 2008-07-10 11:00:00 [offset] -4時間
[日本] 2008-08-11 00:00:00 [EST] 2008-08-10 11:00:00 [offset] -4時間
[日本] 2008-09-11 00:00:00 [EST] 2008-09-10 11:00:00 [offset] -4時間
[日本] 2008-10-11 00:00:00 [EST] 2008-10-10 11:00:00 [offset] -4時間
[日本] 2008-11-11 00:00:00 [EST] 2008-11-10 10:00:00 [offset] -5時間
[日本] 2008-12-11 00:00:00 [EST] 2008-12-10 10:00:00 [offset] -5時間


タイムゾーンは"EST"とかの方が分かりやすいが、
ここに挙げられているタイムゾーン (UTC 以外のもの) は使用しないでください。 これらは過去のバージョンとの互換性のためにのみ残されています。
とあるのでやめましょう。


参考:
 PHP: timezone_open - Manual
 PHP: date_timezone_set - Manual

.htaccessでPHPのエラーログ設定をする方法

例えばこんな感じで。
flagとvalueを使い分ける。

php_flag display_errors On
php_flag log_errors On
php_value error_log /var/www/log/php_error.log

参考:PHPのエラーログについて PEAR::Logでエラーログを取りたいです(中略)人力検索はてな

CakePHPで pagesを使う

基本
CakePHPでContorllerを使うまでもないページ(静的な表示が中心のページ)を作りたい場合、pagesを使うと便利。
(例:サイトの紹介ページ、利用規約、などなど。)
views/pagesの中にxxxx.ctpというファイル名でVIEWテンプレートを入れておけば、/pages/xxxx というURLでアクセスできる。
Controllerは作成しなくてOK。
(config/routes.phpに下記設定があるため。PagesControllerはCakeの標準機能として装備されている。)

Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
このpages内のVIEWテンプレートにもlayoutsは適用される。


タイトルタグをセットする
VIEWテンプレート内で、<?php $this->pageTitle = 'タイトル' ?> とすればタイトルタグをセットできる。


pagesからModelを呼び出す
pagesのVIEWテンプレートの中でimportする。
App::import('Model', 'Member');
後は普通のPHPクラスと同じようにnewすれば使えた。


セキュリティ上の注意
デフォルトでは /pages/home というURLで内部情報を表示してしまう。
pagesを使わない場合は、config/routes.phpのpagesへの設定を削除すればOK。
pagesを使う場合は、view/pagesにhome.ctpを作ればとりあえず害は無くなる。


参考:
 CakePHP 静的なページの作成方法 | Sun Limited Mt.
 CakePHP 公開する時はデバッグ情報を出さない | Shin x blog

PHPの file_get_contents()が成功する HTTPステータスコード

PHPのfile_get_contents()でhttp経由でデータを取得する場合、HTTPステータスコードによっては取得が失敗になる。(Warningが出て、戻り値がfalseになる。)
取得が失敗しないHTTPステータスは以下の通り。(数字の部分で判断するので、後ろの文字列は何でもよいが参考までに載せておく。)

  • 200 OK
  • 206 Partial Content
  • 301 Moved Permanently
  • 302 Moved Temporarily
  • 303 See Other

206が意外。

WWW SQL Designer 2.3.2 変更メモ

WWW SQL Designerのバージョンが2.3.2に上がっていたのでUPDATE。
そこで、自分でカスタマイズした点を反映するメモ。やりたい変更内容は以前のバージョンと同じ。

参考:
 floatingdays: WWW SQL Designerのインストール&設定
 floatingdays: WWW SQL Designerの Save ・ Loadをスマートに改良


変更箇所
(全角のスペースは普通のインデントに変換してから使うこと!)

  • js/config.js
    • 9行目の変更:デフォルトの保存方法をファイルに変更
      DEFAULT_BACKEND:["php-mysql"],

      DEFAULT_BACKEND:["php-file"],
  • js/wwwsqldesigner.js
    • 1201行目を変更:保存時のプロンプトにURLから保存名を取得して表示する
      var name = prompt(_("serversaveprompt"),"");

      var name = prompt(_("serversaveprompt"), location.href.split("=")[1]);
    • 1212行目に追加:ロード時のURLの後ろにに保存名を付ける
      if (!keyword) {
       var name = prompt(_("serverloadprompt"),"");
       if (name) {
        location.href = "?keyword=" + encodeURIComponent(name);
       }
       return;
      }
    • 1538~1539行目の変更:外部キーはどのフィールドでも作成可能にする
      this.dom.foreigncreate.disabled = !(this.selected.isPrimary());
      this.dom.foreignconnect.disabled = !(this.selected.isPrimary());

      this.dom.foreigncreate.disabled = false;
      this.dom.foreignconnect.disabled = false;

Windowsに PHP eAcceleratorをインストールメモ

インストールのメモ。PHPは5.2.8。


インストール手順

  1. Apache on Windows binaries and modules downloadからZIPをダウンロード(現時点の最新版(5.2.8)にしか対応していない?)
  2. ZIPを解凍(展開)して、eaccelerator.dllをPHPのextフォルダに移動またはコピー
  3. ZIP内にあるcontrol.phpをWebブラウザで見られる場所に移動またはコピー(例:C:\apache\htdocs\test\control.php)
  4. control.phpの変数$userと$pwの値を適切なものに変える(この認証を使わないなら該当箇所をコメントアウトする)
  5. control.phpではshort_open_tagの"<?="を使ってるので、これを許可していない場合は"<?php echo "に置換する
  6. キャッシュ用のフォルダを作成(例:C:\temp\cache\ea)
  7. php.iniに設定を追加
    (例)
    [eAccelerator]
    extension="eaccelerator.dll"
    eaccelerator.allowed_admin_path="/apache/htdocs/test/control.php"
    eaccelerator.shm_size="64"
    eaccelerator.cache_dir="/temp/cache/ea"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.filter=""
    eaccelerator.shm_max="0"
    eaccelerator.shm_ttl="0"
    eaccelerator.shm_prune_period="0"
    eaccelerator.shm_only="1"
    eaccelerator.compress="0"
    eaccelerator.compress_level="9"
  8. Apacheを再起動
  9. control.phpにアクセス(4.で設定したユーザー情報でログインする)
  10. control panelがエラー無く表示されていればインストール完了



php.iniの設定について
  • [eAccelerator]は無くても良いがあった方がわかりやすい。
  • allowed_admin_path・・・手順3で移動したPHPのパス
  • shm_size・・・0にすると「デフォルト値」が適用される(手元の環境では32MBだった)
  • check_mtime・・・0にするとPHPを更新してもキャッシュをCleanするまで更新が反映されない
  • filter・・・キャッシュ対象を絞り込める
  • compress・・・1にすると圧縮するが、どちらがよいかは状況によるらしい



control.phpでの操作
  • Caching・・・キャッシュの有効/無効の切り替え
  • Optimizer・・・最適化の有効/無効の切り替え
  • Clear cache・・・キャッシュを全て削除
    Remove all unused scripts and data from shared memory and disk cache, this means all data that isn't used in the current requests.
  • Clean cache・・・期限切れのキャッシュを削除


    Remove all expired scripts and data from shared memory and disk cache.


  • Purge cache・・・削除対象としてマークされたキャッシュを削除?


    Removed all scripts that are marked for deletetion. This will happen automaticly when shared memory is needed.





使ってみた感想
control.phpでキャッシュされる様を眺めるのが楽しい。
WordpressとかCakePHPとか、ファイルサイズ大きすぎ。


それから、control.phpでやっている認証はBasic認証なので、気持ち悪かったらApacheでDigest認証やその他のアクセス制限をかけた方が良さそう。



参考

PHPで Windowsのメモリ使用量を取得する方法

準備

  1. pecl4win(現在サイトがダウンしている)かhttp://snaps.php.net/win32/からPECLの該当バージョンを取得する。

  2. php_win32ps.dllをPHPのextフォルダにコピーし、php.iniの設定でこのExtensionを有効にする。


メモリ使用量の取得方法
win32_ps_stat_mem()で取得する。


$stat = win32_ps_stat_mem();
echo '現在メモリを' . $stat['load'] . '%使用中です。';


CPU使用率はどうやれば取得できる?


参考:PHP: win32_ps_stat_mem - Manual

MySQLで INSERT時に重複する KEYが既に存在する場合の動作のオプション


INSERT IGNORE INTO ...

(効能)重複するKEYが既に存在する場合、データは登録されない

INSERT IGNORE INTO members(id, name) VALUES(2, 'TARO');


INSERT INTO ... ON DUPLICATE KEY UPDATE ...
(効能)重複するKEYが既に存在する場合、そのデータをUPDATEする
INSERT INTO members(id, name) VALUES(2, 'TARO') ON DUPLICATE KEY UPDATE cnt = cnt + 1;


REPLACE INTO ...
(効能)重複するKEYが既に存在する場合、そのデータをDELETEしてからINSERTする(※UPDATEではない)

REPLACE INTO members(id, name) VALUES(2, 'TARO');


いずれも、重複するKEYが存在しなければ普通のINSERT文と同じ結果になる。



参考:MySQL :: MySQL 4.1 リファレンスマニュアル :: 6.4.3 INSERT 構文

v8cgiのインストールと簡単なサンプル

v8cgiWWW SQL Designerを作ったondrej.zara氏が作ったサーバサイドJavaScript実行環境&ライブラリ。
CGI感覚で手軽にJavaScriptでWebプログラムが書ける。(さらに、テンプレート機能を使えばPHP感覚で書ける。)

ソースとWindows用のバイナリが配布されている。
メールライブラリや画像ライブラリ(GD)、テンプレートライブラリなどが付属している。


Windowsへのインストール
(参考:Installation - v8cgi - How to install v8cgi - Google Code

  1. v8cgi - Google CodeからZIPをダウンロード。展開して適当なフォルダに置く。(例:C:\test\v8cgi)
  2. v8cgi.confをCドライブの直下(コンパイル時に指定された場所)に移動する。
  3. v8cgi.confの中身を編集。(パスを環境に合わせる。)
    (例)
    // put default .js and .dll files here
    Config["libraryPath"] = "c:/test/v8cgi/lib";
  4. コマンドプロンプトからv8cgi.exeを実行してみる。エラーが無ければOK。
    C:\test\v8cgi>v8cgi.exe
    Nothing to do.
  5. Apacheの設定ファイルhttpd.confにCGI実行の設定を追加。
    (例)
    <Location /v8cgi>
     Options +ExecCGI
     AddHandler cgi-script .ssjs
    </Location>
    ※mod_cgiが有効になっていなかったら有効にしておく。
    LoadModule cgi_module modules/mod_cgi.so
  6. Apacheを再起動。
  7. Webのディレクトリにテスト用のScriptを作る。(例:htdosc\v8cgi\exaple.ssjs)
    (例 1)
    #!/test/v8cgi/v8cgi.exe
    response.write("Hello v8cgi!");
     ※responseオブジェクトはデフォルトでインスタンスが生成されている。(参考:API_HTTP - v8cgi - Library "http.js" - Google Code
    (例 2)
    #!/test/v8cgi/v8cgi.exe
    System.stdout("Content-type: text/plain\n\n");
    System.stdout("Hello v8cgi!");
     ※response.writeを使わない場合、Content-typeを出力しないと500 Internal Server Error(Premature end of script headers: example.ssjs)になる。
  8. 上記のファイルにアクセスしてみる。エラーが無ければOK。



DBを使う例
#!/test/v8cgi/v8cgi
library("mysql.dll");
library("query.js");

Query.setDB(new MySQL().connect("localhost", "db_user", "db_password", "schema"));

var result = new Query(Query.SELECT)
 .field("id").field("name") //SELECT
 .table("members") //FROM
 .where("%f = %s", "name", "TARO") //WHERE
 .execute();

response.write(result.numRows() + "<br>");

var rows = result.fetchObjects();
for (var i = 0; i < rows.length; i++) {
 response.write(rows[i]["id"] + ":" + rows[i]["name"] + "<br>");
}


テンプレートを使う例
テンプレートを呼び出すファイルの記述
#!/test/v8cgi/v8cgi
library("template.js");

var t = new Template({suffix: "tpl.html"}); //現行バージョン(0.2.0)にはバグがあるのでsuffixを指定しないとエラーになる
var var1 = "abc"; //動的なデータは変数に入れておけばテンプレート内から参照できる
var var2 = 123;
response.write(t.process("example")); //現行バージョン(0.2.0)ではdataを渡しても無視される

テンプレートの記述(example.tpl.html)
<html>
<head><title>TEST</title></head>
<body>
This is a random number: $(Math.random())

$code( for(var i = 0; i < 10; i++) { )
<li>$(i)</li>
$code( } )

$(var1) $(var2)
</body>
</html>


REQUEST情報を取り出す方法
"HTTP_"で始まる情報はrequest.header()で取り出せるが、それ以外は直接_headersの中から取り出すしか無さそう。
#!/test/v8cgi/v8cgi
response.write(request._headers["SCRIPT_URL"]);


感想
  • シンプルでよい。ソース追って理解できる。
  • DBアクセス、テンプレートエンジン、メール送信と揃っていて、即戦力っぽい。
  • DAOがORマッパーでなくSQLヘルパーなのが好き。さすがERDを描くためにツールを作ってしまった人だけある。
  • DBアクセスがプレースホルダーでないのが残念。escapeはしているようだがPreparedでないと何かと嫌。

  • response.writeってのがASPみたいでちょっと嫌。echo()とかでラップすればよいが。
  • 実際に使うとしたらmod_rewriteを絡めたオレームワーク(オレオレ・フレームワーク)を被せることになりそう。



参考:Apache Tutorial: CGI による動的コンテンツ - Apache HTTP サーバ

2009年1月22日木曜日

Google ChromeでなぜかQueryStringを含むURLを見られないと思ったら

ChromeでQueryStringを含むURLを見ようとするとしばしば「404 Bad Request」になってしまうことがあり、調べたらIEと同じ現象らしい。

/~sugano/ » Google ChromeのDigest認証

IEへの対応は、Apacheいじり始めてすぐに入れたのでそういうものだと思ってたけど、まさかこんなところで再開するとは。

2009年1月9日金曜日

Googleがホスティングしてくれる JavaScriptライブラリに YUIが追加されていた

Serving YUI Files from Yahoo! Serversを見たら、CDN欄にいつの間にかGoogleが...。Google+Yahooのコラボレーションがこんなところで実現。
Developer's Guide - AJAX Libraries API - Google Codeを見たら、YUIの他、SWFObjectも追加されていた。

google.load()によるYUIのロードは、 YUI Loaderが対象のようだ。
Google AJAX API Loader(http://www.google.com/jsapi) をロードして、それでYUI Loaderをロードして、それでYUIのコンポーネントをロードして...なんか冗長だ。

静的なホスティングもしてくれるようだが、それだとYahooによるホスティングと変わらない。バージョン番号をワイルドカードにできれば嬉しいんだけど...。CSSは静的なロードしかできなさそうなのが残念。

ところでYUI3は2009年にGAを出す予定みたい。また大きく変わるのかな。

ブログ アーカイブ

tags