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

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

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

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);

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のこの緩さが他の言語使いからしたら許せんところやろうな。

7月 1st, 2009PHPのタイムゾーン

しらんかった。
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”

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

今回やりたかったのは、あまりアクセスされなくなったメディアファイルを現サーバーから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日くらいはかかりそう…

10月 23rd, 2008strtotime

何回やっても忘れるのがこれ。
function datereformat($val)
{
return date("Y年m月d日 H:i:s", strtotime($val));
}

$valにはmySQLのdatetime式(2008-07-05 12:30:50)な日付が入ってます。
それをいったんunixタイムに変換してdateしてるだけ。

4月 25th, 2008PHP_EOL

PHPで改行を表す定義済み定数。
しらんかった。

PHP_EOL

シングルクオテーション派には、ソースが少しきれいになりますね。

/**
* 現在のページのURL
*/
if( isset($_SERVER['HTTPS']) ){
$http = ($_SERVER['HTTPS'])?'https://':'http://';
}else{
$http = 'https://';
}
define('CONFIG_THIS_URL',$http.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
echo CONFIG_THIS_URL;

こんな便利なのがあるとは。
pear install --alldeps pear名

12月 21st, 2007PHPデバッグ

これもいっつも忘れてしまうのでここにメモ。
sshのエラーログを眺めてたけどどう考えてもめんどい。

本番環境では使わないけどテスト環境ではこれをつけておくとブラウザにエラーが出力される。
これ忘れるの!?って言われるようなことだけど、こんなことでもがんがんブログに書かかなくては。

ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);