Zend Framework 2.0 體驗~

Zend Framework 2.0

使用前請先參觀ZF2 wiki

安裝方式

前往GIT 作clone 動作取得整個程式.

使用方式

依照正常使用方式 zf create project test1….etc

設定檔與ZF1 不同之處

1
2
3
4
5
6
7
8
resources.db.adapter         = "pdo_mysql"
resources.db.params.host     = "localhost"
resources.db.params.username = "test"
resources.db.params.password = "123456"
resources.db.params.dbname   = "test"
resources.db.params.charset  = "UTF8"
resources.db.params.driver_options.1002 = "SET NAMES utf8"
resources.db.params.profiler.enabled = true
1
2
3
4
5
6
7
8
resources.db.adapter         = "PdoMysql"
resources.db.params.host     = "localhost"
resources.db.params.username = "test"
resources.db.params.password = "123456"
resources.db.params.dbname   = "test"
resources.db.params.charset  = "UTF8"
resources.db.params.driver_options.1002 = "SET NAMES utf8"
resources.db.params.profiler.enabled = true

resources.db.adapter 名稱因為整個架構名稱不同所以必須變更.

Doctrine 入門(一)

準備

依照之前整合的 Zend Framework 1.11.0 and Doctrine 1.2.3 and Smarty 3.0.4 環境,來做學習與測試.
更改index.php

< ?php
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    realpath(APPLICATION_PATH . '/../models'),
    realpath(APPLICATION_PATH . '/../models/generated'),
    get_include_path(),
)));

application.ini 環境

;Doctrine
autoloaderNamespaces[] = "Doctrine_"
pluginPaths.ZendX_Doctrine_Application_Resource = "ZendX/Application/Resource"
resources.doctrine.debug = 1
resources.doctrine.paths.models_path = APPLICATION_PATH "/../models"
resources.doctrine.connections.orm1.dsn.adapter = mysql
resources.doctrine.connections.orm1.dsn.user = "user"
resources.doctrine.connections.orm1.dsn.pass = "password"
resources.doctrine.connections.orm1.dsn.hostspec = "localhost"
resources.doctrine.connections.orm1.dsn.database = "orm1_sd_idv_tw"

檔案架構

Read More

Zend Framework multidb 不好用我自己來 Mudb

源由

Zend Framework 的 multidb 有用過因該知道,只是可以把多跟資料庫加入連結 要用時候在拿出其中之一DB來用.
有做過大型連結資料庫的使用著因該深有同感. 你們常做的動作並不是只要拿其中之一的db來做動作.
這樣動作只有在多個不同資料庫才有用而已.(如同時存取mysql mssql ….)

改進功能

  1. 讀寫分離.
  2. 讀取輪詢,分散式負載.
  3. 多重寫入

看到這邊不知道是否有引起你很大興趣呢?

除了讀寫分離,為何還需要讀取輪詢??

一般常用的資料庫,負載平衡主要也是為了分散負載.
不過你是否有跟我一樣困擾:

  • 已經分散了db讀取,卻需要每台server去分配db作為讀取.
  • 每台server都要不同的設定檔或環境,增加mis維護成本時間(煩不煩阿).
  • 某台slave db掛點,mis還須翻找server對應的db 表作為故障排除.當下還的傷透腦筋不知派哪個db給server用

你的福音來了!!使用他每台db使用固定對應表.

此套件運作模式分為Mw & RW 兩種.

Rw模式

可以設定多個matser和多個slave.
在使用下列取的資料的db function時視為 讀取動作

public function fetchAll($sql, $bind = array(), $fetchMode = null){}
public function fetchRow($sql, $bind = array(), $fetchMode = null){}
public function fetchAssoc($sql, $bind = array()){}
public function fetchCol($sql, $bind = array()){}
public function fetchPairs($sql, $bind = array()){}
public function fetchOne($sql, $bind = array()){}

在使用下列取的資料的db function時視為 寫入動作

