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()一本でいいのに。

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が欲しくなったけど、何も考えなかったことにしました。

Zend_Loader::isReadableを使う理由

Zend_Loader::isReadableというメソッドがあるのを今日知りました。今までphpの標準関数is_readableを使っていたので必要ともしてませんでした。これの違いってなに?

マニュアルを読んでみると、こんな記述が

このメソッドは、PHP の関数 » is_readable() のラッパーです。この関数は include_path を探しませんが、 Zend_Loader::isReadable() は include_path も検索対象に含めます。

ソースはこんな感じ

    public static function isReadable($filename)
    {
        // Phar occasionally fails when using fopen()
        if (strpos($filename, 'phar://') !== false) {
            return is_readable($filename);
        }

        if (!$fh = @fopen($filename, 'r', true)) {
            return false;
        }
        @fclose($fh);
        return true;
    }

なるほど、include_path先も見てくれるとなると便利そうと感じる。
include_path関連で、シンボリック等を使ったパスを渡すと実際の絶対パスを返してくれる、realpathというphpのメソッドも覚えておくと、使うときがありそうです。

viで複数のコピーをペースト仕分ける

便利な割に使う頻度があまりなく、いつも忘れてしまので、覚えるために記事にします。

viは、”yy”で1行コピー、”p”でペーストができますが、この方法だと一度に保持できるコピー情報は1つだけです。複数行をコピーする場合は、”2(行数)yy”でコピー、”p”でペーストです。この場合も一度に保持できるコピー情報は1つだけです。

この保持できる数が複数欲しいときがあるんです。例えば、プログラムを修正する際に前後にいれる以下のようなコメントとかです。

// 2010.01.08 co-hey mod start
  $hoge = $hoge + 1;
// 2010.01.08 co-hey mod end

同じ日に修正した箇所には全部同じコメントを入れるのに、毎回手書きしてたのでは、面倒ですよね。こういうときは、startのコメント行と、endのコント行の2つコピーして保持しておきたいのです。

そういうときに使えるこの方法です。

“shift + 2″ の後、”好きなキー”の後、”yy”
で、”好きなキー”で押したキーにコピーを割り当てることができます。
ペースとする場合は、
“shift + 2″ の後、”好きなキー”の後、”p”
としたらOKです。

“shift + 2” -> “s” -> “yy” でスタートコメントを、
“shift + 2” -> “e” -> “yy” でエンドコメントをコピーしておけば、
“shift + 2” -> “s” -> “p” でスタートコメントを、
“shift + 2” -> “e” -> “p” でエンドコメントをペーストできます。

便利ですよー

画像変換ツール

画像サイズ変換サービス|画像のサイズをきれいに変更

photoshopとか持っていなくても、画像のサイズが変更できるツール。
windows使ってるときは、paintとかでもやりますけど、たまたまmacで作業してたので、重宝しました。macのpreviewって画像編集できないですよね?勘違いかましてたらごめんなさい。

ブログを見直しました

ソースコードをブログに書くようになって、横幅が足りないと感じていたので、単一記事のページを2カラムに変更しました。これで、ソースコードが見やすくなったと思います。TOPページもjavascriptで、2カラムと3カラムを切り替えるようにしようかなと考えています。

同時に以下のプラグインを追加しました。

■ サイトの右側にtwitterのリンクを表示させるプラグイン
http://wpburn.com/wordpress-plugins/wp-followme-plugin

■ 単一記事ページに関連記事のリンクを表示させるプラグイン
http://rmarsh.com/plugins/similar-posts/
http://rmarsh.com/plugins/post-plugin-library/
(similar-postsを使うには、post-plugin-libraryが必要です)

■ 新しい記事を作成した際に、twitterに投稿してくれるプラグイン
http://wppluginsj.sourceforge.jp/simple-tweet/

Zend_Http_Clientでbitly APIを利用する

URL短縮サービス http://bitly.net/ は、APIが準備されているので、自分のプログラムの中に組み込むことができます。

実際に組み込む前に、http://bitly.net でsign up(アカウント登録)して、APIを利用するのに必要なapikeyをメモっておいてくださいね。
英語のページですが、英語がほとんどわからない僕でも登録できたので、そんなに手間取らずにできると思います。

setParameterGet('version', '2.0.1')
       ->setParameterGet('login', 'アカウント')
       ->setParameterGet('apiKey', 'apiKey')    // ログイン後の画面に書いてあるやつR_xxxとか
       ->setParameterGet('longUrl', $url);
$res = $client->request();   // 変換実行

if ($res->isSuccessful()) {
    // 結果を stdClass形式で受け取る
    $body = Zend_Json::decode($res->getBody(), Zend_Json::TYPE_OBJECT);
    $bitlyUrl = $body->results->{$url}->shortUrl;
}
?>