yii 框架的詳情

Yii2的應用結構:
這裏寫圖片描述

目錄篇:

        
 advance版本的特點是:根目錄下預先分配了三個模塊,分別是前臺、後臺、控制檯模塊。
1.backend
它主要用於管理後臺,網站管理員來管理整個系統。

assets 目錄用於存放前端資源包PHP類。 這裏不需要了解什麼是前端資源包,只要大致知道是用於管理CSS、js等前端資源就可以了。
config 用於存放本應用的配置文件,包含主配置文件 main.php 和全局參數配置文件 params.php 。
models views controllers 3個目錄分別用於存放數據模型類、視圖文件、控制器類。這個是我們編碼的核心,也是我們工作最多的目錄。
widgets 目錄用於存放一些常用的小掛件的類文件。
tests 目錄用於存放測試類。
web 目錄從名字可以看出,這是一個對於Web服務器可以訪問的目錄。 除了這一目錄,其他所有的目錄不應對Web用戶暴露出來。這是安全的需要。
runtime 這個目錄是要求權限爲 chmod 777 ,即允許Web服務器具有完全的權限, 因爲可能會涉及到寫入臨時文件等。 但是一個目錄並未對Web用戶可見。也就是說,權限給了,但是並不是Web用戶可以訪問到的。

    
2.frontend

我們的目標最終用戶提供的主要接口的前端應用。其實,前臺和後臺是一樣的,只是我們邏輯上的一個劃分.。
 好了,現在問題來了。對於 frontend backend console 等獨立的應用而言, 他們的內容放在各自的目錄下面,他們的運作必然用到Yii框架等 vendor 中的程序。 他們是如何關聯起來的?這個祕密,或者說整個Yii應用的目錄結構的祕密, 就包含在一個傳說中的稱爲入口文件的地方。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?phpdefined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php'));
$application = new yii\web\Application($config);$application->run();


3.console
控制檯應用程序包含系統所需要的控制檯命令的。
 



下面是全局公共文件夾
4.common

其中:

  • config 就是通用的配置,這些配置將作用於前後臺和命令行。
  • mail 就是應用的前後臺和命令行的與郵件相關的佈局文件等。
  • models 就是前後臺和命令行都可能用到的數據模型。 這也是 common 中最主要的部分。

 公共的目錄(Common)中包含的文件用於其它應用程序之間共享。例如,每一個應用程序可能需要訪問該數據庫的使用 ActiveRecord。因此,我們可以將AR模型類放置在公共(common)的目錄下。同樣,如果在多個應用程序中使用了一些輔助(helper )或部件類(widget ),我們也應該把這些放置在公共目錄(common)下,以避免重複的代碼。
  正如我們將很快解釋,應用程序也可以共享一部分的共用配置。因此,我們還可以存儲config目錄下共同的常見配置。
當開發一個大型項目開發週期長,我們需要不斷調整數據庫結構。出於這個原因,我們還可以使用數據庫遷移(DB migrations )功能來保持跟蹤數據庫的變化。我們將所有 DB migrations(數據庫遷移)目錄同樣都放在公共(common)目錄下面。

5.environment
每個Yii環境就是一組配置文件, 包含了入口腳本 index.php和各類配置文件。 其實他們都放在/environments 目錄下面.

 從上面的目錄結構圖中,可以看到,環境目錄下有3個東東:
  • 目錄 dev
  • 目錄 prod
  • 文件 index.php

其中, dev 和 prod 結構相同,分別又包含了4個目錄和1個文件:

  • frontend 目錄,用於前臺的應用,包含了存放配置文件的 config 目錄和存放web入口腳本的web 目錄
  • backend 目錄,用於後臺應用,內容與 frontend 相同
  • console 目錄,用於命令行應用,僅包含了 config 目錄,因爲命令行應用不需要web入口腳本, 因此沒有 web 目錄。
  • common 目錄,用於各web應用和命令行應用通用的環境配置,僅包含了 config 目錄, 因爲不同應用不可能共用相同的入口腳本。 注意這個 common 的層級低於環境的層級,也就是說,他的通用,僅是某一環境下通用,並非所有環境下通用。
  • yii 文件,是命令行應用的入口腳本文件。