public function insert($table, array $bind)
public function update($table, array $bind, $where = '')
public function delete($table, $where = '')

看範例說明比較快:
檔案application.ini

; multirwdb Databse setting
autoloadernamespaces[] = "Mudb"
pluginPaths.Mudb_Application_Resource = "Mudb/Application/Resource"
resources.multirwdb.model = "Rw"
resources.multirwdb.master[] = "db1"
resources.multirwdb.master[] = "db5"
resources.multirwdb.slave[] = "db2"
resources.multirwdb.slave[] = "db3"
resources.multirwdb.slave[] = "db4"
resources.multirwdb.db.db1.adapter = "pdo_mysql"
resources.multirwdb.db.db1.host     = "localhost"
resources.multirwdb.db.db1.username = "wacow"
resources.multirwdb.db.db1.password = "123456"
resources.multirwdb.db.db1.dbname   = "wacow"
resources.multirwdb.db.db1.charset  = "UTF8"
resources.multirwdb.db.db1.profiler.enabled = true
resources.multirwdb.db.db1.profiler.class = "Zend_Db_Profiler_Firebug"
 
resources.multirwdb.db.db2.adapter = "pdo_mysql"
resources.multirwdb.db.db2.host     = "localhost"
resources.multirwdb.db.db2.username = "wacow"
resources.multirwdb.db.db2.password = "123456"
resources.multirwdb.db.db2.dbname   = "wacow"
resources.multirwdb.db.db2.charset  = "UTF8"
resources.multirwdb.db.db2.profiler.enabled = true
resources.multirwdb.db.db2.profiler.class = "Zend_Db_Profiler_Firebug"
resources.multirwdb.db.db2.default = true
 
resources.multirwdb.db.db3.adapter = "pdo_mysql"
resources.multirwdb.db.db3.host     = "localhost"
resources.multirwdb.db.db3.username = "wacow"
resources.multirwdb.db.db3.password = "123456"
resources.multirwdb.db.db3.dbname   = "wacow"
resources.multirwdb.db.db3.charset  = "UTF8"
resources.multirwdb.db.db3.profiler.enabled = true
resources.multirwdb.db.db3.profiler.class = "Zend_Db_Profiler_Firebug"
resources.multirwdb.db.db3.default = true
 
resources.multirwdb.db.db4.adapter = "pdo_mysql"
resources.multirwdb.db.db4.host     = "localhost"
resources.multirwdb.db.db4.username = "wacow"
resources.multirwdb.db.db4.password = "123456"
resources.multirwdb.db.db4.dbname   = "wacow"
resources.multirwdb.db.db4.charset  = "UTF8"
resources.multirwdb.db.db4.profiler.enabled = true
resources.multirwdb.db.db4.profiler.class = "Zend_Db_Profiler_Firebug"
resources.multirwdb.db.db4.default = true
 
resources.multirwdb.db.db5.adapter = "pdo_mysql"
resources.multirwdb.db.db5.host     = "localhost"
resources.multirwdb.db.db5.username = "wacow"
resources.multirwdb.db.db5.password = "123456"
resources.multirwdb.db.db5.dbname   = "wacow"
resources.multirwdb.db.db5.charset  = "UTF8"
resources.multirwdb.db.db5.profiler.enabled = true
resources.multirwdb.db.db5.profiler.class = "Zend_Db_Profiler_Firebug"
resources.multirwdb.db.db5.default = true

