0

はてなブックマークとあとで読む系のサービスをつなぐHaboryをリリースしました。

logo-2

HaboryというWebサービスをリリースしました。
はてなブックマークとあとで読む系のサービス(Readability,Pocket,Instapaper)をつなぐWebサービスです。はてなブックマークするだけで自動的にあとで読む系のサービスにもポストされます。
一度連携設定したら何もしなくていいサービスですのでぜひご利用ください。

今回に関しては作ったモチベーションとか開発小咄的なものはなく、
半年かけて作ったFaboryが非常に残念な結果に終わった反面、開発期間も2週間程のお気軽サービスがどうなるか、これがみてみたいというのと、
この手のサービスは一度セットアップに訪れたらユーザーはもうWebサイトを訪ねる事はありません。(ツイエバ、ハテブテ然り) これのマネタイズという程ではないけどサーバー代ペイできる方法の模索、
くらいです。

簡単にいうとなんとなく作ったという事ですね。

0

FuelPHPが素晴らしい理由

FuelPHPが素晴らしい理由

共にcontrollerからsessionのset&get。

cakePHP1.3
$this->Session->write('name', 'hoge');
$this->Session->read('name');

CodeIgniter2.0
$this->session->set_userdata('name', 'hoge');
$this->session->userdata('name');

Symfony1.4
$this->getUser()->setAttribute('name', 'hoge');
$this->getUser()->getAttribute('name');

FuelPHP1.2
Session::set('name', 'hoge')
Session::get('name')

直感的。staticといえどもタイプ数が少ない。
Symfonyのそれはもはやsession関係のメソッドとは気付かない。

0

【IE6】facebookページからinframeで読み込んだアプリがCookieを受け付けない現象

変な日本語だな。
facebookアプリを作っていているドキュメントは古いわ、仕様は急に変わるわで、日本のソーシャルアプリをやってる感覚でやってると痛い目にあいます。
試行錯誤を繰り返し開発中に一つ大きく嵌まったのが、IE6でログイン状態がとれない。
普通のアプリを動かしてる場合は問題ないけど、アプリをfacebookページのiframeで読みこんで動かしてる時に発生する。
この状況で、ログイン状態がとれない→sessionが使えてない→Cookieが使えてないと気付くまでが長かった。

IE6はデフォルトだと、自分以外のドメインから来た Cookie は受け入れないようになっています。
確かに受け入れると危険だなーと思う気もするけど、iframeの内と外が別ドメインの場合困った事になります。
解決方法は、明示的に自分以外のドメインからのCookieも受け入れるようにヘッダーに情報を付与する事です。

phpだと、
header("P3P: CP='UNI CUR OUR'");
のようにすれば、Cookieを読み込めるようになります。

P3PというのはW3Cの仕様です。IE6、こういうところはW3Cの仕様に準拠してるんですね。
CPが「コンタクトポリシー」の略。
他にも、”NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI”ってのがあります。
今回、ヘッダーに埋め込んだ3つは、以下の通りです。

UNI
個人を識別するために生成されるID

CUR
情報は、情報提供や通信、双方向サービスなど、利用者がそのために情報を与えたところの活動を遂行するために、サービス提供者によって利用されるかもしれない。

OUR
当組織または当組織の業務を委託している法人やサイトの運営者

facebookアプリは色々嵌りポイントがあるけどとりあえずはこれ。

0

APC

微妙な時間が空いたので、メモレベルで貯めてたものをブログを書いてみる。
phpのアクセレータで有名なAPCの最新版は実はphp5.3に対応してないので、beta版を入れないとダメ。

pecl install apc-beta

コンパイルでコケる。

yum install -y httpd-devel pcre-devel

httpd-develはともかくpcre-develなんて入ってないのでこれをyumで入れる。

無事インストールが完了すれば、php.iniに追記して完了。
extension=apc.so

インストールが簡単なのに効果は抜群。
インストールするだけでLoad Average半分くらいに減ります。

0

CakePHPでルーティング

今までオレオレフレームワークを使ってきたけど、結局のところプロジェクト全体ではOSSのフレームワークを使って処理の重い所だけ、別途作成予定のオレオレ軽量フレームワークを使うのが一番開発効率がいい気がしてきた。

という事で最近cakePHPをちょこちょこ触ってます。
今回はずっと気になってたcakephpのルーティングについてのメモ。

CakePHPのルーティングを何も分からずcakephpで作ってるとURLがこんな感じに一階層ものばかりになってしまいます。

  • http://hoge.com/profiles/add
  • http://hoge.com/profiles/edit
  • http://hoge.com/profiles/list

もちろんコンテンツの内容によって以下ように2階層目以下も使って表示させたいわけで、そういう時はroutes.phpに記述していきます。

  • http://hoge.com/mypage/profiles/add
  • http://hoge.com/mypage/profiles/edit
  • http://hoge.com/mypage/profiles/list

app/config/routes.php
Router::connect('/mypage/profiles/add', array('controller' => 'profiles', 'action' => 'add'));
Router::connect('/mypage/profiles/edit', array('controller' => 'profiles', 'action' => 'edit'));
Router::connect('/mypage/profiles/list', array('controller' => 'profiles', 'action' => 'list'));

と、一つ一つ書いていってもいいし:actionを使ってワイルドカードのようにも扱えます。
Router::connect('/mypage/profiles/:action', array('controller' => 'profiles'));

今後主とするフレームワークをどれにするかかなり迷い中。
一番手になじんでるcakephp、なんとなく恰好良いsymfony、今ならあえてLithiumか。

0

Twitter APIでOAuth認証後にユーザー名を取得

