一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - Zend Framework教程之動作的基類Zend_Controller_Action詳解

Zend Framework教程之動作的基類Zend_Controller_Action詳解

2020-12-28 13:18coder PHP教程

這篇文章主要介紹了Zend Framework教程之動作的基類Zend_Controller_Action的用法,結合實例形式詳細分析了動作的基類Zend_Controller_Action具體功能,使用方法與相關注意事項,需要的朋友可以參考下

本文實例講述了Zend Framework教程之動作的基類Zend_Controller_Action。分享給大家供大家參考,具體如下:

Zend_Controller_Action的實現

Zend Framework的動作控制器需要繼承Zend_Controller_Action,Zend_Controller_Action提供了動作控制器的基本功能,具體參考如下代碼:

Zend_Controller_Action_Interface

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
interface Zend_Controller_Action_Interface
{
  /**
   * Class constructor
   *
   * The request and response objects should be registered with the
   * controller, as should be any additional optional arguments; these will be
   * available via {@link getRequest()}, {@link getResponse()}, and
   * {@link getInvokeArgs()}, respectively.
   *
   * When overriding the constructor, please consider this usage as a best
   * practice and ensure that each is registered appropriately; the easiest
   * way to do so is to simply call parent::__construct($request, $response,
   * $invokeArgs).
   *
   * After the request, response, and invokeArgs are set, the
   * {@link $_helper helper broker} is initialized.
   *
   * Finally, {@link init()} is called as the final action of
   * instantiation, and may be safely overridden to perform initialization
   * tasks; as a general rule, override {@link init()} instead of the
   * constructor to customize an action controller's instantiation.
   *
   * @param Zend_Controller_Request_Abstract $request
   * @param Zend_Controller_Response_Abstract $response
   * @param array $invokeArgs Any additional invocation arguments
   * @return void
   */
  public function __construct(Zend_Controller_Request_Abstract $request,
                Zend_Controller_Response_Abstract $response,
                array $invokeArgs = array());
  /**
   * Dispatch the requested action
   *
   * @param string $action Method name of action
   * @return void
   */
  public function dispatch($action);
}

