Welcome 微信登录

首页 / 网页编程 / PHP / Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解

本文实例讲述了Zend Framework教程之分发器Zend_Controller_Dispatcher用法。分享给大家供大家参考,具体如下:
分发器的具体实现
Zend Framework的分发器Zend_Controller_Dispatcher设计主要有,如下类和接口组成:
├── Dispatcher
│   ├── Abstract.php
│   ├── Exception.php
│   ├── Interface.php
│   └── Standard.php
Zend_Controller_Dispatcher_Interface
定义了分发器提供的基本和标准功能。
interface Zend_Controller_Dispatcher_Interface{public function formatControllerName($unformatted);public function formatModuleName($unformatted);public function formatActionName($unformatted);public function isDispatchable(Zend_Controller_Request_Abstract $request);public function setParam($name, $value);public function setParams(array $params);public function getParam($name);public function getParams();public function clearParams($name = null);public function setResponse(Zend_Controller_Response_Abstract $response = null);public function getResponse();public function addControllerDirectory($path, $args = null);public function setControllerDirectory($path);public function getControllerDirectory();public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response);public function isValidModule($module);public function getDefaultModule();public function getDefaultControllerName();public function getDefaultAction();}
Zend_Controller_Dispatcher_Abstract
实现了Zend_Controller_Dispatcher_Interface接口,提供了分发器提供的基本和标准功能的抽象父类。
<?php/** Zend_Controller_Dispatcher_Interface */require_once "Zend/Controller/Dispatcher/Interface.php";abstract class Zend_Controller_Dispatcher_Abstract implements Zend_Controller_Dispatcher_Interface{protected $_defaultAction = "index";protected $_defaultController = "index";protected $_defaultModule = "default";protected $_frontController;protected $_invokeParams = array();protected $_pathDelimiter = "_";protected $_response = null;protected $_wordDelimiter = array("-", ".");public function __construct(array $params = array()){$this->setParams($params);}public function formatControllerName($unformatted){return ucfirst($this->_formatName($unformatted)) . "Controller";}public function formatActionName($unformatted){$formatted = $this->_formatName($unformatted, true);return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . "Action";}public function _verifyDelimiter($spec){if (is_string($spec)) {return (array) $spec;} elseif (is_array($spec)) {$allStrings = true;foreach ($spec as $delim) {if (!is_string($delim)) {$allStrings = false;break;}}if (!$allStrings) {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Word delimiter array must contain only strings");}return $spec;}require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Invalid word delimiter");}public function getWordDelimiter(){return $this->_wordDelimiter;}public function setWordDelimiter($spec){$spec = $this->_verifyDelimiter($spec);$this->_wordDelimiter = $spec;return $this;}public function getPathDelimiter(){return $this->_pathDelimiter;}public function setPathDelimiter($spec){if (!is_string($spec)) {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Invalid path delimiter");}$this->_pathDelimiter = $spec;return $this;}protected function _formatName($unformatted, $isAction = false){// preserve directoriesif (!$isAction) {$segments = explode($this->getPathDelimiter(), $unformatted);} else {$segments = (array) $unformatted;}foreach ($segments as $key => $segment) {$segment= str_replace($this->getWordDelimiter(), " ", strtolower($segment));$segment= preg_replace("/[^a-z0-9 ]/", "", $segment);$segments[$key] = str_replace(" ", "", ucwords($segment));}return implode("_", $segments);}public function getFrontController(){if (null === $this->_frontController) {require_once "Zend/Controller/Front.php";$this->_frontController = Zend_Controller_Front::getInstance();}return $this->_frontController;}public function setFrontController(Zend_Controller_Front $controller){$this->_frontController = $controller;return $this;}public function setParam($name, $value){$name = (string) $name;$this->_invokeParams[$name] = $value;return $this;}public function setParams(array $params){$this->_invokeParams = array_merge($this->_invokeParams, $params);return $this;}public function getParam($name){if(isset($this->_invokeParams[$name])) {return $this->_invokeParams[$name];}return null;}public function getParams(){return $this->_invokeParams;}public function clearParams($name = null){if (null === $name) {$this->_invokeParams = array();} elseif (is_string($name) && isset($this->_invokeParams[$name])) {unset($this->_invokeParams[$name]);} elseif (is_array($name)) {foreach ($name as $key) {if (is_string($key) && isset($this->_invokeParams[$key])) {unset($this->_invokeParams[$key]);}}}return $this;}public function setResponse(Zend_Controller_Response_Abstract $response = null){$this->_response = $response;return $this;}public function getResponse(){return $this->_response;}public function setDefaultControllerName($controller){$this->_defaultController = (string) $controller;return $this;}public function getDefaultControllerName(){return $this->_defaultController;}public function setDefaultAction($action){$this->_defaultAction = (string) $action;return $this;}public function getDefaultAction(){return $this->_defaultAction;}public function setDefaultModule($module){$this->_defaultModule = (string) $module;return $this;}public function getDefaultModule(){return $this->_defaultModule;}}
Zend_Controller_Dispatcher_Standard
ZendFramework继承抽象类Zend_Controller_Dispatcher_Abstract,定义了Zend_Controller_Dispatcher_Standard。Zend_Controller_Dispatcher_Standard是ZendFramework提供的基本的分发器,完成了分发功能。
<?php/** Zend_Loader */require_once "Zend/Loader.php";/** Zend_Controller_Dispatcher_Abstract */require_once "Zend/Controller/Dispatcher/Abstract.php";class Zend_Controller_Dispatcher_Standard extends Zend_Controller_Dispatcher_Abstract{protected $_curDirectory;protected $_curModule;protected $_controllerDirectory = array();public function __construct(array $params = array()){parent::__construct($params);$this->_curModule = $this->getDefaultModule();}public function addControllerDirectory($path, $module = null){if (null === $module) {$module = $this->_defaultModule;}$module = (string) $module;$path= rtrim((string) $path, "/\");$this->_controllerDirectory[$module] = $path;return $this;}public function setControllerDirectory($directory, $module = null){$this->_controllerDirectory = array();if (is_string($directory)) {$this->addControllerDirectory($directory, $module);} elseif (is_array($directory)) {foreach ((array) $directory as $module => $path) {$this->addControllerDirectory($path, $module);}} else {require_once "Zend/Controller/Exception.php";throw new Zend_Controller_Exception("Controller directory spec must be either a string or an array");}return $this;}public function getControllerDirectory($module = null){if (null === $module) {return $this->_controllerDirectory;}$module = (string) $module;if (array_key_exists($module, $this->_controllerDirectory)) {return $this->_controllerDirectory[$module];}return null;}public function removeControllerDirectory($module){$module = (string) $module;if (array_key_exists($module, $this->_controllerDirectory)) {unset($this->_controllerDirectory[$module]);return true;}return false;}public function formatModuleName($unformatted){if (($this->_defaultModule == $unformatted) && !$this->getParam("prefixDefaultModule")) {return $unformatted;}return ucfirst($this->_formatName($unformatted));}public function formatClassName($moduleName, $className){return $this->formatModuleName($moduleName) . "_" . $className;}public function classToFilename($class){return str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php";}public function isDispatchable(Zend_Controller_Request_Abstract $request){$className = $this->getControllerClass($request);if (!$className) {return false;}$finalClass = $className;if (($this->_defaultModule != $this->_curModule)|| $this->getParam("prefixDefaultModule")){$finalClass = $this->formatClassName($this->_curModule, $className);}if (class_exists($finalClass, false)) {return true;}$fileSpec= $this->classToFilename($className);$dispatchDir = $this->getDispatchDirectory();$test= $dispatchDir . DIRECTORY_SEPARATOR . $fileSpec;return Zend_Loader::isReadable($test);}public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response){$this->setResponse($response);/** * Get controller class */if (!$this->isDispatchable($request)) {$controller = $request->getControllerName();if (!$this->getParam("useDefaultControllerAlways") && !empty($controller)) {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Invalid controller specified (" . $request->getControllerName() . ")");}$className = $this->getDefaultControllerClass($request);} else {$className = $this->getControllerClass($request);if (!$className) {$className = $this->getDefaultControllerClass($request);}}/** * Load the controller class file */$className = $this->loadClass($className);/** * Instantiate controller with request, response, and invocation * arguments; throw exception if it"s not an action controller */$controller = new $className($request, $this->getResponse(), $this->getParams());if (!($controller instanceof Zend_Controller_Action_Interface) &&!($controller instanceof Zend_Controller_Action)) {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Controller "" . $className . "" is not an instance of Zend_Controller_Action_Interface");}/** * Retrieve the action name */$action = $this->getActionMethod($request);/** * Dispatch the method call */$request->setDispatched(true);// by default, buffer output$disableOb = $this->getParam("disableOutputBuffering");$obLevel= ob_get_level();if (empty($disableOb)) {ob_start();}try {$controller->dispatch($action);} catch (Exception $e) {// Clean output buffer on error$curObLevel = ob_get_level();if ($curObLevel > $obLevel) {do {ob_get_clean();$curObLevel = ob_get_level();} while ($curObLevel > $obLevel);}throw $e;}if (empty($disableOb)) {$content = ob_get_clean();$response->appendBody($content);}// Destroy the page controller instance and reflection objects$controller = null;}public function loadClass($className){$finalClass = $className;if (($this->_defaultModule != $this->_curModule)|| $this->getParam("prefixDefaultModule")){$finalClass = $this->formatClassName($this->_curModule, $className);}if (class_exists($finalClass, false)) {return $finalClass;}$dispatchDir = $this->getDispatchDirectory();$loadFile= $dispatchDir . DIRECTORY_SEPARATOR . $this->classToFilename($className);if (Zend_Loader::isReadable($loadFile)) {include_once $loadFile;} else {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Cannot load controller class "" . $className . "" from file "" . $loadFile . """);}if (!class_exists($finalClass, false)) {require_once "Zend/Controller/Dispatcher/Exception.php";throw new Zend_Controller_Dispatcher_Exception("Invalid controller class ("" . $finalClass . "")");}return $finalClass;}public function getControllerClass(Zend_Controller_Request_Abstract $request){$controllerName = $request->getControllerName();if (empty($controllerName)) {if (!$this->getParam("useDefaultControllerAlways")) {return false;}$controllerName = $this->getDefaultControllerName();$request->setControllerName($controllerName);}$className = $this->formatControllerName($controllerName);$controllerDirs = $this->getControllerDirectory();$module = $request->getModuleName();if ($this->isValidModule($module)) {$this->_curModule= $module;$this->_curDirectory = $controllerDirs[$module];} elseif ($this->isValidModule($this->_defaultModule)) {$request->setModuleName($this->_defaultModule);$this->_curModule= $this->_defaultModule;$this->_curDirectory = $controllerDirs[$this->_defaultModule];} else {require_once "Zend/Controller/Exception.php";throw new Zend_Controller_Exception("No default module defined for this application");}return $className;}public function isValidModule($module){if (!is_string($module)) {return false;}$module= strtolower($module);$controllerDir = $this->getControllerDirectory();foreach (array_keys($controllerDir) as $moduleName) {if ($module == strtolower($moduleName)) {return true;}}return false;}public function getDefaultControllerClass(Zend_Controller_Request_Abstract $request){$controller = $this->getDefaultControllerName();$default= $this->formatControllerName($controller);$request->setControllerName($controller)->setActionName(null);$module = $request->getModuleName();$controllerDirs = $this->getControllerDirectory();$this->_curModule= $this->_defaultModule;$this->_curDirectory = $controllerDirs[$this->_defaultModule];if ($this->isValidModule($module)) {$found = false;if (class_exists($default, false)) {$found = true;} else {$moduleDir = $controllerDirs[$module];$fileSpec = $moduleDir . DIRECTORY_SEPARATOR . $this->classToFilename($default);if (Zend_Loader::isReadable($fileSpec)) {$found = true;$this->_curDirectory = $moduleDir;}}if ($found) {$request->setModuleName($module);$this->_curModule= $this->formatModuleName($module);}} else {$request->setModuleName($this->_defaultModule);}return $default;}public function getDispatchDirectory(){return $this->_curDirectory;}public function getActionMethod(Zend_Controller_Request_Abstract $request){$action = $request->getActionName();if (empty($action)) {$action = $this->getDefaultAction();$request->setActionName($action);}return $this->formatActionName($action);}}
前端控制器和分发器
<?php/** Zend_Loader */require_once "Zend/Loader.php";/** Zend_Controller_Action_HelperBroker */require_once "Zend/Controller/Action/HelperBroker.php";/** Zend_Controller_Plugin_Broker */require_once "Zend/Controller/Plugin/Broker.php";class Zend_Controller_Front{protected $_baseUrl = null;protected $_controllerDir = null;protected $_dispatcher = null;protected static $_instance = null;protected $_invokeParams = array();protected $_moduleControllerDirectoryName = "controllers";protected $_plugins = null;protected $_request = null;protected $_response = null;protected $_returnResponse = false;protected $_router = null;protected $_throwExceptions = false;protected function __construct(){$this->_plugins = new Zend_Controller_Plugin_Broker();}private function __clone(){}public static function getInstance(){if (null === self::$_instance) {self::$_instance = new self();}return self::$_instance;}public function resetInstance(){$reflection = new ReflectionObject($this);foreach ($reflection->getProperties() as $property) {$name = $property->getName();switch ($name) {case "_instance":break;case "_controllerDir":case "_invokeParams":$this->{$name} = array();break;case "_plugins":$this->{$name} = new Zend_Controller_Plugin_Broker();break;case "_throwExceptions":case "_returnResponse":$this->{$name} = false;break;case "_moduleControllerDirectoryName":$this->{$name} = "controllers";break;default:$this->{$name} = null;break;}}Zend_Controller_Action_HelperBroker::resetHelpers();}public static function run($controllerDirectory){self::getInstance()->setControllerDirectory($controllerDirectory)->dispatch();}public function addControllerDirectory($directory, $module = null){$this->getDispatcher()->addControllerDirectory($directory, $module);return $this;}public function setControllerDirectory($directory, $module = null){$this->getDispatcher()->setControllerDirectory($directory, $module);return $this;}public function getControllerDirectory($name = null){return $this->getDispatcher()->getControllerDirectory($name);}public function removeControllerDirectory($module){return $this->getDispatcher()->removeControllerDirectory($module);}public function addModuleDirectory($path){try{$dir = new DirectoryIterator($path);} catch(Exception $e) {require_once "Zend/Controller/Exception.php";throw new Zend_Controller_Exception("Directory $path not readable", 0, $e);}foreach ($dir as $file) {if ($file->isDot() || !$file->isDir()) {continue;}$module= $file->getFilename();// Don"t use SCCS directories as modulesif (preg_match("/^[^a-z]/i", $module) || ("CVS" == $module)) {continue;}$moduleDir = $file->getPathname() . DIRECTORY_SEPARATOR . $this->getModuleControllerDirectoryName();$this->addControllerDirectory($moduleDir, $module);}return $this;}public function getModuleDirectory($module = null){if (null === $module) {$request = $this->getRequest();if (null !== $request) {$module = $this->getRequest()->getModuleName();}if (empty($module)) {$module = $this->getDispatcher()->getDefaultModule();}}$controllerDir = $this->getControllerDirectory($module);if ((null === $controllerDir) || !is_string($controllerDir)) {return null;}return dirname($controllerDir);}public function setModuleControllerDirectoryName($name = "controllers"){$this->_moduleControllerDirectoryName = (string) $name;return $this;}public function getModuleControllerDirectoryName(){return $this->_moduleControllerDirectoryName;}public function setDefaultControllerName($controller){$dispatcher = $this->getDispatcher();$dispatcher->setDefaultControllerName($controller);return $this;}public function getDefaultControllerName(){return $this->getDispatcher()->getDefaultControllerName();}public function setDefaultAction($action){$dispatcher = $this->getDispatcher();$dispatcher->setDefaultAction($action);return $this;}public function getDefaultAction(){return $this->getDispatcher()->getDefaultAction();}public function setDefaultModule($module){$dispatcher = $this->getDispatcher();$dispatcher->setDefaultModule($module);return $this;}public function getDefaultModule(){return $this->getDispatcher()->getDefaultModule();}public function setRequest($request){...........................return $this;}public function getRequest(){return $this->_request;}public function setRouter($router){....................return $this;}public function getRouter(){..................return $this->_router;}public function setBaseUrl($base = null){..............return $this;}public function getBaseUrl(){return $this->_baseUrl;}/** * Set the dispatcher object. The dispatcher is responsible for * taking a Zend_Controller_Dispatcher_Token object, instantiating the controller, and * call the action method of the controller. * * @param Zend_Controller_Dispatcher_Interface $dispatcher * @return Zend_Controller_Front */public function setDispatcher(Zend_Controller_Dispatcher_Interface $dispatcher){$this->_dispatcher = $dispatcher;return $this;}/** * Return the dispatcher object. * * @return Zend_Controller_Dispatcher_Interface */public function getDispatcher(){/** * Instantiate the default dispatcher if one was not set. */if (!$this->_dispatcher instanceof Zend_Controller_Dispatcher_Interface) {require_once "Zend/Controller/Dispatcher/Standard.php";$this->_dispatcher = new Zend_Controller_Dispatcher_Standard();}return $this->_dispatcher;}public function setResponse($response){..................return $this;}public function getResponse(){return $this->_response;}public function setParam($name, $value){$name = (string) $name;$this->_invokeParams[$name] = $value;return $this;}public function setParams(array $params){$this->_invokeParams = array_merge($this->_invokeParams, $params);return $this;}public function getParam($name){if(isset($this->_invokeParams[$name])) {return $this->_invokeParams[$name];}return null;}public function getParams(){return $this->_invokeParams;}public function clearParams($name = null){if (null === $name) {$this->_invokeParams = array();} elseif (is_string($name) && isset($this->_invokeParams[$name])) {unset($this->_invokeParams[$name]);} elseif (is_array($name)) {foreach ($name as $key) {if (is_string($key) && isset($this->_invokeParams[$key])) {unset($this->_invokeParams[$key]);}}}return $this;}public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null){$this->_plugins->registerPlugin($plugin, $stackIndex);return $this;}public function unregisterPlugin($plugin){$this->_plugins->unregisterPlugin($plugin);return $this;}public function hasPlugin($class){return $this->_plugins->hasPlugin($class);}public function getPlugin($class){return $this->_plugins->getPlugin($class);}public function getPlugins(){return $this->_plugins->getPlugins();}public function throwExceptions($flag = null){.....................return $this->_throwExceptions;}public function returnResponse($flag = null){................return $this->_returnResponse;}/** * Dispatch an HTTP request to a controller/action. * * @param Zend_Controller_Request_Abstract|null $request * @param Zend_Controller_Response_Abstract|null $response * @return void|Zend_Controller_Response_Abstract Returns response object if returnResponse() is true */public function dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null){if (!$this->getParam("noErrorHandler") && !$this->_plugins->hasPlugin("Zend_Controller_Plugin_ErrorHandler")) {// Register with stack index of 100require_once "Zend/Controller/Plugin/ErrorHandler.php";$this->_plugins->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(), 100);}if (!$this->getParam("noViewRenderer") && !Zend_Controller_Action_HelperBroker::hasHelper("viewRenderer")) {require_once "Zend/Controller/Action/Helper/ViewRenderer.php";Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-80, new Zend_Controller_Action_Helper_ViewRenderer());}/** * Instantiate default request object (HTTP version) if none provided */if (null !== $request) {$this->setRequest($request);} elseif ((null === $request) && (null === ($request = $this->getRequest()))) {require_once "Zend/Controller/Request/Http.php";$request = new Zend_Controller_Request_Http();$this->setRequest($request);}/** * Set base URL of request object, if available */if (is_callable(array($this->_request, "setBaseUrl"))) {if (null !== $this->_baseUrl) {$this->_request->setBaseUrl($this->_baseUrl);}}/** * Instantiate default response object (HTTP version) if none provided */if (null !== $response) {$this->setResponse($response);} elseif ((null === $this->_response) && (null === ($this->_response = $this->getResponse()))) {require_once "Zend/Controller/Response/Http.php";$response = new Zend_Controller_Response_Http();$this->setResponse($response);}/** * Register request and response objects with plugin broker */$this->_plugins ->setRequest($this->_request) ->setResponse($this->_response);/** * Initialize router */$router = $this->getRouter();$router->setParams($this->getParams());/** * Initialize dispatcher */$dispatcher = $this->getDispatcher();$dispatcher->setParams($this->getParams())->setResponse($this->_response);// Begin dispatchtry {/** * Route request to controller/action, if a router is provided *//*** Notify plugins of router startup*/$this->_plugins->routeStartup($this->_request);try {$router->route($this->_request);} catch (Exception $e) {if ($this->throwExceptions()) {throw $e;}$this->_response->setException($e);}/*** Notify plugins of router completion*/$this->_plugins->routeShutdown($this->_request);/** * Notify plugins of dispatch loop startup */$this->_plugins->dispatchLoopStartup($this->_request);/** * Attempt to dispatch the controller/action. If the $this->_request * indicates that it needs to be dispatched, move to the next * action in the request. */do {$this->_request->setDispatched(true);/** * Notify plugins of dispatch startup */$this->_plugins->preDispatch($this->_request);/** * Skip requested action if preDispatch() has reset it */if (!$this->_request->isDispatched()) {continue;}/** * Dispatch request */try {$dispatcher->dispatch($this->_request, $this->_response);} catch (Exception $e) {if ($this->throwExceptions()) {throw $e;}$this->_response->setException($e);}/** * Notify plugins of dispatch completion */$this->_plugins->postDispatch($this->_request);} while (!$this->_request->isDispatched());} catch (Exception $e) {if ($this->throwExceptions()) {throw $e;}$this->_response->setException($e);}/** * Notify plugins of dispatch loop completion */try {$this->_plugins->dispatchLoopShutdown();} catch (Exception $e) {if ($this->throwExceptions()) {throw $e;}$this->_response->setException($e);}if ($this->returnResponse()) {return $this->_response;}$this->_response->sendResponse();}}
以上对Zend_Controller_Front和Zend_Controller_Dispatcher做了简单的标记,通过分析代码不难看出,基本的运行机制。
分发发生在前端控制器中的一个循环(loop)中。分发之前,前端控制器通过路由请求,找到用户指定的模块、控制器、动作和可选参数。然后进入分发循环,分发请求。
分发器需要大量数据完成任务——它需要知道如何格式化控制器和动作的名称,到哪儿找到控制器类文件,模块名是否有效,以及基于其它可用信息判定请求是否能分发的API。
每次迭代(iteration)过程开始时,在请求对象中设置一个标志指示该动作已分发。如果在动作或者前/后分发(pre/postDispatch)插件重置了该标志,分发循环将继续下去并试图分发新的请求。通过改变请求中的控制器或者动作并重置已分发标志,开发人员可以定制执行一个请求链。
控制这种分发过程的动作控制器方法是_forward();在任意的pre/postDispatch()或者动作中调用该方法,并传入动作、控制器、模块、以及可选的附加参数,就可以进入新的动作。
自定义分发器
Zend_Controller_Dispatcher_Interface定义了下列所有分发器需要实现的方法。
不过大多数情况下,只需要简单地扩展抽象类Zend_Controller_Dispatcher_Abstract,其中已经定义好了上面的大部分方法。或者扩展Zend_Controller_Dispatcher_Standard类,基于标准分发器来修改功能。
需要子类化分发器的可能原因包括:期望在动作控制器中使用不同的类和方法命名模式,或者期望使用不同的分发方式,比如分发到控制器目录下的动作文件,而不是控制器类的动作方法。
更多关于zend相关内容感兴趣的读者可查看本站专题:《Zend FrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。