もうだいぶ前の話しになるけど、なんとなくTwitterAPI+OAuthというのが触ってみたくて、こちらのブログを参考にプロトタイプを作りました。
参考にというか、ほぼコピペで。

検索とかポストとかは一通り問題なく行えたのですが、OAuthで認証後の自身のユーザー名の取得で躓きました。ad.lyとかやってるOAuthで認証後にユーザー名を表示してるやつ。

きっとトリッキーな事をしてると思いきやあっさり取れました。
躓いてたのはアクセストークンと同時に取れると思ったから。
もらったアクセストークンで、すぐにverify_credentialsというAPIを叩きユーザー名を含むユーザー情報を取得できます。
http://twitter.com/account/verify_credentials.xml
これでOAuthを行ったユーザーの情報がとれます。

0

wordpressでexec-phpが対応がmoreで反応しない件

wordpressで本文でphpのコードが実行できるexec-phpというプラグインがあります。
これを本文を分割する<!–more–>と一緒につかうと、phpが実行されずコードがそのまま表示されます。

詳しくはみてないけど、moreの部分をWPで処理するするのにタグをエスケープしていて、その際<?phpもタグみなしてエスケープしてる為です。
しかもエスケープの仕方が<?php → < ?phpとなってしまいます。

formatting.phpに該当するコードがあるのでこれを置換したら元通りphpが実行されます。
wp-includes/formatting.phpの989行目くらい。

$newtext = str_replace("< ?php","<?php",$newtext);

0

phpで前月の日付を表示

phpで前日とか前月の日付を取得するのにこんなやり方もあったんや。
date("Y年m月d", strtotime("-1 day"));
date("Y年m月d", strtotime("-1 month"));
date("Y年m月d", strtotime("-1 year"));
date("Y年m月d", strtotime("-1 week"));

今までmktime使って取得してたけど、こっちの方がきれい。
phpのこの緩さが他の言語使いからしたら許せんところやろうな。

0

PHPのタイムゾーン

しらんかった。
phpのdate関数がアメリカの時間を取得していたので、てっきりec2に突っ込んだfedoraのタイムゾーンがアメリカだからと思い込み下記のような修正を行いました。
# mv /etc/localtime /etc/localtime.org
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

これでfedoraのタイムゾーンが変わったからいけると思ったけどそれでも無理。

で調べるとphp.iniを修正するとのこと。
date.timezone=”Asia/Tokyo”

これで無事、日本時間が取得できます。

0

phpでS3を扱うamazon-s3-php-class

今回やりたかったのは、あまりアクセスされなくなったメディアファイルを現サーバーからS3にバックアップさせるというやつです。
ファイル数が1万弱あるので手動では厳しいしいのでスクリプトに頼ることにしました。

やりたいことは、
ディレクトリ構成は極力保持。
DBで削除フラグがたってるようなやつは移動させない。
なので、そのままディレクトリを同期っていうやつは使えません。
WEBサービスの中でユーザーがアップロードしたらそのままS3へ同期ってのをいずれやりたいので、できればPHPで。

そんな条件で探してたら、洋物ながらamazon-s3-php-classっていうのがありました。
CURLを使ってHTTPメソッド(GET、PUT、DELETE、POST)なんかができます。

付属のサンプルを動かしてみたらうまくいったのだけど、どうも2階層目以降のディレクトリが指定できない。
(そもそも2階層目以降はディレクトリと呼ぶのか?これらもバケット?)
http://hoge.s3.amazonaws.com/huga.jpgだといけるけどhttp://hoge.s3.amazonaws.com/file/2008/huge.jpgだとうまくエラー吐き出してうまくアップロードができません。

putObjectFileのソースを追っていくと第2引数がそのままhttp://(第2引数).s3.amazonaws.comとしてサブドメインとして使われてるのが原因でした。

下記のようにS3.phpを修正したらうまくいくようになりました。
但し今回使うputObjectFileだけ。
// 1093行目あたり
$this->headers['Date'] = gmdate('D, d M Y H:i:s T');
$this->response = new STDClass;
$this->response->error = false;
 
//以下を追記
if (strstr($this->bucket, '/')) {
$tmp_bucket = explode("/", $this->bucket);
$subdomain = $tmp_bucket[0];
$this->headers['Host'] = $subdomain . '.' . $defaultHost;
 
$tmp = array_slice($tmp_bucket, 1);
$this->directory = implode("/", $tmp);
}

//1143行目あたり
if (sizeof($this->parameters) > 0) {
$query = substr($this->uri, -1) !== '?' ? '?' : '&';
foreach ($this->parameters as $var => $value)
if ($value == null || $value == '') $query .= $var.'&';
// Parameters should be encoded (thanks Sean O'Dea)
else $query .= $var.'='.rawurlencode($value).'&';
$query = substr($query, 0, -1);
$this->uri .= $query;
  
if (array_key_exists('acl', $this->parameters) ||
array_key_exists('location', $this->parameters) ||
array_key_exists('torrent', $this->parameters) ||
array_key_exists('logging', $this->parameters))
$this->resource .= $query;
}
 
//以下を追記
if (isset($this->directory)) {
$this->uri = '/' . $this->directory . $this->uri;
}

これだと、putObjectFileの第2引数はhoge/file/2008/と指定できます。
DELETEのとこも同様な処理をしたらいいんだろうけど、とりあえずは必要なとこだけ修正して使ってます。

こんな感じで動いてるけどS3遅い。
遅すぎる。

総ファイル数9300、総ファイル容量15Gをアップ中だけど、ISDN並の速度。
この調子だと4日くらいはかかりそう…