Zend_Controller_Action

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
<?php
require_once 'Zend/Controller/Action/HelperBroker.php';
require_once 'Zend/Controller/Action/Interface.php';
require_once 'Zend/Controller/Front.php';
abstract class Zend_Controller_Action implements Zend_Controller_Action_Interface
{
  protected $_classMethods;
  protected $_delimiters;
  protected $_invokeArgs = array();
  protected $_frontController;
  protected $_request = null;
  protected $_response = null;
  public $viewSuffix = 'phtml';
  public $view;
  protected $_helper = null;
  public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
  {
    $this->setRequest($request)
       ->setResponse($response)
       ->_setInvokeArgs($invokeArgs);
    $this->_helper = new Zend_Controller_Action_HelperBroker($this);
    $this->init();
  }
  public function init()
  {
  }
  public function initView()
  {
    if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
      return $this->view;
    }
    require_once 'Zend/View/Interface.php';
    if (isset($this->view) && ($this->view instanceof Zend_View_Interface)) {
      return $this->view;
    }
    $request = $this->getRequest();
    $module = $request->getModuleName();
    $dirs  = $this->getFrontController()->getControllerDirectory();
    if (empty($module) || !isset($dirs[$module])) {
      $module = $this->getFrontController()->getDispatcher()->getDefaultModule();
    }
    $baseDir = dirname($dirs[$module]) . DIRECTORY_SEPARATOR . 'views';
    if (!file_exists($baseDir) || !is_dir($baseDir)) {
      require_once 'Zend/Controller/Exception.php';
      throw new Zend_Controller_Exception('Missing base view directory ("' . $baseDir . '")');
    }
    require_once 'Zend/View.php';
    $this->view = new Zend_View(array('basePath' => $baseDir));
    return $this->view;
  }
  public function render($action = null, $name = null, $noController = false)
  {
    if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
      return $this->_helper->viewRenderer->render($action, $name, $noController);
    }
    $view  = $this->initView();
    $script = $this->getViewScript($action, $noController);
    $this->getResponse()->appendBody(
      $view->render($script),
      $name
    );
  }
  public function renderScript($script, $name = null)
  {
    if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
      return $this->_helper->viewRenderer->renderScript($script, $name);
    }
    $view = $this->initView();
    $this->getResponse()->appendBody(
      $view->render($script),
      $name
    );
  }
  public function getViewScript($action = null, $noController = null)
  {
    if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
      $viewRenderer = $this->_helper->getHelper('viewRenderer');
      if (null !== $noController) {
        $viewRenderer->setNoController($noController);
      }
      return $viewRenderer->getViewScript($action);
    }
    $request = $this->getRequest();
    if (null === $action) {
      $action = $request->getActionName();
    } elseif (!is_string($action)) {
      require_once 'Zend/Controller/Exception.php';
      throw new Zend_Controller_Exception('Invalid action specifier for view render');
    }
    if (null === $this->_delimiters) {
      $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
      $wordDelimiters = $dispatcher->getWordDelimiter();
      $pathDelimiters = $dispatcher->getPathDelimiter();
      $this->_delimiters = array_unique(array_merge($wordDelimiters, (array) $pathDelimiters));
    }
    $action = str_replace($this->_delimiters, '-', $action);
    $script = $action . '.' . $this->viewSuffix;
    if (!$noController) {
      $controller = $request->getControllerName();
      $controller = str_replace($this->_delimiters, '-', $controller);
      $script = $controller . DIRECTORY_SEPARATOR . $script;
    }
    return $script;
  }
  public function getRequest()
  {
    return $this->_request;
  }
  public function setRequest(Zend_Controller_Request_Abstract $request)
  {
    $this->_request = $request;
    return $this;
  }
  public function getResponse()
  {
    return $this->_response;
  }
  public function setResponse(Zend_Controller_Response_Abstract $response)
  {
    $this->_response = $response;
    return $this;
  }
  protected function _setInvokeArgs(array $args = array())
  {
    $this->_invokeArgs = $args;
    return $this;
  }
  public function getInvokeArgs()
  {
    return $this->_invokeArgs;
  }
  public function getInvokeArg($key)
  {
    if (isset($this->_invokeArgs[$key])) {
      return $this->_invokeArgs[$key];
    }
    return null;
  }
  public function getHelper($helperName)
  {
    return $this->_helper->{$helperName};
  }
  public function getHelperCopy($helperName)
  {
    return clone $this->_helper->{$helperName};
  }
  public function setFrontController(Zend_Controller_Front $front)
  {
    $this->_frontController = $front;
    return $this;
  }
  public function getFrontController()
  {
    // Used cache version if found
    if (null !== $this->_frontController) {
      return $this->_frontController;
    }
    // Grab singleton instance, if class has been loaded
    if (class_exists('Zend_Controller_Front')) {
      $this->_frontController = Zend_Controller_Front::getInstance();
      return $this->_frontController;
    }
    // Throw exception in all other cases
    require_once 'Zend/Controller/Exception.php';
    throw new Zend_Controller_Exception('Front controller class has not been loaded');
  }
  public function preDispatch()
  {
  }
  public function postDispatch()
  {
  }
  public function __call($methodName, $args)
  {
    require_once 'Zend/Controller/Action/Exception.php';
    if ('Action' == substr($methodName, -6)) {
      $action = substr($methodName, 0, strlen($methodName) - 6);
      throw new Zend_Controller_Action_Exception(sprintf('Action "%s" does not exist and was not trapped in __call()', $action), 404);
    }
    throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500);
  }
  public function dispatch($action)
  {
    // Notify helpers of action preDispatch state
    $this->_helper->notifyPreDispatch();
    $this->preDispatch();
    if ($this->getRequest()->isDispatched()) {
      if (null === $this->_classMethods) {
        $this->_classMethods = get_class_methods($this);
      }
      // If pre-dispatch hooks introduced a redirect then stop dispatch
      // @see ZF-7496
      if (!($this->getResponse()->isRedirect())) {
        // preDispatch() didn't change the action, so we can continue
        if ($this->getInvokeArg('useCaseSensitiveActions') || in_array($action, $this->_classMethods)) {
          if ($this->getInvokeArg('useCaseSensitiveActions')) {
            trigger_error('Using case sensitive actions without word separators is deprecated; please do not rely on this "feature"');
          }
          $this->$action();
        } else {
          $this->__call($action, array());
        }
      }
      $this->postDispatch();
    }
    // whats actually important here is that this action controller is
    // shutting down, regardless of dispatching; notify the helpers of this
    // state
    $this->_helper->notifyPostDispatch();
  }
  public function run(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null)
  {
    if (null !== $request) {
      $this->setRequest($request);
    } else {
      $request = $this->getRequest();
    }
    if (null !== $response) {
      $this->setResponse($response);
    }
    $action = $request->getActionName();
    if (empty($action)) {
      $action = 'index';
    }
    $action = $action . 'Action';
    $request->setDispatched(true);
    $this->dispatch($action);
    return $this->getResponse();
  }
  protected function _getParam($paramName, $default = null)
  {
    $value = $this->getRequest()->getParam($paramName);
     if ((null === $value || '' === $value) && (null !== $default)) {
      $value = $default;
    }
    return $value;
  }
  protected function _setParam($paramName, $value)
  {
    $this->getRequest()->setParam($paramName, $value);
    return $this;
  }
  protected function _hasParam($paramName)
  {
    return null !== $this->getRequest()->getParam($paramName);
  }
  protected function _getAllParams()
  {
    return $this->getRequest()->getParams();
  }
  final protected function _forward($action, $controller = null, $module = null, array $params = null)
  {
    $request = $this->getRequest();
    if (null !== $params) {
      $request->setParams($params);
    }
    if (null !== $controller) {
      $request->setControllerName($controller);
      // Module should only be reset if controller has been specified
      if (null !== $module) {
        $request->setModuleName($module);
      }
    }
    $request->setActionName($action)
        ->setDispatched(false);
  }
  protected function _redirect($url, array $options = array())
  {
    $this->_helper->redirector->gotoUrl($url, $options);
  }
}

