おすすめ猫カフェ

2月にオープンしたばかりという猫カフェ。
http://mi-neko.com/

友人の話だと、猫カフェにしては狭いから、猫との距離も近く、
昼間にこれだけ活発に動いているところはめずらしいということでした。

自由が丘駅と九品仏駅の間にあり、駅からは少し歩きますが、
頭をからっぽにしたいときは、猫と遊ぶのはありやと思いますよ。

頭をからっぽということなら、代官山にある重要文化財、朝倉邸もおすすめ。
100円で入れるお手軽さとは思えない程、静かな空間です。
夜はちょっと怖そうだけどもw

Zend_Db_SelectでUNIONとHAVINGを同時に使えない

訂正:2010/04/09

通りすがりさんにコメントを頂き、UNIONで連結した全体にhavingをかけるのはできないということで正しいということが分かりました。

たまたま、$select2の方にだけhavingでフィルターされるデータがあったため、結果的に意図通りのデータが出力されただけで、全体にhavingが掛かっているわけではありませんでした。

サブクエリを使う方法が適切です。

    // $adapterはZend_Db_Adapterのクラス。MySQLを利用。
    $select1 = $adapter->select()->from(....)->where(....);
    $select2 = $adapter->select()->from(....)->where(....);

    $select = $adapter->select()->union(array($select1, $select2));

   echo $adapter->select()->from($select)->where(....); ←havingで書いてた条件

=========

UNIONとHAVINGを同時に使うSQLを組んでいたときに、Zend_Db_Selectから生成されたSQLからHAVING句が抜け落ちていました。

プログラムは以下のようなものです。

    // $adapterはZend_Db_Adapterのクラス。MySQLを利用。
    $select1 = $adapter->select()->from(....)->where(....);
    $select2 = $adapter->select()->from(....)->where(....);

    $select = $adapter->select()->union($select1, $select2)->having(.....);
    echo $select;   ← ここで HAVING句がなくなってる

上記でできるSQLのイメージは、これです。

   select ...... from .... where ....
   union
   select ...... from .... where ....
   having .....

このSQLをDBサーバで実行すると、動くので構文はあってます。

そこで、Zend_Db_Selectクラスのhaving句を出力するところを見たら、こうなってました。(バージョンは10.2)

    /**
     * Render HAVING clause
     *
     * @param string   $sql SQL query
     * @return string
     */
    protected function _renderHaving($sql)
    {
        if ($this->_parts[self::FROM] && $this->_parts[self::HAVING]) {
            $sql .= ' ' . self::SQL_HAVING . ' ' . implode(' ', $this->_parts[self::HAVING]);
        }

        Zend_Debug::dump($sql);
        return $sql;
    }

FROM句とHAVING句が両方ある場合に、HAVINGをつけるって処理ですね。確かにこれだと、UNIONと同時に使ったときは、FROM句がないので、HAVING句がつかないのは納得です。

というわけで、以下のように修正して、UNIONとHAVINGが同時に使えることを確認しました。

    /**
     * Render HAVING clause
     *
     * @param string   $sql SQL query
     * @return string
     */
    protected function _renderHaving($sql)
    {
        // FROMかUNIONがあればOKに変更
        if (($this->_parts[self::FROM] || $this->_parts[self::UNION]) && $this->_parts[self::HAVING]) {
            $sql .= ' ' . self::SQL_HAVING . ' ' . implode(' ', $this->_parts[self::HAVING]);
        }

        Zend_Debug::dump($sql);
        return $sql;
    }

そのうちZend本体でも実装してくれることに期待します。

phpで子クラスへ__constructのパラメタを渡す

今までは、配列で渡してたんですが、違和感があるので、どうにか__constructに渡した形と同じように _initにも渡せないかなと考えて、以下のようにしました。

意図通りに動いてくれています。5個以上パラメタがあるときも稀だと思うので、5個までにしています。増えたら増やせばいいかなと。これで違和感なく使えるようになってすっきりです。

abstract class Hoge_Model_Abstract
{
    final public function __construct()
    {
        // ここに共通初期化処理
 
        if (func_num_args() != 0) {
            list($param1, $param2, $param3, $param4, $param5) = func_get_args();
        }
        $this->_init($param1, $param2, $param3, $param4, $param5);
    }

    protected function _init()
    {
        // 初期化処理するときはこちらで
    }
}

filterに使えるarray_intersect_key

第一パラメタの配列の中で、第2パラメタ以降の配列全てに存在するキーのものだけ取得してくれる。

詳しい説明はこちらで。
http://php.net/manual/ja/function.array-intersect-key.php

今まで、Zend_Db_Table_RowのsetFromArrayの存在を知らなかったので、自分でこんなやりかたでfilterしてました。

