Hatena::ブログ(Diary)

例えば、PHPを使う このページをアンテナに追加 RSSフィード

Diggin - PHPライブラリ

2111-03-23

「例えば、PHPを使う」は終わりました。長年のご愛顧ありがとうございました。

ほんとにPHP使い始めたら止めようと初めたときから思ってたのでここでの更新やめます。

(あとはてなダイアリーがEUC-JPとかだったりするので)

移転先はとくにありません。


散文的なものは主に以下を更新してるようです。

- https://gist.github.com/sasezaki

- jottit

2010-12-05

悪用厳禁! ZF2のPluginClassLoader::addStaticMap

こんな場末の日記をご覧の方は、ZF2のプラグイン機構では、クラス定義の読み込みをPluginClassLoaderが、インスタンス化をPluginBrokerが行うということはご存知ですよね!え、ご存知ない?Wikipedia創設者ZFリードデペロッパーMatthew Weier O'Phinneyからのメッセージをお読みください。


Introducing the ZF2 Plugin Broker

http://weierophinney.net/matthew/archives/248-Introducing-the-ZF2-Plugin-Broker.html


で、LazyLoadingをする場合は、PlginBrokerの拡張PluginSpecBrokerというのが存在します。

(Controller\Actionでは、Loader\PluginSpecBrokerの拡張のController\Action\HelperBrokerを

ヘルパー読み込みの際に使用。View\PhpRendererでは、Loader\PluginBrokerの拡張のView\HelperBrokerを使用)


ということで、プラグイン機構を自前のライブラリで使う場合に以下のように使う場合に以下のような構造を考えるわけですが、

<?php
namespace Diggin\Service\ShortUrl;

class ShortUrl
{
    protected $shortUrlBroker;
   
    // host名=$plugin名としてpreg_replace_callbackに渡すなどする包括的なフィルタ用
    public function unshorten($plugin, $shortenedUrl)
    {       
        if ($shortener = $this->getShortUrlBroker()->load($plugin)) {
                
            if ($shortener instanceof \Zend_Service_ShortUrl_Shortener) {
                return $shortener->unshorten($shortenUrl);
            } else if ($shortener instanceof \Services_ShortUrl) {
            }

            return $shortenedUrl;
        }

        return $shortenedUrl;
    }   
        
    public function getShortUrlBroker() 
    {   
        if (!$this->shortUrlBroker instanceof ShortUrlBroker) {
            $this->shortUrlBroker = new ShortUrlBroker;
        }
        return $this->shortUrlBroker;
    }

}
<?php
namespace Diggin\Service\ShortUrl;
use Zend\Loader\PluginSpecBroker;

class ShortUrlBroker extends PluginSpecBroker
{
    protected $defaultClassLoader = 'Diggin\Service\ShortUrl\ShortUrlClassLoader';
}
<?php
namespace Diggin\Service\ShortUrl;
use Zend\Loader\PluginClassLoader;

class ShortUrlClassLoader extends PluginClassLoader
{
    protected $plugins = array(
        'tinyurl' => 'Zend_Service_ShortUrl_TinyUrlCom',
        'isgd' => 'Zend_Service_ShortUrl_IsGd',
        'metamark' => 'Zend_Service_ShortUrl_MetamarkNet',
    );
}

ここで、メンドくさがって、BrokerにvalidatePlugin()の個別処理を書かないと、以下のような呼び出しをしたときに

<?php
set_include_path(__DIR__.'/library/'. PATH_SEPARATOR .get_include_path());
require_once 'Zend/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader;
//$loader->registerNamespace('Diggin');
$loader->setFallbackAutoloader(true);
$loader->register();

//bootstrapなどで
Zend\Loader\PluginClassLoader::addStaticMap(array('tinyurl' => 'Zend\Version'));

//bootstrapなででtypoした場合
Diggin\Service\ShortUrl\ShortUrlClassLoader::addStaticMap(array('tonyurl' => 'User\ShortUrl\Type'));

use Diggin\Service\ShortUrl\ShortUrl;
$shorturl = new ShortUrl;
var_dump($shorturl->getShortUrlBroker()->load('tinyurl')); //Zend\Version

という感じで処理がインスタンス生成後もヘルパーコールの場合処理がそのまま起動されちゃいます。なので、読み込み後インスタンスが適切か確認するvalidatePluginはちゃんと書かないとだめですね。

<?php
namespace Diggin\Service\ShortUrl;
use Zend\Loader\PluginSpecBroker;

class ShortUrlBroker extends PluginSpecBroker
{
    protected $defaultClassLoader = 'Diggin\Service\ShortUrl\ShortUrlClassLoader';

    protected function validatePlugin($plugin)
    {
        if (!$plugin instanceof \Zend_Service_ShortUrl_Shortener) {
            throw new Exception\RuntimeException('Serializer adapters must implement Zend\Serializer\Adapter');
        }
        return true;
    }
}

まあ、この自前コンポネーント設計どうなのよって話もありますが。

2010-10-20

AjaxなURL(#!)を変換する奴を書かれたものをPHP用にポーティング

http://github.com/sasezaki/Zend_Uri_HttpCrawlableHash


@see http://code.google.com/intl/ja/web/ajaxcrawling/docs/specification.html

@see http://subtech.g.hatena.ne.jp/mala/20101018/1287419036



とりあえずテストコードに書かれた分はパスしてますって程度ですね。

<?php
require_once 'Diggin/Uri/HttpCrawlableHashTest.php';

$uri = Zend_Uri::factory("http://twitter.com/#!/wozozo", 'Diggin_Uri_HttpCrawlableHash');

// 変換したURIオブジェクトが欲しいとき(cloneして返します)
echo $uri->getFragmentToQuery(); // http://twitter.com/?_escaped_fragment_=/wozozo

// uriオブジェクトを変換して保持する場合
$uri->filterFragmentToQuery();
echo $uri; // http://twitter.com/?_escaped_fragment_=/wozozo

// 常に変換を掛けたい場合
//(zf2だとスタティックコンフィグじゃなくなるんで結構いまさらできても意味ない)
Zend_Uri::setConfig(array('convert_always' => 'query'));
$uri2 = Zend_Uri::factory("http://twitter.com/#!/gusagi", 'Diggin_Uri_HttpCrawlableHash');
echo $uri2; // http://twitter.com/?_escaped_fragment_=/gusagi

Zend_Uri、コンストラクタは置き換えられませんが、factoryでのクラスは置き換えられます。

(Zend Framework 1.10.5以上)

http://framework.zend.com/issues/browse/ZF-9925

http://framework.zend.com/manual/ja/zend.uri.chapter.html (Creating a New Custom-Class URI)