最近Zend Framework1.11をベースにORMにDoctrine2、viewにtwigという組み合わせを試してみました。
書く予定のネタ
- Zend FrameworkへのDoctrine2およびCLIツールの組み込み
- Doctrine2 Extensionの組み込み
- Doctrine2へのビヘイビア(Timestampable)の組み込み
- Zend Frameworkへのtwigの組み込み
- twigのデバッグ方法
- twigへのExtensionの組み込み
※長いので今回はZend FrameworkとDoctrine2の組み込みおよびDoctrine CLIの動作確認までとします。
ライブラリのDLと配置
Zend Framework
Zend Framework 1.11.11を使用します。このエントリを読んでいる人はすでにZend Frameworkを使っているはずなので設定方法は省略します。
zf create project project_name
で標準的な構成のプロジェクトを作ります。
話をシンプルにするためにサードパーティライブラリも自作ライブラリもフラットにlibrary/以下に置くことにします。
※本当は外部ライブラリはvendor/などのディレクトリを切ってその下に置くべきなんでしょうね。symfonyやCakePHPはそのあたりのルールがきちんとしていますがZend Frameworkは自由に置けるので(以下略
Doctrine2
http://www.doctrine-project.org/projects/orm/download
からDoctrine2 ORMパッケージをDLします。(2011/12/16現在最新は2.1.4)
解凍したらDoctrine/配下にある4つのディレクトリ(Common, DBAL, ORM, Symfony)をプロジェクトのlibrary/の下にこのように配置します。
Zend FrameworkとDoctrine2を統合するライブラリ(Bisna)
Zend Framework1とDoctrine2の結合についてはいくつかのソリューションがあるのですが、自分が探した中で最もエレガントな統合を行っているのは以下でした。
https://github.com/guilhermeblanco/ZendFramework1-Doctrine2
※詳しいドキュメント(英語)は以下にあります。
http://www.kurttest.com/zfa/bisna.html
ライブラリを
git clone https://github.com/guilhermeblanco/ZendFramework1-Doctrine2.git zfdooctrine
で持ってきたらlibrary/Bisnaをプロジェクトのlibrary/直下に移動します。ライブラリ内のapplication.iniでプロジェクトのapplication.ini上書きしてください。さらにbin/doctrine.phpをプロジェクトに取り込みます。(上図を参考にしてください)
※ライブラリ内のapplication/Bootstrap.phpは今回不要です。_initAutoloaderNamespacesというメソッドは、Doctrine2をpear経由でインストールした場合に名前空間のマッピングをするためのものです。
設定
application.iniの修正
名前空間の追加
次の2行を追加します
autoloaderNamespaces[] = Symfony autoloaderNamespaces[] = Doctrine
“Doctrine Class Loader Configuration”の削除
これは、Doctrine2取得の際にgithubからのclone & git submoduleという方法で取得した際のディレクトリ構造とプロジェクトの名前空間のマッピングを行うための設定です。今回Doctrine2はpackageとして取得していますのでこの部分は不要です。
cacheの設定
resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\MemcacheCache"
となっていますが、開発環境のPHPにmemcachedモジュールが入っていない場合はDoctrine CLIでエラーが出てしまいます。自分でmemcachedを入れるなり他のcacheモジュールを使うなりしましょう。MAMPを使用している場合はAPCがすでに組み込まれているので
resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\ApcCache"
としておけばよいでしょう。
なお、開発中は最もベーシックなArrayCacheを使うと都合が良いのでdevelopmentセクションに
resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\ArrayCache"
を追加します。
Doctrine ORM Configurationセクションのパス修正
Doctrineのパス指定をプロジェクトの構成に合わせます。
resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationFiles[] = APPLICATION_PATH "/../library/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"
コマンドラインツールの設定
CLIを使わなくてもDoctrineは動作しますが開発作業には実質不可欠なツールです。Bisnaが提供しているbin/doctrine.phpをプロジェクトにコピーするだけです。ただしCLIを使うのはdevelopment環境に限定したいので
defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
を
defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'development');
とします。
設定の確認
コマンドラインでプロジェクトのルートに移動して
php bin/doctrine.php
を実行します。
こんな感じでプロンプトが出力されればOKです。
今回設定した結果のapplication.iniファイルは以下です。
; -----------------------------; forked from https://github.com/guilhermeblanco/ZendFramework1-Doctrine2/blob/master/application/configs/application.ini; -----------------------------
[production]
; --------------------------; PHP Specific Configuration; --------------------------phpSettings.display_startup_errors = 0phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
; ----------------------------------------; Zend Framework Application Configuration; ----------------------------------------bootstrap.path = APPLICATION_PATH "/Bootstrap.php"bootstrap.class = "Bootstrap"
pluginPaths.Bisna\Application\Resource\ = "Bisna/Application/Resource"
autoloaderNamespaces[] = BisnaautoloaderNamespaces[] = SymfonyautoloaderNamespaces[] = DoctrineautoloaderNamespaces[] = Application\Entity
appnamespace = "Application"
; ------------------------------; Front Controller Configuration; ------------------------------
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"resources.frontController.params.displayExceptions = 0
; ------------------------------------------------------------------------------; Doctrine Class Loader Configuration; ------------------------------------------------------------------------------
; resources.doctrine.classLoader.loaderClass = "Doctrine\Common\ClassLoader"; resources.doctrine.classLoader.loaderFile = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php"; ; resources.doctrine.classLoader.loaders.doctrine_common.namespace = "Doctrine\Common"; resources.doctrine.classLoader.loaders.doctrine_common.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor/doctrine-common/lib"; ; resources.doctrine.classLoader.loaders.doctrine_dbal.namespace = "Doctrine\DBAL"; resources.doctrine.classLoader.loaders.doctrine_dbal.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor/doctrine-dbal/lib"; ; resources.doctrine.classLoader.loaders.doctrine_orm.namespace = "Doctrine\ORM"; resources.doctrine.classLoader.loaders.doctrine_orm.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib"; ; resources.doctrine.classLoader.loaders.symfony_console.namespace = "Symfony\Component\Console"; resources.doctrine.classLoader.loaders.symfony_console.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor"; ; resources.doctrine.classLoader.loaders.symfony_yaml.namespace = "Symfony\Component\Yaml"; resources.doctrine.classLoader.loaders.symfony_yaml.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor"
; ------------------------------------------------------------------------------; Doctrine Cache Configuration; ------------------------------------------------------------------------------
; Points to default cache instance to be used. Optional is only one cache is definedresources.doctrine.cache.defaultCacheInstance = default
; Cache Instance configuration for "default" cache;resources.doctrine.cache.instances.default.id = defaultresources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\MemcacheCache"
resources.doctrine.cache.instances.default.namespace = "Application_"resources.doctrine.cache.instances.default.options.servers.0.host = localhostresources.doctrine.cache.instances.default.options.servers.0.port = 11211;resources.doctrine.cache.instances.default.options.servers.0.persistent = true;resources.doctrine.cache.instances.default.options.servers.0.weight = 1;resources.doctrine.cache.instances.default.options.servers.0.timeout = 1;resources.doctrine.cache.instances.default.options.servers.0.retryInterval = 15;resources.doctrine.cache.instances.default.options.servers.0.status = true
; ------------------------------------------------------------------------------; Doctrine DBAL Configuration; ------------------------------------------------------------------------------
; Points to default connection to be used. Optional if only one connection is definedresources.doctrine.dbal.defaultConnection = default
; DBAL Connection configuration for "default" connection;resources.doctrine.dbal.connections.default.id = default;resources.doctrine.dbal.connections.default.eventManagerClass = "Doctrine\Common\EventManager";resources.doctrine.dbal.connections.default.eventSubscribers[] = "DoctrineExtensions\Sluggable\SluggableSubscriber";resources.doctrine.dbal.connections.default.configurationClass = "Doctrine\DBAL\Configuration";resources.doctrine.dbal.connections.default.sqlLoggerClass = "Doctrine\DBAL\Logging\EchoSQLLogger";resources.doctrine.dbal.connections.default.types.my_type = "Application\DBAL\Type\MyType"
; Database configuration;resources.doctrine.dbal.connections.default.parameters.wrapperClass = ""resources.doctrine.dbal.connections.default.parameters.driver = "pdo_mysql"resources.doctrine.dbal.connections.default.parameters.dbname = "fmm"resources.doctrine.dbal.connections.default.parameters.host = "localhost"resources.doctrine.dbal.connections.default.parameters.port = 3306resources.doctrine.dbal.connections.default.parameters.user = "root"resources.doctrine.dbal.connections.default.parameters.password = "password";resources.doctrine.dbal.connections.default.parameters.driverOptions.ATTR_USE_BUFFERED_QUERIES = true
; ------------------------------------------------------------------------------; Doctrine ORM Configuration; ------------------------------------------------------------------------------
; Points to default EntityManager to be used. Optional if only one EntityManager is definedresources.doctrine.orm.defaultEntityManager = default
; EntityManager configuration for "default" manager;resources.doctrine.orm.entityManagers.default.id = default;resources.doctrine.orm.entityManagers.default.entityManagerClass = "Doctrine\ORM\EntityManager";resources.doctrine.orm.entityManagers.default.configurationClass = "Doctrine\ORM\Configuration";resources.doctrine.orm.entityManagers.default.entityNamespaces.app = "Application\Entity"resources.doctrine.orm.entityManagers.default.connection = defaultresources.doctrine.orm.entityManagers.default.proxy.autoGenerateClasses = trueresources.doctrine.orm.entityManagers.default.proxy.namespace = "Application\Entity\Proxy"resources.doctrine.orm.entityManagers.default.proxy.dir = APPLICATION_PATH "/../library/Application/Entity/Proxy";resources.doctrine.orm.entityManagers.default.metadataCache = default;resources.doctrine.orm.entityManagers.default.queryCache = default;resources.doctrine.orm.entityManagers.default.resultCache = default;resources.doctrine.orm.entityManagers.default.DQLFunctions.numeric.PI = "DoctrineExtensions\ORM\Query\Functions\Numeric\PiFunction"resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationFiles[] = APPLICATION_PATH "/../library/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php";resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationNamespaces.0.namespace = "Gedmo";resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationNamespaces.0.includePath = APPLICATION_PATH "/../library/vendor"resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.adapterClass = "Doctrine\ORM\Mapping\Driver\AnnotationDriver"resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.mappingNamespace = "Application\Entity"resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.mappingDirs[] = APPLICATION_PATH "/../library/Application/Entity"resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderClass = "Doctrine\Common\Annotations\AnnotationReader"resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderCache = default;resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderNamespaces.App = "Application\DoctrineExtensions\ORM\Mapping"
[staging : production]
[testing : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1
[development : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1resources.frontController.params.displayExceptions = 1resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\ArrayCache"
(その2へ続く)


Pingback: Zend Framework1 + Doctrine2 + twigを組み合わせる(その2) | KDF Memo