亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > 建站經驗 > 正文

詳解PHP的Yii框架中的Controller控制器

2024-08-30 19:06:49
字體:
來源:轉載
供稿:網友

控制器是 MVC 模式中的一部分, 是繼承yii/base/Controller類的對象,負責處理請求和生成響應。 具體來說,控制器從應用主體接管控制后會分析請求數據并傳送到模型, 傳送模型結果到視圖,最后生成輸出響應信息。

操作

控制器由 操作 組成,它是執行終端用戶請求的最基礎的單元,一個控制器可有一個或多個操作。

如下示例顯示包含兩個操作view and create 的控制器post:

  1. namespace app/controllers; 
  2.  
  3.   
  4.  
  5. use Yii; 
  6.  
  7. use app/models/Post; 
  8.  
  9. use yii/web/Controller; 
  10.  
  11. use yii/web/NotFoundHttpException; 
  12.  
  13.   
  14.  
  15. class PostController extends Controller 
  16.  
  17.  
  18.  public function actionView($id
  19.  
  20.  { 
  21.  
  22.   $model = Post::findOne($id); 
  23.  
  24.   if ($model === null) { 
  25.  
  26.    throw new NotFoundHttpException; 
  27.  
  28.   } 
  29.  
  30.   
  31.  
  32.   return $this->render('view', [ 
  33.  
  34.    'model' => $model
  35.  
  36.   ]); 
  37.  
  38.  } 
  39.  
  40.   
  41.  
  42.  public function actionCreate() 
  43.  
  44.  { 
  45.  
  46.   $model = new Post; 
  47.  
  48.   
  49.  
  50.   if ($model->load(Yii::$app->request->post()) && $model->save()) { 
  51.  
  52.    return $this->redirect(['view''id' => $model->id]); 
  53.  
  54.   } else { 
  55.  
  56.    return $this->render('create', [ 
  57. //Vevb.com 
  58.     'model' => $model
  59.  
  60.    ]); 
  61.  
  62.   } 
  63.  
  64.  } 
  65.  

在操作 view (定義為 actionView() 方法)中, 代碼首先根據請求模型ID加載 模型, 如果加載成功,會渲染名稱為view的視圖并顯示,否則會拋出一個異常。

在操作 create (定義為 actionCreate() 方法)中, 代碼相似. 先將請求數據填入模型, 然后保存模型,如果兩者都成功,會跳轉到ID為新創建的模型的view操作,否則顯示提供用戶輸入的create視圖。

路由

終端用戶通過所謂的路由尋找到操作,路由是包含以下部分的字符串:

模型ID: 僅存在于控制器屬于非應用的模塊;

控制器ID: 同應用(或同模塊如果為模塊下的控制器)下唯一標識控制器的字符串;

操作ID: 同控制器下唯一標識操作的字符串。

路由使用如下格式:

ControllerID/ActionID

如果屬于模塊下的控制器,使用如下格式:

ModuleID/ControllerID/ActionID

如果用戶的請求地址為 http://hostname/index.php?r=site/index, 會執行site 控制器的index 操作。

創建控制器

在yii/web/Application網頁應用中,控制器應繼承yii/web/Controller 或它的子類。 同理在yii/console/Application控制臺應用中,控制器繼承yii/console/Controller 或它的子類。 如下代碼定義一個 site 控制器:

  1. namespace app/controllers; 
  2.  
  3. use yii/web/Controller; 
  4.  
  5. class SiteController extends Controller 
  6.  
  7.  

控制器ID

通常情況下,控制器用來處理請求有關的資源類型,因此控制器ID通常為和資源有關的名詞。 例如使用article作為處理文章的控制器ID。

控制器ID應僅包含英文小寫字母、數字、下劃線、中橫杠和正斜杠, 例如 article 和 post-comment 是真是的控制器ID,article?, PostComment, admin/post不是控制器ID。

控制器Id可包含子目錄前綴,例如 admin/article 代表 yii/base/Application::controllerNamespace控制器命名空間下 admin子目錄中 article 控制器。 子目錄前綴可為英文大小寫字母、數字、下劃線、正斜杠,其中正斜杠用來區分多級子目錄(如panels/admin)。

控制器類命名

控制器ID遵循以下規則衍生控制器類名:

將用正斜杠區分的每個單詞第一個字母轉為大寫。注意如果控制器ID包含正斜杠,只將最后的正斜杠后的部分第一個字母轉為大寫;

去掉中橫杠,將正斜杠替換為反斜杠;

增加Controller后綴;

在前面增加yii/base/Application::controllerNamespace控制器命名空間.

下面為一些示例,假設yii/base/Application::controllerNamespace控制器命名空間為 app/controllers:

article 對應 app/controllers/ArticleController;

post-comment 對應 app/controllers/PostCommentController;

admin/post-comment 對應 app/controllers/admin/PostCommentController;

adminPanels/post-comment 對應 app/controllers/adminPanels/PostCommentController.

控制器類必須能被 自動加載,所以在上面的例子中, 控制器article 類應在 別名 為@app/controllers/ArticleController.php的文件中定義, 控制器admin/post2-comment應在@app/controllers/admin/Post2CommentController.php文件中。

補充: 最后一個示例 admin/post2-comment 表示你可以將控制器放在 yii/base/Application::controllerNamespace控制器命名空間下的子目錄中, 在你不想用 模塊 的情況下給控制器分類,這種方式很有用。

控制器部署

可通過配置 yii/base/Application::controllerMap 來強制上述的控制器ID和類名對應, 通常用在使用第三方不能掌控類名的控制器上。

配置 應用配置 中的application configuration,如下所示:

  1.  
  2.  'controllerMap' => [ 
  3.  
  4.   // 用類名申明 "account" 控制器 
  5.  
  6.   'account' => 'app/controllers/UserController'
  7.  
  8. //Vevb.com 
  9.   // 用配置數組申明 "article" 控制器 
  10.  
  11.   'article' => [ 
  12.  
  13.    'class' => 'app/controllers/PostController'
  14.  
  15.    'enableCsrfValidation' => false, 
  16.  
  17.   ], 
  18.  
  19.  ], 
  20.  

默認控制器

每個應用有一個由yii/base/Application::defaultRoute屬性指定的默認控制器; 當請求沒有指定 路由,該屬性值作為路由使用。 對于yii/web/Application網頁應用,它的值為 'site', 對于 yii/console/Application控制臺應用,它的值為 help, 所以URL為http://hostname/index.php 表示由 site 控制器來處理。

可以在 應用配置 中修改默認控制器,如下所示:

  1.  
  2.  'defaultRoute' => 'main'
  3.  

創建操作

創建操作可簡單地在控制器類中定義所謂的 操作方法 來完成,操作方法必須是以action開頭的公有方法。 操作方法的返回值會作為響應數據發送給終端用戶,如下代碼定義了兩個操作 index 和 hello-world:

  1. namespace app/controllers; 
  2.  
  3. use yii/web/Controller; 
  4.  
  5. class SiteController extends Controller 
  6.  
  7.  
  8.  public function actionIndex() 
  9.  
  10.  { 
  11.  
  12.   return $this->render('index'); 
  13.  
  14.  } 
  15.  
  16.   
  17. //Vevb.com 
  18.  public function actionHelloWorld() 
  19.  
  20.  { 
  21.  
  22.   return 'Hello World'
  23.  
  24.  } 
  25.  

操作ID

操作通常是用來執行資源的特定操作,因此,操作ID通常為動詞,如view, update等。

操作ID應僅包含英文小寫字母、數字、下劃線和中橫杠,操作ID中的中橫杠用來分隔單詞。 例如view, update2, comment-post是真實的操作ID,view?, Update不是操作ID.

可通過兩種方式創建操作ID,內聯操作和獨立操作. An inline action is 內聯操作在控制器類中定義為方法;獨立操作是繼承yii/base/Action或它的子類的類。 內聯操作容易創建,在無需重用的情況下優先使用; 獨立操作相反,主要用于多個控制器重用,或重構為擴展。

內聯操作

內聯操作指的是根據我們剛描述的操作方法。

操作方法的名字是根據操作ID遵循如下規則衍生:

將每個單詞的第一個字母轉為大寫;

去掉中橫杠;

增加action前綴.

例如index 轉成 actionIndex, hello-world 轉成 actionHelloWorld。

注意: 操作方法的名字大小寫敏感,如果方法名稱為ActionIndex不會認為是操作方法, 所以請求index操作會返回一個異常,也要注意操作方法必須是公有的,私有或者受保護的方法不能定義成內聯操作。

因為容易創建,內聯操作是最常用的操作,但是如果你計劃在不同地方重用相同的操作, 或者你想重新分配一個操作,需要考慮定義它為獨立操作。

獨立操作

獨立操作通過繼承yii/base/Action或它的子類來定義。 例如Yii發布的yii/web/ViewAction和yii/web/ErrorAction都是獨立操作。

要使用獨立操作,需要通過控制器中覆蓋yii/base/Controller::actions()方法在action map中申明,如下例所示:

  1. public function actions() 
  2.  
  3.  
  4.  return [ 
  5.  
  6.   // 用類來申明"error" 操作 
  7.  
  8.   'error' => 'yii/web/ErrorAction'
  9.  
  10.  //Vevb.com 
  11.  
  12.   // 用配置數組申明 "view" 操作 
  13.  
  14.   'view' => [ 
  15.  
  16.    'class' => 'yii/web/ViewAction'
  17.  
  18.    'viewPrefix' => ''
  19.  
  20.   ], 
  21.  
  22.  ]; 
  23.  

如上所示, actions() 方法返回鍵為操作ID、值為對應操作類名或數組configurations 的數組。 和內聯操作不同,獨立操作ID可包含任意字符,只要在actions() 方法中申明.

為創建一個獨立操作類,需要繼承yii/base/Action 或它的子類,并實現公有的名稱為run()的方法, run() 方法的角色和操作方法類似,例如:

  1. namespace app/components; 
  2.  
  3. use yii/base/Action; 
  4.  
  5. class HelloWorldAction extends Action 
  6.  
  7.  
  8.  public function run() 
  9.  
  10.  { 
  11.  
  12.   return "Hello World"
  13.  
  14.  } 
  15.  

操作結果

操作方法或獨立操作的run()方法的返回值非常重要,它表示對應操作結果。

返回值可為 響應 對象,作為響應發送給終端用戶。

對于yii/web/Application網頁應用,返回值可為任意數據, 它賦值給yii/web/Response::data, 最終轉換為字符串來展示響應內容。

對于yii/console/Application控制臺應用,返回值可為整數, 表示命令行下執行的 yii/console/Response::exitStatus 退出狀態。

在上面的例子中,操作結果都為字符串,作為響應數據發送給終端用戶,下例顯示一個操作通過 返回響應對象(因為yii/web/Controller::redirect()方法返回一個響應對象)可將用戶瀏覽器跳轉到新的URL。

public function actionForward()

  1.  
  2.  // 用戶瀏覽器跳轉到 http://example.com 
  3.  
  4.  return $this->redirect('http://example.com'); 
  5.  

操作參數

內聯操作的操作方法和獨立操作的 run() 方法可以帶參數,稱為操作參數。 參數值從請求中獲取,對于yii/web/Application網頁應用, 每個操作參數的值從$_GET中獲得,參數名作為鍵; 對于yii/console/Application控制臺應用, 操作參數對應命令行參數。

如下例,操作view (內聯操作) 申明了兩個參數 $id 和 $version。

  1. namespace app/controllers; 
  2.  
  3. use yii/web/Controller;  
  4.  
  5. class PostController extends Controller 
  6.  
  7.  
  8.   public function actionView($id$version = null) 
  9.  
  10.   { 
  11.  
  12.     // ... 
  13.  
  14.   } 
  15.  

操作參數會被不同的參數填入,如下所示:

http://hostname/index.php?r=post/view&id=123: $id 會填入'123',$version 仍為 null 空因為沒有version請求參數;

http://hostname/index.php?r=post/view&id=123&version=2: $id 和 $version 分別填入 '123' 和 '2'`;

http://hostname/index.php?r=post/view: 會拋出yii/web/BadRequestHttpException 異常 因為請求沒有提供參數給必須賦值參數$id;

http://hostname/index.php?r=post/view&id[]=123: 會拋出yii/web/BadRequestHttpException 異常 因為$id 參數收到數字值 ['123']而不是字符串.

如果想讓操作參數接收數組值,需要指定$id為array,如下所示:

  1. public function actionView(array $id$version = null) 
  2.  
  3.  
  4.  // ... 
  5.  

現在如果請求為 http://hostname/index.php?r=post/view&id[]=123, 參數 $id 會使用數組值['123'], 如果請求為http://hostname/index.php?r=post/view&id=123, 參數 $id 會獲取相同數組值,因為無類型的'123'會自動轉成數組。

上述例子主要描述網頁應用的操作參數,對于控制臺應用,更多詳情請參閱控制臺命令。

默認操作

每個控制器都有一個由 yii/base/Controller::defaultAction 屬性指定的默認操作, 當路由 只包含控制器ID,會使用所請求的控制器的默認操作。

默認操作默認為 index,如果想修改默認操作,只需簡單地在控制器類中覆蓋這個屬性,如下所示:

  1. namespace app/controllers; 
  2.  
  3. use yii/web/Controller;  
  4.  
  5. class SiteController extends Controller 
  6.  
  7.  
  8.  public $defaultAction = 'home'
  9.  
  10.  public function actionHome() 
  11.  
  12.  { 
  13.  
  14.   return $this->render('home'); 
  15.  
  16.  } 
  17.  

控制器動作參數綁定 

從版本 1.1.4 開始,Yii 提供了對自動動作參數綁定的支持。就是說,控制器動作可以定義命名的參數,參數的值將由 Yii 自動從 $_GET 填充。

為了詳細說明此功能,假設我們需要為 PostController 寫一個 create 動作。此動作需要兩個參數:

category:一個整數,代表帖子(post)要發表在的那個分類的ID。

language:一個字符串,代表帖子所使用的語言代碼。

從 $_GET 中提取參數時,我們可以不再下面這種無聊的代碼了:

  1. class PostController extends CController 
  2.  
  3.  { 
  4.  
  5.    public function actionCreate() 
  6.  
  7.    { 
  8.  
  9.      if(isset($_GET['category'])) 
  10.  
  11.       $category=(int)$_GET['category']; 
  12.  
  13.      else 
  14.  
  15.       throw new CHttpException(404,'invalid request'); 
  16.  
  17.      if(isset($_GET['language'])) 
  18.  
  19.       $language=$_GET['language']; 
  20.  
  21.      else 
  22.  
  23.       $language='en'
  24.  
  25.   
  26.  
  27.      // ... fun code starts here ... 
  28.  
  29.    } 
  30.  
  31.  } 

現在使用動作參數功能,我們可以更輕松的完成任務:

  1. class PostController extends CController 
  2.  
  3.  
  4.   public function actionCreate($category$language='en'
  5.  
  6.   { 
  7.  
  8.     $category = (int)$category
  9.  
  10.   
  11.  
  12.     echo 'Category:'.$category.'/Language:'.$language
  13.  
  14.   
  15.  
  16.     // ... fun code starts here ... 
  17.  
  18.   } 
  19.  

注意我們在動作方法 actionCreate 中添加了兩個參數。這些參數的名字必須和我們想要從 $_GET 中提取的名字一致。當用戶沒有在請求中指定 $language 參數時,這個參數會使用默認值 en 。由于 $category 沒有默認值,如果用戶沒有在 $_GET 中提供 category 參數,將會自動拋出一個 CHttpException (錯誤代碼 400) 異常。

從版本1.1.5開始,Yii已經支持數組的動作參數。使用方法如下:

  1. class PostController extends CController 
  2.  
  3.  
  4.   public function actionCreate(array $categories
  5.  
  6.   { 
  7.  
  8.     // Yii will make sure $categories be an array 
  9.  
  10.   } 
  11.  

控制器生命周期

處理一個請求時,應用主體 會根據請求路由創建一個控制器,控制器經過以下生命周期來完成請求:

在控制器創建和配置后,yii/base/Controller::init() 方法會被調用。

控制器根據請求操作ID創建一個操作對象:

如果操作ID沒有指定,會使用yii/base/Controller::defaultAction默認操作ID;

如果在yii/base/Controller::actions()找到操作ID,會創建一個獨立操作;

如果操作ID對應操作方法,會創建一個內聯操作;

否則會拋出yii/base/InvalidRouteException異常。

控制器按順序調用應用主體、模塊(如果控制器屬于模塊)、控制器的 beforeAction() 方法;

如果任意一個調用返回false,后面未調用的beforeAction()會跳過并且操作執行會被取消; action execution will be cancelled.

默認情況下每個 beforeAction() 方法會觸發一個 beforeAction 事件,在事件中你可以追加事件處理操作;

控制器執行操作:

請求數據解析和填入到操作參數;

控制器按順序調用控制器、模塊(如果控制器屬于模塊)、應用主體的 afterAction() 方法;

默認情況下每個 afterAction() 方法會觸發一個 afterAction 事件,在事件中你可以追加事件處理操作;

應用主體獲取操作結果并賦值給響應.

最佳實踐

在設計良好的應用中,控制器很精練,包含的操作代碼簡短; 如果你的控制器很復雜,通常意味著需要重構,轉移一些代碼到其他類中。

歸納起來,控制器:

可訪問請求 數據;

可根據請求數據調用 模型 的方法和其他服務組件;

可使用視圖構造響應;

不應處理應被模型處理的請求數據;

應避免嵌入HTML或其他展示代碼,這些代碼最好在 視圖中處理.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕国产日韩| 欧美在线观看一区二区三区| 亚洲人精品午夜在线观看| 国产日韩av在线播放| 性欧美在线看片a免费观看| 亚洲激情成人网| 亚洲精品国产欧美| 最近更新的2019中文字幕| 亚洲视频网站在线观看| 91沈先生在线观看| 久久伊人免费视频| 久久精品国产久精国产思思| 欧美激情videos| 欧美在线www| 国产网站欧美日韩免费精品在线观看| 久久天天躁夜夜躁狠狠躁2022| 欧美视频在线观看免费| 中文字幕综合在线| 亚洲小视频在线| 国色天香2019中文字幕在线观看| 日韩精品免费在线视频| 一区二区三区 在线观看视| 国产成人精品综合久久久| 欧美人在线视频| 国产精品九九久久久久久久| 久久国产精品久久久| 欧美最猛性xxxxx免费| 日韩中文字幕视频在线观看| 久久久久久国产三级电影| 亚洲精品中文字幕有码专区| 亚洲欧美在线一区二区| 国产va免费精品高清在线| 粗暴蹂躏中文一区二区三区| 欧美视频免费在线| 91精品国产精品| 国产在线观看91精品一区| 国产一区二区三区网站| 亚洲美女视频网| 中文字幕亚洲欧美一区二区三区| 91精品国产91久久久久福利| 在线一区二区日韩| 欧美精品videos性欧美| 久久久久久久久久久网站| 亚洲精品少妇网址| 在线精品国产成人综合| 成人h猎奇视频网站| 成人有码在线视频| 国产亚洲视频中文字幕视频| 亚洲综合视频1区| 亚洲精品电影网站| 亚洲国产一区自拍| 亚洲国产精品福利| 中文字幕无线精品亚洲乱码一区| 欧美日韩亚洲一区二| 国产不卡av在线免费观看| 国产精品久久久久久五月尺| 精品国产乱码久久久久酒店| 欧美性生交xxxxxdddd| 久久99久久久久久久噜噜| 久久久99免费视频| 欧美视频国产精品| 91高清视频免费观看| 国产精品久久久久久久久久新婚| 91在线免费视频| 国产精品精品视频一区二区三区| 亚洲精品www久久久久久广东| 欧美日韩精品在线播放| 日韩电影免费在线观看| 国产精品6699| 国产精品美腿一区在线看| 欧美精品在线免费播放| 欧美成人sm免费视频| 久久精品久久久久| 精品国产成人在线| 国产91在线播放九色快色| 久久高清视频免费| 91夜夜未满十八勿入爽爽影院| 国产v综合v亚洲欧美久久| 亚洲国产精品一区二区久| 性欧美视频videos6一9| 欧美国产日韩在线| 7777精品久久久久久| 中文字幕成人精品久久不卡| 国产丝袜一区二区三区| 久久久久久久久久国产精品| 国产在线观看91精品一区| 国产精品稀缺呦系列在线| 国产视频久久网| 国产欧美久久久久久| 亚洲图片制服诱惑| 国产精品白嫩美女在线观看| 欧洲一区二区视频| 亚洲国产又黄又爽女人高潮的| 韩国v欧美v日本v亚洲| 91国产精品电影| 91国内免费在线视频| 色悠久久久久综合先锋影音下载| 日韩亚洲成人av在线| 亚洲精品aⅴ中文字幕乱码| 97碰碰碰免费色视频| 国产主播喷水一区二区| 欧美性高跟鞋xxxxhd| 欧美日韩aaaa| 91免费看视频.| 在线国产精品播放| 亚洲人成伊人成综合网久久久| 欧美风情在线观看| 国产成人综合亚洲| 国产精品99一区| 亚洲美女激情视频| 欧美日韩在线影院| 亚洲精品视频免费在线观看| 亚洲一区二区中文| 欧美性视频精品| 国产欧美一区二区| 亚洲人成网站777色婷婷| 欧美xxxx做受欧美.88| 成人午夜在线视频一区| 亚洲免费伊人电影在线观看av| 国产精品一区二区在线| 久久天天躁狠狠躁夜夜躁| 国产在线精品成人一区二区三区| 91精品视频在线免费观看| 啪一啪鲁一鲁2019在线视频| 国产精品电影久久久久电影网| 欧美疯狂性受xxxxx另类| 国产成人在线亚洲欧美| 国产精品久久国产精品99gif| 久久大大胆人体| 在线日韩第一页| 国产精品美女无圣光视频| 国产亚洲欧美aaaa| 欧美日韩视频免费播放| 国产成人久久久精品一区| 中文字幕免费精品一区高清| 亚洲精品视频久久| 黑人与娇小精品av专区| 欧美精品久久久久久久| 国产日韩欧美中文| 国产精品第100页| 日韩成人黄色av| 久久亚洲精品中文字幕冲田杏梨| 亚洲欧美日韩中文视频| 欧美亚洲视频在线看网址| 中文字幕久热精品视频在线| 欧美激情亚洲一区| 97人洗澡人人免费公开视频碰碰碰| 中文字幕欧美专区| 精品国产美女在线| 日韩va亚洲va欧洲va国产| 亚洲bt天天射| 欧美日韩国产丝袜美女| 亚洲国产日韩欧美在线图片| 欧美在线观看www| 日韩成人中文电影| 亚洲精品乱码久久久久久金桔影视| 国产丝袜一区二区| 亚洲精品免费一区二区三区| 精品福利在线看| 久久精品国产亚洲一区二区| 91精品在线影院| 日本老师69xxx| 久久久999国产精品| 国产精品亚洲аv天堂网|