對於分散於各處的 web 和 config 目錄而言,它們也是有共性的。

  • 凡是 web 目錄,存放的都是web應用的入口腳本,一個 index.php 和一個測試版本的index-test.php
  • 凡是 config 目錄,存放的,都是本地配置信息 main-local.php 和 params-local.php

6.vendor
 
 vendor 。 這個目錄從字面的意思看,就是各種第三方的程序。 這是Composer安裝的其他程序的存放目錄,包含Yii框架本身,也放在這個目錄下面。 如果你向composer.json 目錄增加了新的需要安裝的程序,那麼下次調用Composer的時候, 就會把新安裝的目錄也安裝在這個 vendor 下面。

下面也是一些不太常用的文件夾
7.vagrant
 
8.tests
 

入口文件篇:

1、入口文件路徑:

http://127.0.0.1/yii2/advanced/frontend/web/index.php

每個應用都有一個入口腳本 web/index.PHP,這是整個應用中唯一可以訪問的 PHP 腳本。一個應用處理請求的過程如下:

1.用戶向入口腳本 web/index.php 發起請求。
2.入口腳本加載應用配置並創建一個應用實例去處理請求。
3.應用通過請求組件解析請求的路由。
4.應用創建一個控制器實例去處理請求。
5.控制器創建一個操作實例並針對操作執行過濾器。
6.如果任何一個過濾器返回失敗,則操作退出。
7.如果所有過濾器都通過,操作將被執行。
8.操作會加載一個數據模型,或許是來自數據庫
9.操作會渲染一個視圖,把數據模型提供給它。
10.渲染結果返回給響應組件。
11.響應組件發送渲染結果給用戶瀏覽器

可以看到中間有模型-視圖-控制器 ,即常說的MVC。入口腳本並不會處理請求,而是把請求交給了應用主體,在處理請求時,會用到控制器,如果用到數據庫中的東西,就會去訪問模型,如果處理請求完成,要返回給用戶信息,則會在視圖中回饋要返回給用戶的內容。

2、爲什麼我們訪問方法會出現url加密呢?


我們找到文件:vendor/yiisoft/yii2/web/UrlManager.php

    return "$baseUrl/{$route}{$anchor}";
} else {
    $url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
    if (!empty($params) && ($query = http_build_query($params)) !== '') {
        $url .= '&' . $query;
    }
將urlencode去掉就可以了
3、入口文件內容
 
入口文件流程如下:


MVC篇:


一、控制器詳解:

1、修改默認控制器和方法

  修改全局控制器:打開vendor/yiisoft/yii2/web/Application.php

eg:

public $defaultRoute = 'student/show';
 修改前臺或者後臺控制器:
eg :打開  frontend/config/main.php 中
'params' => $params,
'defaultRoute' => 'login/show',
2、建立控制器示例:StudentController.php

//命名空間

namespace frontend\controllers;


use Yii; 

use yii\web\Controller;   vendor/yiisoft/yii2/web/Controller.php   (該控制器繼承的是\yii\base\Controller)
\web\Controller.php中幹了些什麼  
1、默認開啓了 授權防止csrf攻擊
2、響應Ajax請求的視圖渲染
3、將參數綁定到動作(就是看是不是屬於框架自己定義的方法,如果沒有定義就走run方法解析)
4、檢測方法(beforeAction)beforeAction() 方法會觸發一個 beforeAction 事件,在事件中你可以追加事件處理操作;
5、重定向路徑 以及一些http Response(響應) 的設置
use yii\db\Query; //使用query查詢
use yii\data\Pagination;//分頁  
use yii\data\ActiveDataProvider;//活動記錄  
use frontend\models\ZsDynasty;//自定義數據模型 


class StudentController extends Controller
{  
 $request = YII::$app->request;//獲取請求組件
   $request->get('id');//獲取get方法數據
   $request->post('id');//獲取post方法數據
   $request->isGet;//判斷是不是get請求
   $request->isPost;//判斷是不是post請求
   $request->userIp;//獲取用戶IP地址
    $res = YII::$app->response;//獲取響應組件
    $res->statusCode = '404';//設置狀態碼
    $this->redirect('http://baodu.com');//頁面跳轉
    $res->sendFile('./b.jpg');//文件下載

 $session = YII::$app->session;
    $session->isActive;//判斷session是否開啓
    $session->open();//開啓session
    //設置session值
    $session->set('user','zhangsan');//第一個參數爲鍵,第二個爲值
    $session['user']='zhangsan';
    //獲取session值
    $session->get('user');
    $session['user'];
    //刪除session值
    $session-remove('user');
    unset($session['user']);

 $cookies = Yii::$app->response->cookies;//獲取cookie對象
    $cookie_data = array('name'=>'user','value'=>'zhangsan')//新建cookie數據
    $cookies->add(new Cookie($cookie_data));
    $cookies->remove('id');//刪除cookie
    $cookies->getValue('user');//獲取cookie

     //顯示視圖
     return $this->render('add'); 默認.php
     return $this->render('upda',["data"=>$data]); 
 

   }
}