檔案Bootstrap.php

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
	protected $_defaultDb = null;
	protected $_CacheDB = null;
	protected $_View = null;
	protected $_Customer = null;
	protected function _initDatabase() {
		if ($this->_defaultDb === null) {
			if ($this->hasPluginResource('multirwdb')) {
				$this->bootstrap('multirwdb');
				$resource = $this->getPluginResource('multirwdb');
				$this->_defaultDb = $resource->getDefaultDb();
			}elseif($this->hasPluginResource('db')){
				$this->bootstrap('db');
				$this->_defaultDb = $this->getPluginResource('db')->getDbAdapter();
			}
		}
		Zend_Registry::set('db',$this->_defaultDb);
	}
     protected function _initZFDebug() {
    if ($this->_defaultDb === null) {
			$this->_initDatabase();
    }
		$options = array(
	    	'plugins' => array(
				'Html',
				'Variables',
				'Memory',
				'Time',
				'Database' => ($this->hasPluginResource('multirwdb')) ? array('adapter' => MuDB_Db::getAllDb()) : array('adapter' => array('default' => $this->_defaultDb)),
				'File' => array('base_path' => realpath(APPLICATION_PATH . '/../')),
				'Registry',
				'Exception',
	 	));
    $debug = new ZFDebug_Controller_Plugin_Debug($options);
		$this->bootstrap('frontController');
		$frontController = $this->getResource('frontController');
		$frontController->registerPlugin($debug);
 
	}

檔案IndexController.php

<?php
class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        $this->db=Zend_Registry::get('db');
    }
 
    public function indexAction()
    {
		$select_test = $this->db->select()->from('system_permissions', '*')->limit(100);
		$result = $this->db->fetchAll($select_test);
		$result = $this->db->fetchAll($select_test);
		$result = $this->db->fetchAll($select_test);
		$result = $this->db->fetchAll($select_test);
		$data= array('test' => rand(5, 15));
		$this->db->insert('test', $data);
    }
}

執行畫面解說:
在IndexController.php indexAction()下我們只是如同往常對單一的db做讀取動做.
總共做了4次,卻在不同db下查詢完成.
卻可以看到執行畫面下,自動輪詢查詢取的資料.
你是否可以發現程式設計師不用傷透腦筋去更改程式碼即可使用此套件即可完成!!
而寫入動作 $this->db->insert(‘test’, $data);
卻是對全部的MASTER做一併寫入更改!!

Mw模式

Mw模式基本上是Rw延伸
設定檔只存取master部分設定!!!
如範例檔案application.ini
只有db1 db5被引用
並將model改為Mw resources.multirwdb.model = “Mw"
而Mw模式下對db做讀取動做會做輪詢.(每個master都會輪詢等同Rw的slave)
寫入動作則一樣,全部寫入.

注意事項

不再列表的圖取寫入動作則做為對db直接的使用.
Rw模式會限制每個Slave db必須為相同的adapter,此處設限為了避免不小心混用db而渾然不知.
因為很多程式設計師select用法會而不同的資料庫而使用特殊語法.

寫入的特殊應用

而不管為Rw 或MW模式 對於寫入動作則不設限.
此方式可以實現有趣的功能 同時對不同的db來源(如同時對mssql 與mysql做同步更新 不過前提是兩邊資料表必須詳同),資料同步寫入變更!!!

總結

此套件花了近一個月修改,其中的經驗與處理模式不知是否讓你產生感慨~~
這些經驗都是爆肝來的,如有取用或發佈請保留引用來源.(檔案內並未有版權註解請隨意使用)
到這邊你以為沒了嗎???
其實還有西可以實現,如本來要加入的讀取權重(但是我不能再爆肝了 交由你吧QQ)
為何需要讀取權重??
很多系統會有開發報表等等做大量的資料處理(例如報表)
如果此時有權重分配即可像此套件的使用方式一樣不用額外定義,只需對大量的讀取另做讀取做權重區分!!

感謝收看 再會byby~~

附件檔案:Mudb.tar

Zend Framework + Smarty3 整合應用

承上篇 Zend Framework + Smarty2 + Smarty3 整合應用
我曾說過:之前有使用過ZFDebug 感受到整合便利性
所以對之前整合不甚滿意.
來看看最新版本~
將附件內的Smarty3拷貝到你的library目錄內
application.ini

autoloadernamespaces[] = "Smarty3"
pluginPaths.Smarty3_Application_Resource = "Smarty3/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.plugins_dir = APPLICATION_PATH "/lib/My/Smarty/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_"