$tmp = array();     
$table = new Zend_Db_Table_Abstractを継承したクラス();
$cols = $table->info('cols');
foreach ($params as $key => $value) {
    if (in_array($key, $cols)) { $columns[$key] = $value; }
}

これが、

$table = new Zend_Db_Table_Abstractを継承したクラス();
$cols = $table->info('cols');
$tmp = array_intersect_key($params, array_flip($cols));

と書けます。これ便利ですね。

ZendFrameworkのソースに書いてありました。
なんで今まで見つけれなかったんだろう。必要としてなかったからなのか。
もっと楽な方法がないのかって思えてなかったことに反省。

phpのautoloadメソッドはスタック

Zend_Loader_Autoloaderってどういう手順で、__autoloadを設定しているのかが気になってみてみたら、spl_autoload_registerを使っていました。apl_autoload_registerの説明を見てみたら、以下の文が。

指定した関数を、spl が提供する __autoload スタックに登録します。
スタックがまだアクティブになっていない場合は、まずアクティブにします。

もしあなたのコード中に __autoload 関数が存在するのなら、 それを明示的に __autoload スタックに登録しなければなりません。 なぜなら、spl_autoload_register() は、 spl_autoload() あるいは spl_autoload_call() によって __autoload 関数のエンジンキャッシュを効率的に置き換えるからです。

スタックってことは、複数のautoloadロジックを使えるってことですよね。
これはいつか覚えててよかったと思いそうだったので、メモがわりに残します。

動的にクラスを定義する方法ないかなと思ってるんです。
Zend_Db_Table_Rowをテーブル毎に名前を変えて定義したい場合、名前とprotectedの変数の値しか変わらないのに、毎回書くのは面倒に感じてしまって。

Doctrineは、自動生成っていう方法で面倒さを回避していますが、Zend_Db_Table_Rowの拡張の場合、自動生成するような分量でもないし、自動生成のやり方を説明するところで、時間をくいそうなので、自動的ができたらなと考えています。現時点でいいアイデアは浮かんでいません。

http://www.php.net/manual/ja/function.spl-autoload-functions.php
http://www.php.net/manual/ja/function.spl-autoload-register.php
http://www.php.net/manual/ja/function.spl-autoload.php
http://www.php.net/manual/ja/function.spl-autoload-call.php

【Zend】処理中にbootstrapを取得する方法

controllerの中なら、

$bootstrap = $this->getInvokeArg('bootstrap');

で取得できる。

modelとかの中でも

$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');

で取得できる

bootstrap取得して何をするかというと、application.iniで設定したリソースを取得できる。
例えば、multidbリソースを使ってたとすると

$bootstrap->getPluginResource('multidb')->getDb('hoge1');

みたいに、hoge1 DBへのDBアダプターが取得できる。

このアダプターを、各テーブルクラスのコンストラクタで、テーブルのアダプターとして設定してあげると、普段Default_Adapterを設定しているときのように、どのアダプタを使うとかを、プログラムを作るときに意識しなくていい。

== その後1 ==
生成されたPluginリソース(Zend/Application/Resourceとかにあるやつ)は、
BootstrapのContainer(中身はZend_Registryインスタンス)に入ってたので。

$boostrap->getContainer()->multidb->getDb('hoge1');

でも同様のDBアダプターが取得できる。

getPluginResource()だと、インスタンスがなかった場合作ってくれるが、
Container経由だと、なかったらnullが返ってくるはず。

どっちもpublicメソッドなので、どちらでも使える。
処理数でいうと、getContainerが少ない(チェックとかないため)ので、
最初からインスタンスがあるってわかってるものについては、getContainer()経由がいいのかも。

== その後2 ==
ソース見ても、getPluginResource()は、bootstrapの中からしか呼ばれてないし、
protectedでいいと思うんだけど、なんでだろう?

自前のBootstrap作るときも、Bootstrapクラス継承するから問題ないし。
クラス外から呼ばれることを想定していたとして、どういう場合かがわからん。

getContainer()一本でいいのに。

会社帰りにウイスキー

昨日、mixiでラッキー★ハウス店長 レイシ君の日記を発見。めずらしい。
年始以来ご無沙汰してたし、久々に会いたいなと思って、中目黒ラッキー★ハウスへ。

ほぼ満席だったけど、1席だけ空いてたラッキー☆
ウイスキーのCMをYouTubeで前日見てたのもあって、角ハイを注文。

お通しと一緒にすっと出てくる。ちょいちょい飲みながら話始めた。
最近どうですか?ってところから始まって、確定申告の話、クラブの話、ロックの話、ワンピースの話。やっぱりゾロはアツいし、赤犬が裏でこそこそやってるのに男っぽい広島弁使ってるのが嫌っていうところが一致したのが面白かったw

