Zend Framework 1.11.0 and Doctrine 1.2.3 and Smarty 3.0.4
by admin on 十一月.20, 2010, under Doctrine, PHP & MYSQL, Zend Framework
懶惰許久~~ 趕快來補一下功課.
這篇主要介紹 Zend Framework 1.11.0 and Doctrine 1.2.3 and Smarty 3.0.4 的結合方式.
Doctrine 1.2.3 跟 Zend Framework 1.11.0 結合主要參考 http://pastie.org/481633 http://pastie.org/481635 使用.
目錄結構:

將之前所做Smarty整合 與Doctrine 整合需要的放在一起,不像之前在個別目錄.
如果再像之前一樣, 放在個別目錄目錄會遇到升級版本不便利性.
現在將之後要整合的東西命名為ZendX.

之後Smarty要升級只需將Smarty3目錄內容替換.
來看看application.ini
phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 includePaths.library = APPLICATION_PATH "/../library" bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" appnamespace = "Application" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.frontController.params.displayExceptions = 0 ;resources.frontController.noViewRenderer = 1 resources.layout.layout = "layout" resources.layout.layoutPath[] = APPLICATION_PATH "/layouts/scripts/" resources.layout.viewSuffix = "tpl.htm" resources.layout.inflectorTarget = "layouts/scripts/:script.:suffix" autoloaderNamespaces[] = "ZendX_" ;Smarty3 pluginPaths.ZendX_Smarty3_Application_Resource = "ZendX/Application/Resource" resources.smarty.script_path = APPLICATION_PATH "/" resources.smarty.view_suffix = "tpl.htm" resources.smarty.params.left_delimiter = "<%" resources.smarty.params.right_delimiter = "%>" resources.smarty.params.auto_literal = 0 resources.smarty.params.plugins_dir = APPLICATION_PATH "/../Smarty3/plugins" resources.smarty.params.compile_dir = APPLICATION_PATH "/../tmp/compiled" resources.smarty.helper_dirs.key[] = "Zend/View/Helper" resources.smarty.helper_dirs.value[] = "Zend_View_Helper_" ;如果將來需要自己的 View Helper ,可以放在這裡 resources.smarty.helper_dirs.key[] = "My/View/Helper" resources.smarty.helper_dirs.value[] = "My_View_Helper_" ;Doctrine autoloaderNamespaces[] = "Doctrine_" pluginPaths.ZendX_Doctrine_Application_Resource = "ZendX/Application/Resource" resources.doctrine.connections.orm1.dsn = "mysql://user:password@hosts/db"
加入整合用的
autoloaderNamespaces[] = "ZendX_"
之前整合Smarty 未使用layout.
搞了半天發現只是要簡單的加入.
resources.layout.layout = "layout" resources.layout.layoutPath[] = APPLICATION_PATH "/layouts/scripts/" resources.layout.viewSuffix = "tpl.htm" resources.layout.inflectorTarget = "layouts/scripts/:script.:suffix"
其中主要為
resources.layout.viewSuffix = "tpl.htm" resources.layout.inflectorTarget = "layouts/scripts/:script.:suffix"
告訴ZF layout使用的目標與附檔名格式即可.
再來看看Doctrine
http://pastie.org/481633
此為主要Application Resource 內容如下
<?php class ZendX_Doctrine_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract { /** * @var Doctrine_Manager */ protected $_manager = null; /** * @var array */ protected $_paths = array(); /** * @var array */ protected $_profilers = array(); /** * Initialize Doctrine * * @return bool */ public function init() { Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true); $manager = $this->getManager(); if ($options = $this->getOptions()) { if (isset($options['paths'])) { $this->getPaths($options['paths']); } if (isset($options['attributes'])) { $this->getAttributes($options['attributes']); } if (isset($options['connections'])) { $this->getConnections($options['connections']); } if (isset($options['debug'])) { $this->getDebug($options['debug']); } } $registryData = array( 'paths' => $this->_paths, 'profilers' => $this->_profilers, ); Zend_Registry::set('doctrine', $registryData); return $manager; } /** * Retrieve manager instance * * @return Doctrine_Manager */ public function getManager() { if (null === $this->_manager) { try { $this->_manager = Doctrine_Manager::getInstance(); } catch (Doctrine_Exception $e) { /** @see Zend_Application_Resource_ResourceAbstract */ require_once 'ZendX/Doctrine/Application/Resource/Exception.php'; throw new ZendX_Doctrine_Application_Resource_Exception('Unable to retrieve Doctrine_Manager instance.'); } } return $this->_manager; } /** * Set global attributes * * @param array $attributes * @return ZendX_Doctrine_Application_Resource_Doctrine */ public function getAttributes(array $attributes = array()) { foreach ($attributes as $key => $value) { $this->_manager->setAttribute($key, $value); } return $this; } /** * Lazy load connections * * @param array $connections * @return ZendX_Doctrine_Application_Resource_Doctrine * * @todo Handle event listeners */ public function getConnections(array $connections = array()) { foreach ($connections as $name => $params) { if (!isset($params['dsn'])) { /** @see Zend_Application_Resource_ResourceAbstract */ require_once 'ZendX/Doctrine/Application/Resource/Exception.php'; throw new ZendX_Doctrine_Application_Resource_Exception('Doctrine resource dsn not present.'); } $dsn = null; if (is_string($params['dsn'])) { $dsn = $params['dsn']; } elseif (is_array($params['dsn'])) { $dsn = $this->_buildConnectionString($params['dsn']); } else { /** @see Zend_Application_Resource_ResourceAbstract */ require_once 'ZendX/Doctrine/Application/Resource/Exception.php'; throw new ZendX_Doctrine_Application_Resource_Exception("Invalid Doctrine resource dsn format."); } try { $conn = Doctrine_Manager::connection($dsn, $name); if (isset($params['attributes'])) { foreach ($params['attributes'] as $key => $value) { $conn->setAttribute($key, $value); } } if (isset($params['listeners']['connection'])) { foreach ($params['listeners']['connection'] as $alias => $class) { $listener = new $class(); $conn->addListener($listener, $alias); if ($listener instanceof Doctrine_Connection_Profiler) { $this->_profilers[] = $listener; } } } if (isset($params['listeners']['record'])) { foreach ($params['listeners']['record'] as $alias => $class) { $listener = new $class(); $conn->addRecordListener($listener, $alias); } } } catch(Doctrine_Exception $e) { /** @see Zend_Application_Resource_ResourceAbstract */ require_once 'ZendX/Doctrine/Application/Resource/Exception.php'; throw new ZendX_Doctrine_Application_Resource_Exception("Unable to establish connection named $name to $dsn."); } } return $this; } /** * Set the debug status * * @param bool $debug * @return ZendX_Doctrine_Application_Resource_Doctrine */ public function getDebug($debug = 0) { Doctrine::debug($debug); return $this; } /** * Set the paths array * * @param array $paths * @return ZendX_Doctrine_Application_Resource_Doctrine */ public function getPaths(array $paths = array()) { $this->_paths = $paths; return $this; } /** * Build connection string * * @param array $dsnData * @return string */ private function _buildConnectionString(array $dsnData = array()) { $connectionOptions = null; if ((isset($dsnData['options'])) || (!empty($dsnData['options']))) { $connectionOptions = $this->_buildConnectionOptionsString($dsnData['options']); } return sprintf('%s://%s:%s@%s/%s?%s', $dsnData['adapter'], $dsnData['user'], $dsnData['pass'], $dsnData['hostspec'], $dsnData['database'], $connectionOptions); } /** * Build connection options string * * @param array $optionsData * @return string */ private function _buildConnectionOptionsString(array $optionsData = array()) { $i = 0; $count = count($optionsData); $options = null; foreach ($optionsData as $key => $value) { if ($i == $count) { $options .= "$key=$value"; } else { $options .= "$key=$value&"; } $i++; } return $options; } }
使用時必須在你的public/index.php 內的增加修改這段.
// Ensure library/ is on include_path /*set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../library'), get_include_path(), )));*/ /** 修改為**/ set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../library'), realpath(APPLICATION_PATH . '/models'), realpath(APPLICATION_PATH . '/models/generated'), get_include_path(), )));
因為Doctrine 太強大可以引入各總sql 自定models…等等.
但是目前不太熟所以沒有針對Doctrine 做目錄規劃整合.
使用方式:
http://pastie.org/481635
1. Overview Zend_Application_Resource_Doctrine is intended to provide connection initialization and environment setup for Doctrine ORM. 2. References Zend_Application_Resource_ResourceAbstract 3. Component Requirements, Constraints, and Acceptance Criteria This component will require the use of the fallback autoload mechanism. TESTS >>> check autoloader property This will component will store an array of paths and profilers to the registry using the key 'doctrine'. This component will allow specification of an array of paths to be added to the registry. Typically these would include paths necessary to execute Doctrine tasks. TESTS >>> check for existence of registry key if one or more paths are set. This component will provide lazy loading of multiple connections. TESTS >>> check Doctrine_Manager connections This component will allow specification of global Doctrine environment settings. TESTS >>> check Doctrine settings This component will allow specification of connection level environment settings. TESTS >>> check Doctrine settings This component will allow specification of connection and record event listeners for connections. Modifying the existing environment is not supported. TESTS >>> check Doctrine_Connection properties Unsupported Features: - Cacheing - Persistent connections. See http://groups.google.com/group/doctrine-user/browse_thread/thread/19700db17bfe5470/eef3690beeffb72e? - Special cases of array, as opposed to string, properties attribute properties: resources.doctrine.attributes.default_column_options.length = 255 resources.doctrine.attributes.default_column_options.notnull = 1 resources.doctrine.attributes.default_column_options.type = "string" --- resources.doctrine.attributes.default_identifier_options.length = 16 resources.doctrine.attributes.default_identifier_options.name = "%s_id" resources.doctrine.attributes.default_identifier_options.type = "string" 4. Dependencies on Other Framework Components Doctrine Zend_Application Zend_Config 5. Theory of Operation Users will specify paths, data source names, attribute and event listeners in application.ini. Resources will be autoloaded when using Zend_Application. 6. Milestones / Tasks 7. Class Index ZendX_Doctrine_Application_Resource_Doctrine 8. Use Cases ------------------------------ Base Setup ------------------------------ Setup autoloader and plugin path in application/configs/application.ini: autoloadernamespaces.0 = "Doctrine" pluginpaths.ZendX_Doctrine_Application_Resource= "ZendX/Doctrine/Application/Resource" Add paths to models and generated models in public/index.php set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../library'), realpath(APPLICATION_PATH . '/models'), realpath(APPLICATION_PATH . '/models/generated'), get_include_path(), ))); ------------------------------ Set Debug Status 是否開啟debug ------------------------------ resources.doctrine.debug = 1 ------------------------------ Use Single Connection (string) 單一連接(使用dsn字串) ------------------------------ resources.doctrine.connections.cx1.dsn = "mysql://user:pass@host/cx1" ------------------------------ Use Multiple Connections (string) 多重連接(使用dsn字串) ------------------------------ resources.doctrine.connections.cx1.dsn = "mysql://user:pass@host/cx1" resources.doctrine.connections.cx2.dsn = "mysql://user:pass@host/cx2" ------------------------------ Use Single Connection (array) 單一連接 ------------------------------ resources.doctrine.connections.cx1.dsn.adapter = mysql resources.doctrine.connections.cx1.dsn.user = user resources.doctrine.connections.cx1.dsn.pass = pass resources.doctrine.connections.cx1.dsn.hostspec = host resources.doctrine.connections.cx1.dsn.database = cx1 resources.doctrine.connections.cx1.dsn.options.option1 = value resources.doctrine.connections.cx1.dsn.options.option2 = value ------------------------------ Use Multiple Connections (array) 多重連接 ------------------------------ resources.doctrine.connections.cx1.dsn.adapter = mysql resources.doctrine.connections.cx1.dsn.user = user resources.doctrine.connections.cx1.dsn.pass = pass resources.doctrine.connections.cx1.dsn.hostspec = host resources.doctrine.connections.cx1.dsn.database = cx1 resources.doctrine.connections.cx1.dsn.options.option1 = value resources.doctrine.connections.cx1.dsn.options.option2 = value resources.doctrine.connections.cx2.dsn.adapter = mysql resources.doctrine.connections.cx2.dsn.user = user resources.doctrine.connections.cx2.dsn.pass = pass resources.doctrine.connections.cx2.dsn.hostspec = host resources.doctrine.connections.cx2.dsn.database = cx2 resources.doctrine.connections.cx2.dsn.options.option1 = value resources.doctrine.connections.cx2.dsn.options.option2 = value ------------------------------ Set Global Attributes 設定全域共用屬性 ------------------------------ resources.doctrine.attributes.auto_accessor_override = 0 resources.doctrine.attributes.auto_free_query_objects = 1 resources.doctrine.attributes.autoload_table_classes = 0 resources.doctrine.attributes.coll_key = resources.doctrine.attributes.dbname_format = "appname_%s" resources.doctrine.attributes.export = "all" resources.doctrine.attributes.idxname_format = "%s_index" resources.doctrine.attributes.model_loading = "conservative" resources.doctrine.attributes.portability = "all" resources.doctrine.attributes.query_cache = resources.doctrine.attributes.query_limit = resources.doctrine.attributes.quote_identifier = 0 resources.doctrine.attributes.result_cache = resources.doctrine.attributes.result_cache_lifespan = 3600 resources.doctrine.attributes.seqname_format = "%s_sequence" resources.doctrine.attributes.tblname_format = "%s_table" resources.doctrine.attributes.use_dql_callbacks = 1 resources.doctrine.attributes.use_native_enum = 0 resources.doctrine.attributes.validate = "all" ------------------------------ Set Connection Attributes 自定連接資料庫屬性 ------------------------------ resources.doctrine.connections.cx1.attributes.auto_accessor_override = 0 resources.doctrine.connections.cx1.attributes.auto_free_query_objects = 1 resources.doctrine.connections.cx1.attributes.autoload_table_classes = 0 resources.doctrine.connections.cx1.attributes.coll_key = resources.doctrine.connections.cx1.attributes.dbname_format = "appname_%s" resources.doctrine.connections.cx1.attributes.export = "all" resources.doctrine.connections.cx1.attributes.idxname_format = "%s_index" resources.doctrine.connections.cx1.attributes.model_loading = "conservative" resources.doctrine.connections.cx1.attributes.portability = "all" resources.doctrine.connections.cx1.attributes.query_cache = resources.doctrine.connections.cx1.attributes.query_limit = resources.doctrine.connections.cx1.attributes.quote_identifier = 0 resources.doctrine.connections.cx1.attributes.result_cache = resources.doctrine.connections.cx1.attributes.result_cache_lifespan = 3600 resources.doctrine.connections.cx1.attributes.seqname_format = "%s_sequence" resources.doctrine.connections.cx1.attributes.tblname_format = "%s_table" resources.doctrine.connections.cx1.attributes.use_dql_callbacks = 1 resources.doctrine.connections.cx1.attributes.use_native_enum = 0 resources.doctrine.connections.cx1.attributes.validate = "all" ------------------------------ Attach Connection Listeners to Connections ------------------------------ resources.doctrine.connections.cx1.listeners.connection.listener1 = My_Listener1 resources.doctrine.connections.cx1.listeners.connection.listener2 = My_Listener2 resources.doctrine.connections.cx2.listeners.connection.listener2 = My_Listener2 resources.doctrine.connections.cx2.listeners.connection.listener2 = My_Listener2 ------------------------------ Attach Record Listeners to Connections ------------------------------ resources.doctrine.connections.cx1.listeners.record.listener1 = My_Listener1 resources.doctrine.connections.cx1.listeners.record.listener2 = My_Listener2 resources.doctrine.connections.cx2.listeners.record.listener1 = My_Listener1 resources.doctrine.connections.cx2.listeners.record.listener2 = My_Listener2 ------------------------------ Add Paths to Registry 自定相關目錄 ------------------------------ resources.doctrine.paths.data_fixtures_path = APPLICATION_PATH "/../doctrine/data/fixtures" resources.doctrine.paths.migrations_path = APPLICATION_PATH "/../doctrine/migrations" resources.doctrine.paths.models_path = APPLICATION_PATH "/models" resources.doctrine.paths.yamlschema_path = APPLICATION_PATH "/../doctrine/schema" resources.doctrine.paths.sql_path = APPLICATION_PATH "/../doctrine/data/sql" 9. Class Skeletons ZendX_Doctrine_Application_Resource_Doctrine
此次檔案包含上述整合內容還有ZFDebug Doctrine ORM plugin
點我下載:library