確認好樣板檔案格式,與目錄屬性.
然後Bootstrap.php呢???

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

你已經完成了!

這就是我要的整合~~

附件檔案:ZF_Smarty3.tar

Zend Framework + Smarty2 + Smarty3 整合應用

在你開始閱讀前請先前往鐵神:Smarty 2 整合到 Zend Framework 1.10 閱讀完畢並了解.

之前有使用過ZFDebug 感受到整合便利性,於是在整合Sarmty 時想嘗試類似方式做到方便的整合.

Smarty 2

將附件內的Smarty2拷貝到你的library目錄內
在你的application.ini加入

autoloadernamespaces[] = "Smarty2"

Bootstrap.php 範例

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
		protected function _initView(){
	        $view = new Smarty2_View_Smarty (array(
			            'scriptPath' => APPLICATION_PATH . '/',
			            'params' => array(
			                'left_delimiter' => '<%', // 改成你慣用的
			                'right_delimiter' => '%>', // 改成你慣用的
			                'plugins_dir' => APPLICATION_PATH . '/library/Smarty2/Smarty/plugins', // 自訂的 Smarty plugins 可以放這裡
			                'compile_dir' => APPLICATION_PATH . '/../tmp/compiled',
			            ),
			            'helper_dirs' => array(
			                //'My/View/Helper' => 'My_View_Helper_', // 如果將來需要自己的 View Helper ,可以放在這裡
			                'Zend/View/Helper' => 'Zend_View_Helper_'
			            ),
			        ));
 
 
	        // Controller Plugin
	        Zend_Controller_Front::getInstance()->registerPlugin(new Smarty2_Controller_Plugin_Smarty());
 
	        // View Renderer
	        Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer')
	            ->setViewSuffix('tpl.htm') // 可以改成慣用的樣版副檔名
	            ->setView($view);
 
	        // Zend Layout
	        $view->layout = Zend_Layout::startMvc(array(
	            'inflectorTarget' => 'layouts/scripts/:script.:suffix',
	            'layout' => 'layout',
	            'viewSuffix' => 'tpl.htm', // 可以改成慣用的樣版副檔名
	        ))->setView($view);
	    }
}

Smarty 3

Smarty3 得特性在浙次整合並沒有發揮,只是先依照以前Smarty2的用法去用而已.
所以與Smarty 2 整合大同小異.
將附件內的Smarty3拷貝到你的library目錄內
在你的application.ini加入

autoloadernamespaces[] = "Smarty3"

Bootstrap.php 範例

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
		protected function _initView(){
	        $view = new Smarty3_View_Smarty (array(
			            'scriptPath' => APPLICATION_PATH . '/',
			            'params' => array(
			                'left_delimiter' => '<%', // 改成你慣用的
			                'right_delimiter' => '%>', // 改成你慣用的
			                'plugins_dir' => APPLICATION_PATH . '/library/Smarty3/Smarty/plugins', // 自訂的 Smarty plugins 可以放這裡
			                'compile_dir' => APPLICATION_PATH . '/../tmp/compiled',
			            ),
			            'helper_dirs' => array(
			                //'My/View/Helper' => 'My_View_Helper_', // 如果將來需要自己的 View Helper ,可以放在這裡
			                'Zend/View/Helper' => 'Zend_View_Helper_'
			            ),
			        ));
 
 
	        // Controller Plugin
	        Zend_Controller_Front::getInstance()->registerPlugin(new Smarty3_Controller_Plugin_Smarty());
 
	        // View Renderer
	        Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer')
	            ->setViewSuffix('tpl.htm') // 可以改成慣用的樣版副檔名
	            ->setView($view);
 
	        // Zend Layout
	        $view->layout = Zend_Layout::startMvc(array(
	            'inflectorTarget' => 'layouts/scripts/:script.:suffix',
	            'layout' => 'layout',
	            'viewSuffix' => 'tpl.htm', // 可以改成慣用的樣版副檔名
	        ))->setView($view);
	    }
}