二、模型層詳解

   簡單模型建立:

  

<?php

namespace frontend\models;
class ListtModel extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
    return 'listt';
    }
    public function one(){
       return $this->find()->asArray()->one();
    }
}

控制器引用
<?php
namespace frontend\controllers;
use Yii;
use yii\web\controller;
use frontend\models\ListtModel;

class ListtController extends Controller{
    public  function  actionAdd(){
        $model=new ListtModel;
        $list=$model->one();
       $data=$model->find()->asArray()->where("id=1")->all();
        print_r($data);
    }
}
?>


三、視圖層詳解首先在frontend下建立與控制器名一致的文件(小寫)eg:student 在文件下建立文件

eg:index.php
每一個controller對應一個view的文件夾,但是視圖文件yii不要求是HTML,而是php,所以每個視圖文件php裏面都是視圖片段:


  而views下面會有一個默認的layouts文件夾,裏面存放的就是佈局文件,什麼意思呢?:
在控制器中,會有一個layout字段,如果制定他爲一個layout視圖文件,比如common.php,那麼視圖就會以他爲主視圖,其他的view視圖片段都會作爲顯示片段嵌入到layout文件common.php中.
而如果不明確重載layout字段,那麼默認layout的值是main,意味着layouts的main.php是視圖模板。
控制器:

common.php:


layouts 

這樣就達到了視圖複用的作用。
    控制器中寫入$layout
//$layout="main"  系統默認文件
//$layout=null  會找父類中默認定義的main
public $layout="common";
public  function  actionIndex(){
  return  $this->render('index');
}
 將以下內容插入 common中
  <?=$content;?>  它就是index文件中的內容
當然了,視圖與模板之間還有數據傳遞以及繼承覆蓋的功能。





YII2框架數據的運用

1、數據庫連接

簡介

一個項目根據需要會要求連接多個數據庫,那麼在yii2中如何鏈接多數據庫呢?其實很簡單,在配置文件中稍加配置即可完成。

配置

打開數據庫配置文件common\config\main-local.php,在原先的db配置項下面添加db2,配置第二個數據庫的屬性即可

  1. 'db' => [  
  2.     'class' => 'yii\db\Connection',  
  3.     'dsn' => 'mysql:host=localhost;dbname=hyii2',   //數據庫hyii2  
  4.     'username' => 'root',  
  5.     'password' => 'pwhyii2',  
  6.     'charset' => 'utf8',  
  7. ],  
  8. 'db2' => [  
  9.     'class' => 'yii\db\Connection',  
  10.     'dsn' => 'mysql:host=localhost;dbname=hyii',     //數據庫hyii  
  11.     'username' => 'root',  
  12.     'password' => 'pwhyii',  
  13.     'charset' => 'utf8',  
  14. ],  

如上配置就可以完成yii2連接多個數據庫的功能,但還是需要注意幾個點

