Shin x blog
Twitter 検索
先日はじめたTwitterですが、なかなか楽しいです。
Twitterの仕組み自体ももちろん面白い良いのですが、日々ユーザが増えていき、システムが改良され(今日は日本語入力が改善されたもよう)、どんどん完成度が高まっていくさまが何だか楽しいです。
で、ちょうどCakePHPで何か作ろうと思っていたので、こんなの作ってみました。
Twitterの検索では、既にtwittersearchがあるのですが、それとは違いこちらは日本語ユーザのみの検索ができます。
興味のあるキーワードを入れて、Friends探しに使って貰えたら良いかと。
# 超見切り発車気味な公開なので、突然消える可能性もありますが。;-)
- コメント (Close): 1
- トラックバック: 1
Twitterで一人言
ちまたで話題のTwitterはじめてみました。
当初IMのようなサービスだと思っていたので、登録はしたものの身近でやっている人もいないので2,3日放置していました。
で、今日何気に眺めているとIMとは違うものだと何となく気づきました。(遅)
IMというよりはどちらかというとblogの方が近いのかな。
ようは相手がいて初めて成り立つものではなく、基本は自分から発信するだけで、あとはそれを見た誰かが反応を返すものだと。
blogのような情報発信 + IMのような手軽さ + SNSのような繋がり / 3 といった感じですかね。(SBMのコメントを書く感覚にも近いような)
「Twitter」は「さえずり」だそうです。自分で使った感触では「さえずり」というより、ぼそぼそ言う「一人言」という感じでした。
一人言でも何気に面白いので、「相手がいない」と躊躇している方も一度始められてはいかがでしょうか。
# やってみようかな、という人には「第1回 Twitterキホンのキホン|gihyo.jp」が参考になりますよ。
- コメント (Close): 0
- トラックバック: 0
CakePHP SQLをログに記録
CakePHPで発行したSQLをログに記録する方法です。
DEBUG>=2にすれば画面下に表示されるSQL文ですが、DB処理後にリダイレクト等で遷移すると消えてしまいます。さらに本番稼働時は画面に表示するわけにはいかないのでやはりログに出力したいところです。
フレームワークに手を入れるのが一番簡単なのですが、バージョンが上がると面倒なので既存のDboSourceを継承したクラスにログ記録を追加します。
1. DboSourceを継承
dboはフレームワークで用意されているものだけでなく、app/model/dboにあるものもフレームワークで利用する事ができます。
ここではPostgreSQLを使うとしてDboPostgresを継承したDboPostgresLogを作ります。
ログ出力をON/OFFする定数LOG_SQLは後でcore.phpで定義します。
[app/model/dbo/dbo_postgres_log.php]
<?php
uses ('model' . DS . 'dbo' . DS . 'dbo_postgres');
class DboPostgresLog extends DboPostgres {
/**
* @var integer
*/
var $queryNo = 1;
function execute($sql) {
$ret = parent::execute($sql);
if (defined('LOG_SQL') && LOG_SQL) {
$this->log(sprintf("%d. %s", $this->queryNo, $sql), LOG_DEBUG);
$this->queryNo++;
}
return $ret;
}
}
?>
2. 作成したDboPostgresLogを使用する
DATABASE_CONFIGのDB設定でdriverを’postgres_log’を指定します。
[app/config/database.php]
class DATABASE_CONFIG
{
var $default = array('driver' => 'postgres_log',
'connect' => 'pg_connect',
'host' => 'localhost',
'login' => 'user',
'password' => 'pass',
'database' => 'foo',
'prefix' => '');
}
3. core.phpでLOG_SQLを定義
SQLをログに出力するか否かを設定するLOG_SQLをcore.phpで定義します。
LOG_SQLがtrueならSQL出力し、LOG_SQLが未定義もしくはfalseの場合は出力しません。
[app/config/core.php]
<?php
/**
* If set to true, logging sql queries
*/
define('LOG_SQL', true);
?>
これで実行されたSQL文が[app/tmp/logs/debug.log]に出力されます。
この方法はDEBUGの値に関係無くログ出力ができるのは良いのですが、DboSourcesを継承するのがイマイチです。フレームワーク(DboSources自身)で対応して貰えれば一番良いですけどね。;-)
- コメント (Close): 4
- トラックバック: 0
Firecakeのコメントにcakeinfoが
FirecakeはCakePHPのデバッグ情報をFirebugに表示する便利なHelperです。
Bakeryでソースを見ているとコメントにこんな記述が。
Looking for more ideas, I also used cakeinfo.php, * a script released under MIT license by Masashi Shinbara.
cakeinfoを参考にして頂いているようです。嬉しい事です。
- コメント (Close): 0
- トラックバック: 0
PostgreSQL 誤って削除したデータを復元する
- 2007-04-04 (水)
- Web+DB
PostgreSQLの仕組みを考えれば「なるほど」な内容なのですが、実際にできるんですね。
VACUUM していなければ、データベースファイル内に残っている可能性があります。 トランザクションIDをDELETE 文を発行した時点よりも昔に「巻き戻す」ことで、 削除したデータが再び見えるようにできるかもしれません。
トランザクションIDを戻せばOKなのか。うーんスゴイ。
CVSやSubversionでリビジョンを指定する感覚に似ているかも。(そこまで柔軟じゃないか)
間違ってDELETE/UPDATEした時は慌てず騒がず、この方法を思いだそ。
- コメント (Close): 0
- トラックバック: 0
CakePHP Model#save()内でvalidates()を呼ばない
ref: CakePHPの何か-CakePHPのModelを使う
お馴染みyandoさんのプレゼン資料で気になったソースがあったので勝手に添削w。
35p:Validation設定例
<?php
class UsersController extends AppController {
function fuga(){
$data['User'] = array(
'login_id' => '+*+*+*+*',
'password' => 'abcde',
'name' => ''
);
if ($this->User->validates($data)) {
$this->User->save($data);
} else {
$this->validateErrors($this->User);
}
}
}
?>
User#save()の部分ですが、Model#save()メソッド内ではModel#validates()が呼ばれるので、このままだとUser#validates()が2度実行されることになります。
このソースのようにsave()の前にvalidates()を実行するならsave()の第2引数にfalseを渡します。これならsave()内でvalidates()は実行されません。
<?php
if ($this->User->validates($data)) {
// validates()はsave()内では呼ばれない
$this->User->save($data, false);
}
?>
あとこの例のようにController#validationErrorsを参照しないのなら、Controller#validateErrors()は呼ばなくても良いです。
なので↓のようにシンプルに書けたりします。
<?php
class UsersController extends AppController {
function fuga(){
$data['User'] = array(
'login_id' => '+*+*+*+*',
'password' => 'abcde',
'name' => ''
);
$this->User->save($data);
}
}
?>
まあ実際は登録完了後はリダイレクトしたりビューテンプレートを変えたりするので結局上のソースのようになるのですが。;-)
- コメント (Close): 2
- トラックバック: 1
URLをリンクにするSmartyプラグイン
- 2007-03-30 (金)
- PHP
テキスト中にURLが含まれている場合にそれをaタグで囲むSmartyプラグインです。
既にありそうなのですが見つけられなかったので作りました。よろしければどうぞ。
modifier.url_link.php
<?php
/*
* Smarty plugin
* URL to link
*
* @param string $value
* @param string $target
* @return string
*/
function smarty_modifier_url_link($value, $target = null)
{
$options = "";
if (!empty($target)) {
$options = sprintf(" target=\"%s\"", $target);
}
$value = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]",
"<a href=\"\\0\"" . $options . ">\\0</a>", $value);
return $value;
}
?>
plugins/ディレクトリに設置すれば↓のように使えます。
{$text|escape|url_link}
aタグにtarget属性を付加する場合は設定する値を渡します。
{$text|escape|url_link:"_blank"}
Smartyはビューテンプレートでちょっとした加工ができるので便利です。SmartyテンプレートがPHP以外の言語でも使えたら良いのに。
- コメント (Close): 1
- トラックバック: 0
svn log –xml
- 2007-03-28 (水)
- 開発環境
Yesterday I was struggling trying to get svn log to display the results for a certain user and this was very annoying.. then I jumped on #svn on freenode, and someone mentionned svn log –xml
svn logをXMLで出力できるんですね。知りませんでした。。。
試しにCakePHP1.1.xリポジトリのログを出力してみました。
$ svn log --verbose --limit 10 --xml
<?xml version="1.0"?> <log> <logentry revision="4693"> <author>phpnut</author> <date>2007-03-27T04:32:47.490451Z</date> <paths> <path action="M">/branches/1.1.x.x/cake/config/config.php</path> <path action="M">/trunk/cake/1.1.x.x/cake/config/config.php</path> <path action="M">/branches/1.1.x.x/cake/VERSION.txt</path> <path action="M">/trunk/cake/1.1.x.x/cake/libs/session.php</path> <path action="M">/trunk/cake/1.1.x.x/cake/VERSION.txt</path> </paths> <msg>Merging fixes into the trunk Revision: [4692] Merging fix for Ticket #2295</msg> </logentry> </log>
SimpleXmlElementなんかでパースすればすぐに使えそうです。さて何に使おうかなー。
- コメント (Close): 1
- トラックバック: 0
SmartyでSJISテンプレートを使う
- 2007-03-27 (火)
- PHP
SmartyテンプレートをSJISで書いていた時に「本」等の文字でSmartyパースエラーが発生していました。
「本」はSJISで[0x967B]なので、[0x7B]がSmartyのデリミタ[{]として評価されパースエラーになります。
これは{literal}{/literal}で該当文字を囲めば回避することができます。
{literal}本文{/literal}
またSmaryのデリミタを変える事もできるので、この方法で回避することもできそうです。
ref:Smartyの構文解析を回避
- コメント (Close): 0
- トラックバック: 0
PHPからPostgreSQLに大量のデータを登録する
- 2007-03-16 (金)
- PHP
PostgreSQLに大量のデータを登録する際はINSERTを使って一件づつ処理するより、COPYを使って一気に登録した方が実行速度が(かなり)速いです。
そこでPHPでもCOPY文を使ってみましょう。
pg_copy_fromを使う
登録するデータが配列に入っているならpg_copy_fromだけで一気に処理できます。
配列の1要素が1レコードに対応しています。1要素内では各カラムをデリミタ(デフォルトは”\t”)で連結します。
<?php
$values = array();
$values[] = "1\tname1";
$values[] = "2\tname2";
$values[] = "3\tname3";
$db = pg_connect("dbname=hogedb");
pg_copy_from($db, 'table', $values);
?>
単純なCSVならデリミタを[,]に変えればokです。
<?php
$values = array();
$values[] = "1,name1";
$values[] = "2,name2";
$values[] = "3,name3";
$db = pg_connect("dbname=hogedb");
pg_copy_from($db, 'table', $values, ',');
?>
pg_put_lineを使う
登録するデータを一件ずつ処理したいならpg_put_lineで1レコードずつ出力する方法します。
はじめにCOPY文を発行しているので、デリミタの指定などSQL内で変更できます。
登録データ出力後に[\.]を発行してから、最後にpg_end_copyを呼ぶ必要がありますのでご注意を。
<?php
$db = pg_connect("dbname=hogedb");
pg_query($db, "copy table from stdin");
for ($i = 1 ; $i <= 10 ; $i++) {
$line = sprintf("%d\tname%d\n", $i, $i);
pg_put_line($db, $line);
}
pg_put_line($db, "\.\n");
pg_end_copy($db);
?>
ちなみにPostgreSQLではCOPY文もトランザクション内に含める事ができます。当然ROLLBACKも可能です。
数万件レベルのデータでも体感できる程パフォーマンスが違うので、もし知らない方は一度お試しあれ。
- コメント (Close): 0
- トラックバック: 1
- 検索
- フィード
- メタ情報
