2007年10月27日土曜日

Services_Delicious#getAllPosts()でタグを指定する

Services_Delicious#getAllPosts()でタグを指定できない問題 を回避するclassをサブクラスとして作ってみた。

require_once('Services/Delicious.php');

/**
* Services_DeliciousPatched
*
* This is a class to resolve the bug #10062 of Services_Delicious.
*/
class Services_DeliciousPatched extends Services_Delicious {
/**
* @see Services_Delicious#getPosts
*/
public function getAllPosts($tags = array(), $date = null) {
$params = array();
if (!empty($tags)) {
$params['tag'] = $tags;
}
if (!empty($date)) {
$params['dt'] = $date;
}

$result = $this->_sendRequest('posts', 'all', $params);
if (PEAR::isError($result)) {
return $result;
}

$posts = array();
foreach ($result['post'] as $post) {
$post['tag'] = explode(' ', $post['tag']);
array_push($posts, $post);
}

return $posts;
}
}

それにしてもdel.icio.usのAPIってログインを要求するんだね。

Apacheでログを年月別のファイルにする方法

(2007/11/05:変更
 ローテーションのトリガーをファイルサイズから時間に変更。こうしないと年月単位のログにならない
 ここで指定する時間は、1970/1/1 0:00:00からの経過時間を元に計算される。Apacheを起動/再起動してからの時間ではない。
 また、GMT以外の日付を使う場合は"-l"オプションを付ける。
 参考:[Apache-Users 6474] Re: rotatelogs の時刻設定

Apache付属のrotatelogsを使えば簡単にできる。
httpd.confで、CutomLogの設定を下記のようにする。

CustomLog "|bin/rotatelogs logs/access.%Y%m.log 5M" common
CustomLog "|bin/rotatelogs -l logs/access.%Y%m.log 86400" common

ファイルサイズ(この例では5MB)は環境に合わせて変える。
最後のcommonのとこは忘れがちなので注意。(これも状況に合わせて変える。)
envとか付けたいなら付けられるのは普通のCustomLogと一緒。

マニュアルを見るとErrorLogについてもできるようだが、Apache2.2.5/Windowsの環境ではできなかった。(Apacheが起動しなかった。)
でもよく考えたらエラーログはそんなに肥大化しないから、ローテーションする必要ない。


(2007/11/01 追記)
rotatelogsを使うと、Windowsのプロセスがどんどん増えていった。Apache2.2.4~2.2.5のバグ?(Apache 2.2.4でrotatelogs - 負けないように頑張る日記
Apacheを2.2.6に上げたら解消された。

PHPのstaticな変数の値の保持期間

PHPのclassでstaticな変数を使う場合、その値が保持されるのはそのセッションのみ。
つまり、インスタンス変数(classのstaticでない変数)と同じ期間だけ。

セッションが変わると、同一クラスに"再アクセス"しても値は初期化されている。
もちろん他のクライアントからのアクセスでも値は初期化されている。

Java等のstaticな変数とは違うので注意。

2007年10月19日金曜日

PHPで(できるだけ)正しいメールアドレスをチェックする正規表現

2008/02/07 修正 (

  • Blogger投稿時に、バックスラッシュ2つが1つに変換されていた(全角で掲載することにより回避。全角の¥は半角に読み替えてください!)
  • domainの先頭は数字でもOKにした(ドメイン制限の緩和に合わせた)
  • domainのlabelの最後に?を追加(漏れていた)



何回か挫折したけどもう一度チャレンジしてみた。
RFC 2822を読み解くのは辛いので、基準として「正しい方法」でメールアドレスを確認するには - J0hn D0e の日誌に書いてある『「正しいメールアドレスの条件」10か条』をなるべく満たすことを目指した。

できたのはこれ。
preg_match('/^([-!#-¥¥'*+¥¥/-9=?^-~]+(¥¥.[-!#-¥¥'*+¥¥/-9=?^-~]+)*|"([]-~!#-[]|¥¥¥¥[ -~])*")@[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?(¥¥.[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?)*¥¥.([a-z]{2,4}|museum)$/i', $value)


10か条のうち、1~4と6~8を満たしている(と思う)。
以下は未対応
  • 10は正規表現では無理
  • 5と9も正規表現では無理だよね?
  • 3(quoted-string)については、RFC 2822を見た感じではlocal-part全体がquoted-stringの場合のみ使えるように見えるけど、symfonyではlocal-partの一部としてもquoted-stringを許しているのは何故?
  • 4(quoted-pair)については、RFC 2822を見た感じではquoted-string内でのみ使えるように見えるけど、「正しい方法」でメールアドレスを確認するにはを読んだ感じだとlocal-part内ならどこでも使えるみたいに書いてあるからそうなのかな???

現実問題としては、DoCoMo(Softbankも?)はRFC2822違反のメールアドレスでも登録できてしまうので、下記のような"DoCoMo版メールアドレス"は上記の正規表現ではエラーになってしまう。
  • ドットで始まる
  • ドットが連続する
  • @の前がドット


ついでに、上記の正規表現を生成したPHPのソースコードはこちら。
(コメントの番号は10か条の番号に対応)
<?php
if (!$m = $_REQUEST['m']) $m = 'test@example.com';

//local part
$atext = "[-!#-'*+/-9=?^-~]";
$atom = $atext . '+';
$dot_atom = $atom . '(¥¥.' . $atom . ')*'; //2

$qtext = '[]-~!#-[]';
$text = '[ -~]';
$quoted_pair = '¥¥¥¥' . $text; //4
$quoted_string = '"(' . $qtext . '|' . $quoted_pair . ')*"'; //3

$local_part = '(' . $dot_atom . '|' . $quoted_string . ')';

//domain
$label = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?'; //7, 8
$domain = $label . '(¥¥.' . $label . ')*¥¥.([a-z]{2,4}|museum)'; //6

//全体
$addr_spec = $local_part . '@' . $domain; //1

$regexp = '/^' . str_replace('/', '¥¥/', $addr_spec) . '$/i';
?>

正規表現<br />
<?php echo $regexp; ?>
<hr />

preg_match('<strong><?php echo str_replace(array("'", '¥¥'), array("¥¥'", '¥¥¥¥'), $regexp); ?></strong>', $value)
<hr />

<form action="regex.php">
<input name="m" value="<?php echo htmlSpecialChars($m, ENT_QUOTES); ?>" />
は、正し<?php echo (preg_match($regexp, $m) ? 'い' : 'くない') ?>メールアドレスです。
</form>


一般的には、これくらいやれば十分でしょう。
preg_match('/^[-+¥¥w]+(¥¥.[-+¥¥w]+)*@[-a-z0-9]+(¥¥.[-a-z0-9]+)*¥¥.[a-z]{2,6}$/i', $value)


DoCoMoも救済するならもう少しシンプルになる。実際に使うならこれで。
local-partに入れる記号は"-_."くらいが一般的で、Gmailerは"+"も使うからそれぐらい対応すれば99%くらいはカバーすると思う。これでダメなメールアドレスは弾いちゃった方が何かと安心な気がする...。
preg_match('/^[-+.¥¥w]+@[-a-z0-9]+(¥¥.[-a-z0-9]+)*¥¥.[a-z]{2,6}$/i', $value)


参考:
 「正しい方法」でメールアドレスを確認するには - J0hn D0e の日誌
 http://www.puni.net/~mimori/rfc/rfc2822.txt (Internet Message Format)
 ASCII文字コード : IT用語辞典
 正規表現
 perlre - Perlの正規表現
 re: PHPでメールアドレスかどうか調べる方法 (ハズレ日記)

2007年10月18日木曜日

redirectとrewriteが競合した場合

Apacheの設定で、redirectとrewriteが競合した場合はrewriteが適用される。
redirectの方を先に書いていても、rewriteが適用される。
この場合にredirectさせたかったら、rewriteの[R=301,L]を使ってredirectさせればOK。

TracのWikiで外部サイトへのリンクを別Windowで開くGreasemonkey

TracのWikiで外部サイトへのリンクをいちいち別Windowで開くのが面倒で、でも対策を探したけど見つからなかったのでGreasemonkey作ってみた。
Bloggerで添付ファイルのやり方がわからない(できない?)のでソースコードをそのまま書いておく。


このGreasemonkeyの仕様

  • Trac内へのリンクは同一Windowで開く
  • Trac外へのリンクは新しいWindowで開く
  • Trac内か外かは、ドメインとドメイン直下のディレクトリが同じかどうかで判断する
    • 例:現在地(Trac内のWikiページ)が http://example.com/trac/sample の場合
      • http://example.com/trac/sample/wiki/page → Trac内
      • http://example.com/foo/sample/wiki/page → ドメイン直下のディレクトリが違うのでTrac外
      • http://www.google.com/trac/sample/wiki/page → ドメインが違うのでTrac外
      • https://example.com/trac/sample/wiki/page → スキームが変わってもドメインとディレクトリが同じなのでTrac内
  • 対象ページは http(|s)://*/trac/* にしているので、ここは必要に応じて適宜変更する


ソースコード
// ==UserScript==
// @name Trac_newWindowOpener
// @namespace http://fdays.blogspot.com/
// @description A script to open a page in the new window on "Trac".
// @include http://*/trac/*
// @include https://*/trac/*
// ==/UserScript==
(function(){
var current = location.href.split("/");
var domain = current[2];
var dir = current[3];
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
var link = links[i];
var href = link.href.split("/");
if (href[2] != domain || dir != href[3]) {
link.target = "_blank";
}
}
})();

2007年10月11日木曜日

LinuxへのCPANモジュールのインストール方法

 Perlのライブラリ(モジュール)群であるCPANをLinuxへインストールする方法。

まずはCPANシェルを起動する
 Techknow Movable Type: CPANモジュールのインストール方法

そのままだとCPANシェルのモジュールのダウンロード先の設定が空だったので、その設定をする
 K's Lablog - URLリスト

ダウンロード先はここから選ぶ
  CPAN/SITES

 ちなみにシーパン派です。

2007年10月6日土曜日

PDOでDSNのエイリアスを使う方法

PDOを生成する時はDSNのエイリアスを使うのが一番スマートだと思う。

一般的なPDOの生成方法

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);

エイリアスを使うPDOの生成方法
php.iniに下記の記述をしておく。"pdo.dsn."の後ろがDSNのエイリアスになる。
[PDO]
pdo.dsn.mydb="mysql:dbname=testdb;host=localhost"
そうすると$dsnとして下記のようにエイリアスを指定できる。
$dsn = 'pdo_dsn';
$dbh = new PDO($dsn);

エイリアスを使うメリット
  • 複数の環境(開発環境と本番環境とか)で別のDB接続情報を使う場合に、PHPソースを変更せずに済む。
  • DB接続情報の定義場所が分かりやすい。
  • ディレクトリセキュリティの掛け方によっては、DB接続情報を隠蔽できる。
(2007/10/11 追記
 MySQLの場合、ユーザー・パスワードはDSNに含められないようです。
 参考:[ThinkIT] 第1回:PDOの概要 (3/3)びーこん:PDO MySQL (PHP PECL) - livedoor Blog(ブログ)

エイリアスを使うデメリット
  • DB接続情報を変更するたびにWebサーバの再起動が必要。
  • DB接続情報の種類が多い場合に柔軟に対応できない。(dbnameだけ変えるとか。)命名規則を決めれば対応できるけど。


参考:PHP: PDO->__construct() - Manual

XMailでRFC違反のDoCoMoのメールアドレスに送受信

 XMailで下記のようなメールアドレスに送受信できないという問題が発生。

  • ドットが連続する (例:foo..bar@docomo.ne.jp)
  • アットマークの前にドットがある (baz.@dodomo.ne.jp)
 これらはRFC2822というメールアドレス(の一部?)の規約に反してるらしい。

 同じ問題で困っている人はいるらしく、探してみたらxmailserver.jpの掲示板で見つけた。
  RFC2822違反のメールアドレス

 要約すると、

 Postfixでも同様の問題が発生するけど設定で回避可能、sendmailやqmailではこの問題は発生しないらしい。
 XMailは海外のソフトだから東洋の島国の1キャリアの勝手に付き合って仕様を変えてくれないだろうな。今後はXMailがバージョンアップするたびに誰かがパッチを作り続けるのかな...

CPANシェルによるCPANモジュールのインストール方法

CPANモジュールはCPANシェルでインストールするのが楽。

Techknow Movable Type: CPANモジュールのインストール方法

でもCPANシェルをセットアップして、そのままCPANモジュールをインストールしようとすると下記のエラーが出まくる...

anonymous としてログインしています...
サーバの応答にエラーがあるので、接続を終了します。
デフォルトではダウンロード元のURLリストが空になってるみたい。
K’s Lablog - URLリストを参考にURLリストを設定する。
URLリストに設定するURLはCPAN/SITESから選ぶ。

URLリストのことは、よく見ると最初の参考サイトにきちんと書いてあった...

Podcastを配信するためのフィードの作り方メモ

簡単な書き方
 簡単、ポッドキャステング用のRSS 2.0の書き方 - webdog

詳細なデータまで入れる書き方
 iTunes Muisc Store上にPodcastをパブリッシュする方法(http://phobos.apple.com/static/iTunesRSS.htmlの私訳)
 上記と合わせてこれも読んでおく → 蝸牛の歩み - iTunesへのpodcast

Webページのリンクから1クリックでiTunesに登録できるようにする方法
 Going My Way: iTunesをインストールしたPCなら、itpc://とすればPodcastをダイレクトに登録可能


関連記事: RSS/Atomフィードを生成したりSitemapを作成するPHPライブラリ

2007年10月2日火曜日

iPod touchでワンセグを視聴

それができればiPod touchはさらに売れるのでは。

ブログ アーカイブ

tags