如果使用的數據庫前綴 在建立模型時 這樣: eg:這個庫叫 haiyong_test        return {{%test}}

應用

1.我們在hyii數據庫中新建一個測試表test

blob.png

2.通過gii生成模型,這裏需要注意的就是數據庫鏈接ID處要改成db2

blob.png

3.查看生成的模型,比正常的model多了紅色標記的地方

blob.png

所以各位童鞋,如果使用多數據配置,在建db2的模型的時候,也要加上上圖紅色的代碼。

好了,以上步驟就完成了,yii2的多數據庫配置,配置完成之後可以和原因一樣使用model或者數據庫操作

2、數據操作:


方式一:使用createCommand()函數

加 

獲取自增id

$id=Yii::$app->db->getLastInsertID();
  1. Yii::$app->db->createCommand()->insert('user', [    
  2.     'name' => 'test',    
  3.     'age' => 30,    
  4. ])->execute();  

批量插入數據

  1. Yii::$app->db->createCommand()->batchInsert('user', ['name''age'], [    
  2.     ['test01', 30],    
  3.     ['test02', 20],    
  4.     ['test03', 25],    
  5. ])->execute();  
刪除

  1. Yii::$app->db->createCommand()->delete('user''age = 30')->execute();  

修改

  1. Yii::$app->db->createCommand()->update('user', ['age' => 40], 'name = test')->execute();  
查詢

  1. //createCommand(執行原生的SQL語句)    
  2. $sql"SELECT u.account,i.* FROM sys_user as u left join user_info as i on u.id=i.user_id";    
  3. $rows=Yii::$app->db->createCommand($sql)->query();    
  4.   
  5. 查詢返回多行:      
  6. $command = Yii::$app->db->createCommand('SELECT * FROM post');    
  7. $posts = $command->queryAll();  
  8.    
  9. 返回單行  
  10. $command = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=1');    
  11. $post = $command->queryOne();  
  12.     
  13. 查詢多行單值:    
  14. $command = Yii::$app->db->createCommand('SELECT title FROM post');    
  15. $titles = $command->queryColumn();  
  16.     
  17. 查詢標量值/計算值:    
  18. $command = Yii::$app->db->createCommand('SELECT COUNT(*) FROM post');    
  19. $postCount = $command->queryScalar();  

方式二:模型處理數據(優秀程序媛必備)!!


新增(因爲save方法有點low)所以自己在模型層中定義:add和addAll方法

注意:!!!當setAttributes($attributes,fase);時不用設置rules規則,否則則需要設置字段規則;

 //入庫一維數組
    public function add($data)
    {
        $this->setAttributes($data);
        $this->isNewRecord = true;
        $this->save();
        return $this->id;
    }
     //入庫二維數組
    public function addAll($data){
        $ids=array();
        foreach($data as $attributes)
        {
            $this->isNewRecord = true;
            $this->setAttributes($attributes);
            $this->save()&& array_push($ids,$this->id) && $this->id=0;
        }
        return $ids;
    }


    public function rules()
    {
        return [
            [['title','content'],'required'
       ]];
    }

    控制器:

    $ids=$model->addAll($data);
     var_dump($ids);

刪除

使用model::delete()進行刪除

  1. $user = User::find()->where(['name'=>'test'])->one();   
  2. $user->delete();  

直接刪除:刪除年齡爲30的所有用戶

  1. $result = User::deleteAll(['age'=>'30']);  

根據主鍵刪除:刪除主鍵值爲1的用戶

  1. $result = User::deleteByPk(1);  


 /**
     * @param $files  字段
     * @param $values  值
     * @return int  影響行數
     */
    public function del($field,$values){
//        $res = $this->find()->where(['in', "$files", $values])->deleteAll();
        $res=$this->deleteAll(['in', "$field", "$values"]);
        return $res;
    }





修改

使用model::save()進行修改

  1. $user = User::find()->where(['name'=>'test'])->one(); //獲取name等於test的模型  
  2. $user->age = 40; //修改age屬性值  
  3. $user->save();   //保存  