隣で飲んでたお二人とも少し話せたし、いつもと違う刺激があった夜でした。
実は同じような職種の方だったり、広告代理店の方だったり。
昨日入籍されたようです。10才くらい上の方に失礼ですが、
すごくいい笑顔をされてました。それに超よっぱらってましたw
渡した名刺が、無事に認識されて手元に残っていることに期待してます。

レイシくんはOVOで知り合って今もお世話になってますが、同じOVOで知り合った
DJ YAKOが船橋でやっているClub Orangeが3月13日に一周年を迎えます。
http://www.o-ranges.com/

遊びに行きますんで、一緒に行きたいって方はご連絡ください。=> info@co-hey.com
きっと楽しいですよ。
レイシ君の店、ラッキー★ハウスに行ってみたい!って方もぜひ!ご一緒しましょう。

「船橋 オレンジ」で検索したらYAKOのクラブが一番上に。これが一番びっくりした

marantzのイヤホンが好みの音でした

amazonで見つけたこれ。marantzという名前と見た目で惹かれた。
marantzといえば、ONKYOとかと一緒でクラシックを聞くのに使われるアンプのイメージだったので、透明感と余韻がいい感じというのと、低音の出方が足りなかったりしそうというイメージだった。ネットで口コミを見ても似たような感じ。

低音がでないというのがどのくらいのものなのか、でないといわれている低音ってどのあたりの音なのか、一番低音があまりでも、そのちょっと上の音が厚く出てたら、そっちの方が好みだし、透明感とかは音疲れしにくさにつながるので、大事。

販売しているところで見つけてれたのは、amazonとapple store。幸いにもapple storeでは試聴もできるということだったので、早速apple storeに試聴しに行ってきました。

中高音の余韻、広がり、全体的に尖ってない丸みがある音、ウッドベースあたりの音が気持ちよく響きそうな低音のちょっと上辺りがよく出てる。これなら長時間聞いてもつかれない!!音量をそんなに上げなくてもよく聞こえるし、音量を上げても、音がそんなに張ってないので、迫力は増さない。爆音で音圧を感じたければヘッドフォンで、イヤホンはそれより小さい音でも満足感が得られることを目的にしてますってことなのかなと勝手に推測したくなる感じ。

その場で購入しました。4つ打ちでもdeephouseとかjazzhouseとか、break beatsが好きなら、これはおすすめです。techno だと、もっと低音が欲しい方がいるかもしれません。僕はこのくらいで十分です。jazzとか聞いても気持ちイイー

Macにapacheとかインストール(その後)

先日、こんな記事を書きました。
https://life.co-hey.com/2010/02/macにapacheとかインストール

インストールは無事に終了。日を改めてapache経由でphpを動かそうとしたところ全然動かない。さて、困った。index.htmlおいてみたところ、これも表示されない。んー、さらに困った。ということで調べて、httpd.confを修正。

・修正点1
Directory設定の、”Deny from all” を “Allow from all” へ。
これで自分で作成したvirtualhostのdocumentrootでアクセス可能になった。index.htmlはこの時点で参照可能に。


    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
#    Deny from all
    Allow from all

・修正点2
phpのmodulleを読み込みむように以下の行を追加。
ソースからインストールしたときにこれどっかのタイミングで自動で記述されてた気がしたが、今回なかったので追加。
index.phpがこの時点で参照可能に。

LoadModule php5_module        modules/libphp5.so

・修正点3
http://test.local/ 等にアクセスした際に、index.htmlまたはindex.phpを読み込んでくれるように以下の設定を追加。

DirectoryIndex index.html index.php

これで http://test.local/ にて index.phpが読み込まれることに成功。
環境構築ってたまにしかやらないから、やる度に同じところ調べてしまいますね。そして自分の残念さにがっかりします。あと何回か作り直したら覚えるでしょうか。

あとは、php経由でMySQLにつなげれたら、OK。無事にいきますように。

Macにapacheとかインストール

先日、OSクリーンインストールすることになったMacの開発環境を作り直してる途中です。前は、ネットで調べながらapache、php、mysqlをソースからインストールしたんですが、今回は楽そうな記事を見つけたので、macportでインストール。

参考にさせていただきた記事はこちらです。
http://www.serendip.ws/archives/3234

とりあえず、mysqlコマンドでDbにつながること、ブラウザでページが見えることを確認したところまで。php経由で、DBに接続できたら家でまたプログラムを作れるようになります。会社でVM使っているからか、VM Fusionが欲しくなったけど、何も考えなかったことにしました。