一月 16th, 2011 on 03:16:26
I am sorry I can’t write in Chinese, and I hope you can understand this.
I am attempting to follow your examples above, but I am having an issue with Smarty. Here is the errors I am getting:
Warning: include_once(Smarty.php): failed to open stream: No such file or directory in /usr/local/zend/share/ZendFramework/library/Zend/Loader.php on line 146 Warning: include_once(): Failed opening ‘Smarty.php’ for inclusion (include_path=’/usr/local/zend/apache2/htdocs/groups/application/../library:/usr/local/zend/apache2/htdocs/groups/library:/usr/local/zend/apache2/htdocs/groups/application/models::.:/usr/local/zend/share/ZendFramework/library:/usr/local/zend/share/pear’) in /usr/local/zend/share/ZendFramework/library/Zend/Loader.php on line 146 Fatal error: Class ‘Smarty’ not found in /usr/local/zend/apache2/htdocs/groups/library/ZendX/View/Smarty.php on line 5
I uncomment out the require_once in ZendX/View/Smarty.php and it moves forward but then it is unable to load the Smarty plugins, specifically Smarty/Internal/Data.php.
Any ideas?
二月 9th, 2011 on 01:50:20
try add to /public/index.php
require_once APPLICATION_PATH . ‘/../library/Smarty3/Smarty.class.php’;