直接修改:修改用戶test的年齡爲40

  1. $result = User::model()->updateAll(['age'=>40],['name'=>'test']);  


/**
 * @param $data   修改數據
 * @param $where  修改條件
 * @return int  影響行數
 */
public function upda($data,$where){
    $result = $this->updateAll($data,$where);
   // return $this->id;
    return $result;
}


基礎查詢

Customer::find()->one();    此方法返回一條數據;

Customer::find()->all();    此方法返回所有數據;

Customer::find()->count();    此方法返回記錄的數量;

Customer::find()->average();    此方法返回指定列的平均值;

Customer::find()->min();    此方法返回指定列的最小值 ;

Customer::find()->max();    此方法返回指定列的最大值 ;

Customer::find()->scalar();    此方法返回值的第一行第一列的查詢結果;

Customer::find()->column();    此方法返回查詢結果中的第一列的值;

Customer::find()->exists();    此方法返回一個值指示是否包含查詢結果的數據行;

Customer::find()->batch(10);  每次取10條數據 

Customer::find()->each(10);  每次取10條數據,迭代查詢 

//根據sql語句查詢:查詢name=test的客戶
Customer::model()->findAllBySql("select * from customer where name = test"); 

//根據主鍵查詢:查詢主鍵值爲1的數據
Customer::model()->findByPk(1); 

//根據條件查詢(該方法是根據條件查詢一個集合,可以是多個條件,把條件放到數組裏面) 
Customer::model()->findAllByAttributes(['username'=>'admin']); 

//子查詢
$subQuery = (new Query())->select('COUNT(*)')->from('customer');
// SELECT `id`, (SELECT COUNT(*) FROM `customer`) AS `count` FROM `customer`
$query = (new Query())->select(['id', 'count' => $subQuery])->from('customer');

//關聯查詢:查詢客戶表(customer)關聯訂單表(orders),條件是status=1,客戶id爲1,從查詢結果的第5條開始,查詢10條數據
$data = (new Query())
    ->select('*')
    ->from('customer')
    ->join('LEFT JOIN','orders','customer.id = orders.customer_id')
    ->where(['status'=>'1','customer.id'=>'1'])
    ->offset(5)
    ->limit(10)
    ->all()


關聯查詢

  1. /** 
  2.  *客戶表Model:CustomerModel  
  3.  *訂單表Model:OrdersModel 
  4.  *國家表Model:CountrysModel 
  5.  *首先要建立表與表之間的關係  
  6.  *在CustomerModel中添加與訂單的關係 
  7.  */       
  8. Class CustomerModel extends \yii\db\ActiveRecord  
  9. {  
  10.     ...  
  11.     //客戶和訂單是一對多的關係所以用hasMany  
  12.     //此處OrdersModel在CustomerModel頂部別忘了加對應的命名空間  
  13.     //id對應的是OrdersModel的id字段,order_id對應CustomerModel的order_id字段  
  14.     public function getOrders()  
  15.     {  
  16.         return $this->hasMany(OrdersModel::className(), ['id'=>'order_id']);  
  17.     }  
  18.       
  19.     //客戶和國家是一對一的關係所以用hasOne  
  20.     public function getCountry()  
  21.     {  
  22.         return $this->hasOne(CountrysModel::className(), ['id'=>'Country_id']);  
  23.     }  
  24.     ....  
  25. }  
  26.         
  27. // 查詢客戶與他們的訂單和國家  
  28. CustomerModel::find()->with('orders''country')->all();  
  29.   
  30. // 查詢客戶與他們的訂單和訂單的發貨地址(注:orders 與 address都是關聯關係)  
  31. CustomerModel::find()->with('orders.address')->all();  
  32.   
  33. // 查詢客戶與他們的國家和狀態爲1的訂單  
  34. CustomerModel::find()->with([  
  35.     'orders' => function ($query) {  
  36.         $query->andWhere('status = 1');  
  37.         },  
  38.         'country',  
  39. ])->all(); 
發佈了12 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章