Zend_Controller_Action提供了動作和視圖的render功能,以及注冊請求和響應對象,常用助手等等。

動作控制器的常用方法

在動作控制器中常用的方法和屬性如下:

$this->_helper主要完成助手的相關操作例如:

?
1
2
3
4
5
6
// 只是局部控制器;當初始化加載時,對這個控制器的所有動作有效:
$this->_helper->viewRenderer->setNoRender(true);
// 全局:
$this->_helper->removeHelper('viewRenderer');
 // 也是全局,但需要和本地版本協作,以便繁殖這個控制器:
Zend_Controller_Front::getInstance()->setParam('noViewRenderer', true);

通過設置ViewRenderer的noRender標記,可以簡單地為一個獨立的視圖禁止解析(rendering):

?
1
2
3
4
5
6
7
8
class FooController extends Zend_Controller_Action
{
  public function barAction()
  {
    // disable autorendering for this action only:
    $this->_helper->viewRenderer->setNoRender();
  }
}

禁止ViewRenderer的主要原因是如果你不需要視圖對象或者如果你不通過視圖腳本(例如,當使用動作控制器來司服網站服務協議如SOAP,XML-RPC或REST)來解析。大多數情況下,你不需要全局地禁止ViewRenderer,只選擇性地在個別控制器或動作里禁止它。

請求對象和響應對象的相關操作

無數的對象和變量與對象一起注冊,并且每個都有訪問器方法。

請求對象:getRequest()可用來讀取調用動作請求對象。

響應對象: getResponse()可用來讀取收集最終響應的響應對象。一些典型的調用看起來象這樣:

?
1
2
$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);

調用參數:前端控制器可能把參數傳給路由器、派遣器和動作控制器。為了讀取這些參數,可使用getInvokeArg($key);另外,用getInvokeArgs()讀取整個參數列表。

請求參數:請求對象手機請求參數,如任何_GET 或 _POST 參數,或者指定在URL的路徑信息里的用戶參數。為了讀取這些參數,可使用_getParam($key)或_getAllParams()。也可以用_setParam()來設置請求參數;當轉發到另外的動作時這很有用。