注意如果你於使用中 compile_dir目錄未建置或不可讀寫並且使用ZFDebug.會發現空白頁面並且無任何訊息.

請先參考附件架構.
附件:zf_smarty

Zend Famework 1.10.3 + ZFDebug

對基本架構不了解可先前往 鐵神: http://www.jaceju.net/blog/?p=1077

此架構為快速架構起始專案的設定

application.ini 內容

[production]
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
 
autoloadernamespaces[] = "ZFDebug"
;Stand Databse setting
resources.db.adapter         = "pdo_mysql"
resources.db.params.host     = "localhost"
resources.db.params.username = "wacow"
resources.db.params.password = "123456"
resources.db.params.dbname   = "wacow"
resources.db.params.charset  = "UTF8"
resources.db.params.profiler = true
;resources.db.isDefaultTableAdapter = true
; Multidb Databse setting
resources.multidb.db1.adapter = "pdo_mysql"
resources.multidb.db1.host     = "localhost"
resources.multidb.db1.username = "wacow"
resources.multidb.db1.password = "123456"
resources.multidb.db1.dbname   = "wacow"
resources.multidb.db1.charset  = "UTF8"
resources.multidb.db1.params.profiler.enabled = true
resources.multidb.db1.params.profiler.class = "Zend_Db_Profiler_Firebug"
 
resources.multidb.db2.adapter = "pdo_mysql"
resources.multidb.db2.host     = "localhost"
resources.multidb.db2.username = "wacow"
resources.multidb.db2.password = "123456"
resources.multidb.db2.dbname   = "wacow"
resources.multidb.db2.charset  = "UTF8"
resources.multidb.db2.params.profiler.enabled = true
resources.multidb.db2.params.profiler.class = "Zend_Db_Profiler_Firebug"
;resources.multidb.db2.default = true
 
[staging : production]
 
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
 
[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

不同以往 要起始ZFDebug只要加入

autoloadernamespaces[] = "ZFDebug"

並在DB加入 Zend_Db_Profiler_Firebug設定

<?php
 
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
	protected $_defaultDb = null;
	protected function _initDatabase() {
		if ($this->_defaultDb === null) {
		if ($this->hasPluginResource('multidb')) {
			$this->bootstrap('multidb');
			$resource = $this->getPluginResource('multidb');
			$this->_defaultDb = $resource->getDefaultDb();
		}elseif($this->hasPluginResource('db')){
			$this->bootstrap('db');
			$this->_defaultDb = $this->getPluginResource('db')->getDbAdapter();
		}}
	}
	protected function _initZFDebug() {
		$options = array(
	    	'plugins' => array(
	    	'Html',
				'Variables',
				'File' => array('base_path' => realpath(APPLICATION_PATH . '/../')),
				'Memory',
				'Time',
				'Registry',
				'Exception',
	 	));
		if ($this->_defaultDb === null) {
            $this->_initDatabase();
        }
		$options['plugins']['Database']['adapter'] = $this->_defaultDb;
		$debug = new ZFDebug_Controller_Plugin_Debug($options);
 
		$this->bootstrap('frontController');
		$frontController = $this->getResource('frontController');
		$frontController->registerPlugin($debug);
	}
}

_initDatabase() 部份有實座分離單資料庫與多重資料庫的試驗.
其他尚在研究中……………….

改造 ZF架構呼叫檔案方式


(點圖看大圖)

加了自己的 loadfiles class

改掉ZF LOADER 內的 static function loadFile 的 include 改為我的loadfiles class.

有看過原圖的人會發現大不同了.

原架構的ZF執行狀況


2010-03-03WACOW FAMEWORK原始架構

2010-03-04 WACOW FAMEWORK改造

2010-03-12 WACOW FAMEWORK 改造最終版 避開SMARTY,其餘ZNED 和其他 LIBRARY 自動生成單個CACHE檔速度爆衝

12X檔檔案載入 變成一個喔 include_all.php.cache