用_hasParam($key)來測試是否一個參數存在(對邏輯分支有用)。

Note: _getParam()可帶有一個可選的第二個參數,如果它不是空的,就包含一個缺省的值。用它在讀取值之前來消除對_hasParam() 的調用:

?
1
2
3
4
5
6
7
8
// Use default value of 1 if id is not set
$id = $this->_getParam('id', 1);
// Instead of:
if ($this->_hasParam('id') {
  $id = $this->_getParam('id');
} else {
  $id = 1;
}

視圖的相關操作

Zend_Controller_Action為視圖繼承提供了一個初步的靈活的機制。有兩個方法來完成這個:initView() 和 render();前者松散地加載$view public 屬性,后者基于當前請求的動作來解析視圖,它們使用目錄層次來決定腳本路徑。

視圖初始化

initView()初始化視圖對象。為了讀取視圖對象,render()調用initView(),但它可以在任何時候被初始化;缺省地,它用Zend_View對象來組裝$view屬性,但任何實現Zend_View_Interface的類可以使用。如果$view已經被初始化,它就簡單地返回屬性。

缺省的實現使用下面假設的目錄結構:

applicationOrModule/
    controllers/
        IndexController.php
    views/
        scripts/
            index/
                index.phtml
        helpers/
        filters/

換句話說,視圖腳本假定放在views/scripts/子目錄,同時假定 views子目錄還包含兄弟功能(助手和過濾器)。確定視圖腳本名稱和路徑時,先以 views/scripts/作為基路徑,然后加上以視圖腳本對應控制器命名的目錄。

解析(Rendering)視圖

render() 有下列特征:has the following signature:

?
1
2
3
string render(string $action = null,
       string $name = null,
       bool $noController = false);

render()解析視圖腳本。如果沒有傳遞參數,它假定請求的腳本是[controller]/[action].phtml (.phtml是$viewSuffix屬性的值)。為$action傳遞一個值將解析在[controller]子目錄中的模板。為用[controller]重寫,傳遞一個true值給$noController。最后,模板被解析到響應對象;如果你希望解析到一個在響應對象里指定的named segment,傳遞一個值給$name。

Note: 因為控制器和動作名字里可能包含分隔符如'_'、 '.' 和 '-',當決定視圖名字時,render()把它們規格化成 '-'.在內部,它使用派遣器的字和路徑分隔符來做規格化。這樣,對/foo.bar/baz-bat的請求將解析腳本foo-bar/baz-bat.phtml。如果動作方法包含camelCasing,記住當決定視圖腳本文件名的時候,這將變成由'-'分隔的字。

一些例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyController extends Zend_Controller_Action
{
  public function fooAction()
  {
    // Renders my/foo.phtml
    $this->render();
    // Renders my/bar.phtml
    $this->render('bar');
    // Renders baz.phtml
    $this->render('baz', null, true);
    // Renders my/login.phtml to the 'form' segment of the
    // response object
    $this->render('login', 'form');
    // Renders site.phtml to the 'page' segment of the response
    // object; does not use the 'my/' subirectory
    $this->render('site', 'page', true);
  }
  public function bazBatAction()
  {
    // Renders my/baz-bat.phtml
    $this->render();
  }
}

其它

_forward($action, $controller = null, $module = null, array $params = null) :執行另外一個動作。如果在preDispatch()里調用,當前請求的動作將被跳過來支持新的動作。否則,在當前動作被處理之后,在_forward()請求的動作將被執行。

_redirect($url, array $options = array()):重定向到另外一個地方。這個方法用URL和一組可選的選項。缺省地,它執行HTTP 302 重定向。

選項可包括一個或多個下面這些:

exit:是否立即退出。如果被請求,它將干凈地關閉任何打開的會話和執行重定向。

可以用setRedirectExit()訪問器在控制器里全局地設置這個選項。

prependBase:是否預先考慮基礎URL和URL提供的請求對象一起注冊。

使用setRedirectPrependBase()訪問器,在控制器里全局地設置這個選項。

code:在重定向時要用什么HTTP代碼。缺省使用302;可以用從301到306之間的任何代碼。

使用setRedirectCode()訪問器,在控制器里全局地設置這個選項。

擴展自定義Zend_Controller_Action

為了創建動作控制器,設計上,Zend_Controller_Action 必須被繼承。至少,需要定義控制器可能調用的動作方法。

除了為web應用程序創建有用的函數外,你可能發現在不同的控制器里重復同樣的設置和實用方法;如果這樣,創建一個繼承(extends)Zend_Controller_Action 的基礎類可能會解決問題。

Example #1 如何處理不存在的動作

如果控制器的請求包括一個未定義的動作方法,Zend_Controller_Action::__call()將被調用。__call()當然是PHP中用來重載方法的魔術方法。

缺省地,這個方法拋出一個Zend_Controller_Action_Exception 來表明在控制器里沒有發現要求的方法。如果要求的方法以'Action'結尾,就假設一個動作被請求并且不存在;這樣的錯誤導致帶有代碼為 404 的異常。所有其它方法導致帶有代碼為 500 的異常。這使你很容易地在錯誤句柄里區分是頁面沒有發現還是程序錯誤。

如果想執行其它操作,你應該重寫這個函數。例如,如果你想顯示錯誤信息,可以象下面這樣來寫:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyController extends Zend_Controller_Action
{
  public function __call($method, $args)
  {
    if ('Action' == substr($method, -6)) {
      // If the action method was not found, render the error
      // template
      return $this->render('error');
    }
    // all other methods throw an exception
    throw new Exception('Invalid method "'
              . $method
              . '" called',
              500);
  }
}

另外的可能性就是你可能想轉發到缺省控制頁面:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyController extends Zend_Controller_Action
{
  public function indexAction()
  {
    $this->render();
  }
  public function __call($method, $args)
  {
    if ('Action' == substr($method, -6)) {
      // If the action method was not found, forward to the
      // index action
      return $this->_forward('index');
    }
    // all other methods throw an exception
    throw new Exception('Invalid method "'
              . $method
              . '" called',
              500);
  }
}

為了定制控制器,除了重寫__call()以外,本章前面說涉及的初始化、實用程序、訪問器、視圖和派遣鉤子等方法都可以被重寫。作為例子,如果把視圖對象保存到注冊表里,你可能想用象下面的代碼來修改initView():

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class My_Base_Controller extends Zend_Controller_Action
{
  public function initView()
  {
    if (null === $this->view) {
      if (Zend_Registry::isRegistered('view')) {
        $this->view = Zend_Registry::get('view');
      } else {
        $this->view = new Zend_View();
        $this->view->setBasePath(dirname(__FILE__) . '/../views');
      }
    }
    return $this->view;
  }
}

希望本文所述對大家PHP程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久热这里只有精品99国产6 | 操到翻白眼 | 亚洲精品私拍国产福利在线 | 久青草国产在视频在线观看 | 法国女佣系列在线播放 | 91久久夜色精品国产九色 | 91桃花视频 | 婷婷色网 | 久久久影院亚洲精品 | 草草视频免费看 | 国产成人精品免费2021 | 国产一级一级片 | 91天堂素人 | 日韩视频在线观看中字 | 成人丁香乱小说 | naruto堂同人本子汉化gg | 日韩精品亚洲一级在线观看 | 免费369看片入口 | 99re7在线精品免费视频 | 大乳女子一级毛片 | 男人插曲女人身体 | 欧美日韩一区二区三区免费 | 性欧美高清强烈性视频 | 色老板视频在线观看 | 99热成人精品热久久669 | 亚洲精品国产在线 | 青青成人福利国产在线视频 | 图片专区小说专区卡通动漫 | 国产午夜亚洲精品理论片不卡 | 日本一区免费观看 | 99自拍网| 天天摸天天操天天爽 | 四虎新网站| 久久成人国产精品一区二区 | 丝袜足控免费网站xx动漫漫画 | 日韩精品一区二区三区中文字幕 | 国产剧情一区二区三区 | 男人懂得网站 | 国产精品香蕉夜间视频免费播放 | a男人天堂 | 欧美精品成人a多人在线观看 |