laravel6.0控制器-資源控制器


控制器:
控制器用來處理業務的,不應該處理邏輯,如果是小項目可以把邏輯寫到控制器里,大點的項目應該抽離出來業務處理層如下:
services業務處理層:比如:獲取值,驗證值,異常捕獲
 
命名規則:
控制器名:用大駝峰命名 如:HelloController;
方法名:用小駝峰 如:helloWorld();
成員變量:小駝峰 或者 _名稱
 
創建控制器(可以自定義目錄):
php artisan make:controller UserController
php artisan make:controller Admin/UserController
 
 
控制器簡單實用實例:
控制器簡單使用:
遷移數據庫
1.創建數據庫 laravel6 配置數據庫連接
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel6
DB_USERNAME=root
DB_PASSWORD=12345678
2.檢測默認連接
\config\database.php
   'default' => env('DB_CONNECTION', 'mysql'),
 
3.數據庫遷移命令:
php artisan migrate
可能會出現42000  1071錯誤 ,因為創建表的字段名稱過長,如下解決
在 \Providers\AppServiceProvider.php 中
 
控制器簡單使用:
遷移數據庫
1.創建數據庫 laravel6 配置數據庫連接
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel6
DB_USERNAME=root
DB_PASSWORD=12345678
2.檢測默認連接
\config\database.php
   'default' => env('DB_CONNECTION', 'mysql'),
 
3.數據庫遷移命令:
php artisan migrate
可能會出現42000  1071錯誤 ,因為創建表的字段名稱過長,如下解決
在 \Providers\AppServiceProvider.php 中
 
模型工程寫入
php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.10 — cli) by Justin Hileman
>>> factory(App\User::class,5)->create();
User模型 寫入5條數據
數據庫中寫入了5條數據
 
view視圖展示
路由:Route::get("show/{id}","UserController@show");
UserController控制器如下寫:
public function show($id)
{
    return view("user.profile",["user" => User::findOrNew($id)]);
}
傳遞 id 查出一數據顯示
創建視圖 \view\user\profile.blade.php
{{$user}}
 
 
 
 
 
模型工程寫入
php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.10 — cli) by Justin Hileman
>>> factory(App\User::class,5)->create();
User模型 寫入5條數據
數據庫中寫入了5條數據
 
view視圖展示
路由:Route::get("show/{id}","UserController@show");
UserController控制器如下寫:
public function show($id)
{
    return view("user.profile",["user" => User::findOrNew($id)]);
}
傳遞 id 查出一數據顯示
創建視圖 \view\user\profile.blade.php
{{$user}}
 
 
控制器加載原理:
在服務提供者中 RouteServiceProvider.php 中,可以自定義 命名空間
功能 與 業務抽離 不同的控制器目錄下
 
控制器 & 命名空間:
需要着重指出的是,在定義控制器路由時我們不需要指定完整的控制器命名空間。因為 `RouteServiceProvider` 會在一個包含命名空間的路由組中加載路由文件,我們只需要指令類名中 `App\Http\Controllers` 命名空間之后的部分就可以了。
 
單個行為控制器:
如果你想要定義一個只處理單個行為的控制器,你可以在控制器中放置一個 `__invoke` 方法:
你可以通過 Artisan 命令工具里的 `make:controller` 命令中的 `--invokable` 選項來生成一個可調用的控制器:
php artisan make:controller ShowProfile --invokable
 
控制器中間件:
請求流程:
用戶請求 -> 中間件 -> 控制器 -> 控制器方法
例如:
class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware("auth");  //如果沒有登錄會重定向到 login 路由中
        $this->middleware("log")->only("test"); // 只執行當前中間件中 index 之外的方法 [可以是數組] 類似於白名單
        $this->middleware("subscribed")->except("store"); //執行當前中間件中 store 之外的方法 [可以是數組] 類似於黑名單
//        dd($this);
    }
 
    //
    public function show($id)
    {
        return view("user.profile",["user" => User::findOrNew($id)]);
    }
 
    // pubf + tab 快捷鍵生成方法
    public function index()
    {
        echo "this is index()";
    }
 
    // 白名單方法test()
    public function test()
    {
 
    }
 
}
如上代碼會讀取log文件訪問 log /Users/xxxx/wwwn/ test.laravel6.com/storage/logs
錯誤: Route [login] not defined.
原因: 沒有登錄的時候回執行 Middleware\Authenticate.php 重定向方法
    protected function redirectTo($request)
    {
        if (! $request->expectsJson()) {
 
            return route('login');
        }
    }
錯誤:需要對象式的參數 log() expects parameter 1 to be float, object given
$this->middleware("log")這個中間件的錯誤提示
 
可以通過閉包注冊中間件
同時,控制器還允許你使用一個閉包來注冊中間件。這為不定義整個中間件類的情況下為單個控制器定義中間件提供了一種方便的方法:
$this->middleware(function ($request, $next) {
    return $next($request);
});
 
Http請求處理:
用戶請求 -> Illuminate\Http\Request請求類 ->
laravel 中 post請求 Cookie攜帶有 CRSF令牌,如果想要post get方式都可以請求需要注釋掉 CRSF令牌校驗在 kernel.php 如下:
    //  \App\Http\Middleware\VerifyCsrfToken::class,
public function store(Request $request, $name=null)
{
    $name = $request->input('name'); // 既可以獲取get 也可以請求post參數
    $get = $request->get('name');
    $post = $request->post('name');
    $all = $request->all('name');
    dd($name,$get,$post,$all);
    return $name;
}
 
一個路由中可以,既有post參數,也有get地址欄的 where參數
Route::any("stores/{id}/{where?}","UserController@stores");
打印:
"333"
"age"
array:2 [
  "u" => "getUser"
  "s" => "shengri"
]
 
舊數據:
Laravel 允許你在兩次請求之間保持數據。這個特性在有效性校驗出錯后重新填充表單時非常有用。
比如:保存用戶名!
1.1 存儲到session中
    //讀取 session數據
    $name = $request->old("name");  // post 方式請求的 存儲到session
    $m = $request->old("m");        // where get 方式請求的 存儲到session
    var_dump($name,$m);
    //dd($name,$m);
    會把 請求參數寫入session文件 \storage\framework\session\.......
 
文件:上傳與下載
php artisan make:controller FileController
當然你也可以使用 `hasFile` 方法判斷請求中是否存在指定文件:
if ($request->hasFile('photo')) {}
驗證成功上傳:除了檢查上傳的文件是否存在外,你也可以通過 `isValid` 方法驗證上傳的文件是否有效:
if ($request->file('photo')->isValid()) {}
文件路徑 & 擴展名:`UploadedFile` 類還包含訪問文件的全路徑和擴展名的方法。 `extension` 方法會根據文件內容判斷文件的擴展名。該擴展名可能會和客戶端提供的擴展名不同:
$path = $request->photo->path();  //臨時路徑
$extension = $request->photo->extension();  //后綴名
 
存儲上傳文件:
要存儲上傳的文件,先配置好 [文件系統]( https://learnku.com/docs/laravel/6.0/filesystem)。 你可以使用 `UploadedFile` 的 `store` 方法把上傳文件移動到你的某個磁盤上,該文件可能是本地文件系統中的一個位置,甚至像 Amazon S3 這樣的雲存儲位置。
`store` 方法接受相對於文件系統配置的存儲文件根目錄的路徑。這個路徑不能包含文件名,因為系統會自動生成唯一的 ID 作為文件名。
`store` 方法還接受可選的第二個參數,用於存儲文件的磁盤名稱。這個方法會返回相對於磁盤根目錄的文件路徑:
$path = $request->photo->store('images');  // 上傳的文件默認保存在 storage\app\images\xxxxxx
$path = $request->photo->store('images', 's3');
如果你不想自動生成文件名,那么可以使用 `storeAs` 方法,它接受路徑、文件名和磁盤名作為其參數:
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
 
響應:
字符串,數組,視圖,
響應信息可以自定義,針對不同的響應結果,返回對應的響應狀態
string 類型響應 text/html; charset=UTF-8
arr    響應類型 application/json
3.4.2  Response 對象:
通常,我們並不只是從路由動作簡單返回字符串和數組,大多數情況下,都會返回一個完整的`Illuminate\Http\Response` 實例或 [視圖]( https://learnku.com/docs/laravel/6.0/views)。
 
返回完整的 `Response` 實例允許你自定義響應的 HTTP 狀態碼和響應頭信息。 `Response` 實例 繼承自 `Symfony\Component\HttpFoundation\Response` 類, 該類提供了各種構建 HTTP 響應的方法:
 
Route::get('home', function () {
    return response('Hello World', 200)
                  ->header('Content-Type', 'text/plain');
});
 
添加響應頭:
大部分的響應方法都是可鏈式調用的,使得創建響應實例的過程更具可讀性。例如,你可以在響應返回給用戶前使用 `header` 方法為其添加一系列的頭信息:
return response($content)
            ->header('Content-Type', $type)
            ->header('X-Header-One', 'Header Value')
            ->header('X-Header-Two', 'Header Value');
或者,你可以使用 `withHeaders` 方法來指定要添加到響應的頭信息數組:
return response($content)
            ->withHeaders([
                'Content-Type' => $type,
                'X-Header-One' => 'Header Value',
                'X-Header-Two' => 'Header Value',
            ]);
 
重定向:
重定向響應是 `Illuminate\Http\RedirectResponse` 類的實例,並且包含用戶需要重定向至另一個 URL 所需的頭信息。Laravel 提供了幾種方法用於生成 `RedirectResponse` 實例。其中最簡單的方法是使用全局輔助函數 `redirect`:
Route::get("home",function (){
    return redirect("string"); // 重定向到指定路由
});
Route::get("home",function (){
    return redirect(" http://www.baidu.com");  //重定向到 外部的連接url
});
Route::get("cdx",function (){
    return redirect()->away('arr');  // 重定向到指定路由
});
 
有時候你可能希望將用戶重定向到之前的位置,比如提交的表單無效時。這時你可以使用全局輔助函數 `back` 來執行此操作。由於這個功能利用了 [會話控制]( https://learnku.com/docs/laravel/6.0/session),請確保調用 `back` 函數的路由使用 `web` 中間件組或所有 Session 中間件:
Route::post('user/profile', function () {
    // 驗證請求
    return back()->withInput();
});
 
重定向到命名路由:
如果調用不帶參數的輔助函數 `redirect` 時,會返回 `Illuminate\Routing\Redirector` 實例。這個實例允許你調用 `Redirector` 上的任何方法。例如為命名路由生成 `RedirectResponse`,可以使用 `route` 方法:
return redirect()->route('login');
如果路由中有參數,可以將其作為第二個參數傳遞到 `route` 方法:
return redirect()->route('profile', ['id' => 1]);
 
重定向到控制器行為:
還可以生成到 [controller action]( https://learnku.com/docs/laravel/6.0/controllers) 的重定向。要達到這個目的,只要把 控制器 和 action 的名稱傳遞給 `action` 方法。記住,不需要傳遞控制器的全部命名空間,Laravel 的 `RouteServiceProvider` 會自動將其設置為基本控制器的命名空間:
return redirect()->action('HomeController@index');
如果控制器路由需要參數,可以將其作為 `action` 方法的第二個參數:
return redirect()->action(
    'UserController@profile', ['id' => 1]
);
重定向到外部域名:
有時候你需要重定向到應用外的域名。調用 `away` 方法可以達到此目的,它會創建一個不帶有任何額外的 URL 編碼、有效性校驗和檢查的 `RedirectResponse` 實例:
return redirect()->away(' https://www.google.com');
其他的響應類型:
`response` 助手可以用於生成其它類型的響應實例。當還帶參數調用 `response` 助手時,返回 `Illuminate\Contracts\Routing\ResponseFactory` [contract]( https://learnku.com/docs/laravel/6.0/contracts) 的一個實現。這個契約提供了幾個用於生成響應的方法:
視圖響應:
如果需要把 [視圖]( https://learnku.com/docs/laravel/6.0/views) 作為響應內容返回的同時,控制響應狀態和頭信息,就需要調用 `view` 方法,如果不需要傳遞自定義的 HTTP 狀態碼和自定義頭信息,還可以使用全局的 `view` 輔助函數。
return response()
            ->view('hello', $data, 200)
            ->header('Content-Type', $type);
JSON響應:
`json` 自動將 `Content-Type` 頭信息設置為 `application/json`,同時使用 PHP 的 `json_encode` 函數將給定的數組轉換為 JSON :
return response()->json([
    'name' => 'Abigail',
    'state' => 'CA'
]);
如果想要創建 JSONP 響應,可以結合 `withCallback` 方法使用 `json` 方法:
return response()
            ->json(['name' => 'Abigail', 'state' => 'CA'])
            ->withCallback($request->input('callback'));
 
文件下載:
1.設置http響應頭
2.下載文件的名稱,大小
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
return response()->download($pathToFile)->deleteFileAfterSend();
 
RESTful 風格:定義:
REST 是 “呈現狀態轉移(REpresentational State Transfer)” 的縮寫。或許可以這樣來定義它:一種 API 的架構風格,在客戶端和服務端之間通過呈現狀態的轉移來驅動應用狀態的演進。
 
約束:
要讓應用 RESTful 化,需要遵循以下約束。遵循了這些約束的分布式系統,就會擁有如下非功能屬性:性能,伸縮性,易用性,擴展性,可見性,可移植性和可靠性。
 
CS 模式:
CS 模式通過分離客戶端和服務器端的關注點,讓客戶端不再關注數據的存儲問題,從而提高客戶端代碼的可移植性。另一方面,服務器端不再關注用戶界面和用戶狀態,從而變得更簡單,提高了伸縮性。服務器端跟客戶端可以獨立開發,只要它們都遵守契約。
 
無狀態:
客戶端上下文在多個請求之間是絕不會保存在服務器上的。每個請求必須包含必要的信息。無狀態的服務器通過快速釋放資源和簡化實現提高了可伸縮性。可靠性使得從局部失敗中恢復變得容易。很明顯,監控系統不必通過考慮單個請求來判斷請求的性質。 無狀態服務器的一個缺點是降低了網絡性能,因為所有需要的數據必須在每次請求中發送。
 
可緩存:
REST 應用程序是 web 系統,因此客戶端和中間層可以緩存響應。響應必須被定義為可緩存或不可緩存的,以防客戶端重復使用舊數據導致降低可靠性。如果緩存中的陳舊數據與已生成的請求的數據顯著不同,則由服務器處理請求。緩存可以消除一些客戶端和服務器之間的交互,這就提升了可伸縮性、效率和通過減少平均延遲達到的用戶可感知的性能。
 
統一的接口:
使用統一的接口降低了系統復雜度和耦合度,讓系統的不同部分可以獨立演化。稍后會解釋 URI,資源和超媒體是如何通過生成標准接口來提升用戶交互可見性,降低系統復雜度,促進系統組件獨立演化的。但是我們需要在效率方面做出妥協,畢竟消息是通過標准格式傳輸的,並不能滿足所有應用對消息格式的要求。
 
分層的系統:
分層系統通過約束組件的行為來降低系統復雜度,組件不能越過它們的媒介層去訪問其它層。通過組件的阻斷來保持層間的獨立性。遺留的組件可以被封裝成新的層,不讓舊的客戶端訪問。媒介層可以通過負載均衡來提升伸縮性。分層系統存在的主要不足,是它給數據處理增加了一些額外的開銷,增加了延遲,對用戶體驗有所影響。
 
按需編碼:
 
REST 允許客戶端通過下載執行腳本來擴展它們的功能,簡化了客戶端,也提升了擴展性。但這同時也降低了可見性,所以這個約束不是必須遵循的。
 
元素:
REST 提供了以下幾種元素來構建無狀態,可伸縮的 web API。
 
HTTP協議:
資源
URI
超媒體
HTTP - 文本傳輸協議
 
REST 一般使用 HTTP 作為它的傳輸協議,因為 HTTP 提供了一些很好用的特性,如 HTTP 動詞,狀態碼和頭部信息
 
HTTP 動詞:
HTTP 並沒有定義很多動詞來描述 web 服務中可能出現的行為,它只用了一個標准動詞集合來處理各種相似情況,從而讓 API 變得更直觀。每個動詞通過兩種屬性的組合來滿足不同的場景需求。
 
冪等性:操作可以被重復執行,就算在失敗以后。
安全性:對客戶端來說操作不會產生副作用。
 
GET:
用來從服務器端讀取狀態。這個操作是安全的,所以它可以被執行很多次而不會對數據有任何影響,也就是說執行它一次跟執行十次是一樣的效果。從冪等性方面來看,多次請求跟單個請求總能得到相同的結果。
 
POST:
一般用來在服務器端創建某種狀態。這個操作不具備冪等性跟安全性,所以多次請求會在服務器端創建多個資源。因為 POST 是不冪等的, 所以不應該被用來做跟金錢有關系的操作,試想一次失敗的請求如果被執行多次,那么很可能轉賬或者支付也被執行了多次。
 
PUT:
雖然它也可以被用來創建狀態,但主要還是用來在服務器端更新狀態的。它是冪等的,但不安全,因為它會改變服務端的狀態。因為它的冪等性,PUT 可以被用來處理跟金錢有關系的操作。
 
DELETE:
用來在服務器端刪除狀態。它也是冪等非安全的,因為它會移除服務端的狀態。它之所以是冪等的,是因為重復刪除一個狀態的結果是一樣。
 
響應狀態碼:
HTTP 在請求資源的響應里提供了元數據信息,也就是狀態碼。它們是 web 平台之所以能用來構建分布式系統的重要因素。它們被分為以下幾類:
- 1xx —— 元數據
- 2xx —— 正確的響應
- 3xx —— 重定向
- 4xx —— 客戶端錯誤
- 5xx —— 服務端錯誤
 
頭部信息:
HTTP 在消息頭部里為請求響應提供了額外信息。每個頭部由大小寫敏感的關鍵字和值組成,中間用冒號隔開。頭部信息被分為以下幾類:
一般頭部:在請求跟響應里都有,跟消息體里傳輸的數據沒有關系。
請求頭部:更多的是關於被請求資源或者客戶端的信息。
響應頭部:響應的額外信息。
實體頭部:消息體的額外信息,比如 content-length 或 MIMI-type。
 
資源:
資源可以是由系統暴露出來的任何具有唯一標識的東西。資源在應用領域跟客戶端之間建立起了聯系。一張圖片,一個表格,或者它們的集合,都被看作資源。資源通過某種呈現方式被獲取或被創建 (XML,JSON 等)。 我們與之打交道的是資源的呈現形式,並不是資源本身,這個跟值傳遞有點像。根據之前對 REST 的定義,資源代表了在網絡上傳輸的文檔。服務器端關心資源的狀態,因為它們代表了領域的狀態。而客戶端只是獲取或者發送資源的呈現狀態,從而讓應用的狀態發生變化。客戶單關心的是應用的狀態,因為這些狀態的變化跟應用所要達成的目標有關系。 資源的名字都應該是名詞性質的,它們代表的是系統中領域的概念,並用 URI 標識。
 
URIs  (Uniform Resource Identifiers)
URIs 用來唯一標識資源。要訪問或者操作一個資源,最起碼要知道資源的地址。它們由協議 + 服務器地址 + 路徑組成。
客戶端不應該與資源的 URI 有太多耦合,因為服務端可能隨意改變它們的值。在這一點上,超媒體更具優勢。它提供了一種解耦客戶端跟 URI 的方式,並在應用協議中加入新的語義。
 
資源控制器:
簡介:
Laravel 的資源路由將典型的「CURD (增刪改查)」路由分配給具有單行代碼的控制器。例如,你希望創建一個控制器來處理保存 "照片" 應用的所有 HTTP 請求。使用 Artisan 命令 `make:controller` ,我們可以快速創建這樣一個控制器:
php artisan make:controller PhotoController --resource
這個命令將會生成一個控制器 `app/Http/Controllers/PhotoController.php` 。其中包括每個可用資源操作的方法。
 
接下來,你可以給控制器注冊一個資源路由:
Route::resource('photos', 'PhotoController');
 
這個單一的路由聲明創建了多個路由來處理資源上的各種行為。生成的控制器為每個行為保留了方法,包括了關於處理 HTTP 動詞和 URLs 的聲明注釋。
 
你可以通過將數組傳參到 `resource` 方法中的方式來一次性的創建多個資源控制器:
Route::resources([
    'photos' => 'PhotoController',
    'posts' => 'PostController'
]);
 
資源控制器操作處理:
 
| HTTP 方法 | URI                    | 動作    | 路由名稱       |
| --------- | ---------------------- | ------- | -------------- |
| GET       | `/photos`              | index   | photos.index   |
| GET       | `/photos/create`       | create  | photos.create  |
| POST      | `/photos`              | store   | photos.store   |
| GET       | `/photos/{photo}`      | show    | photos.show    |
| GET       | `/photos/{photo}/edit` | edit    | photos.edit    |
| PUT/PATCH | `/photos/{photo}`      | update  | photos.update  |
| DELETE    | `/photos/{photo}`      | destroy | photos.destroy |
 
制定資源模型:
如果你使用了路由模型綁定,並且想在資源控制器的方法中使用類型提示,你可以在生成控制器的時候使用 `--model`選項:
php artisan make:controller PhotoController --resource --model=Photo
 
 
部分資源路由:
Route::resource('photos', 'PhotoController')->only([
    'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
    'create', 'store', 'update', 'destroy'
]);
 
API 資源路由:
當聲明用於 APIs 的資源路由時,通常需要排除顯示 HTML 模板的路由(如 `create` 和 `edit` )。為了方便起見,你可以使用 apiResource 方法自動排除這兩個路由:
 
Route::apiResource('photos', 'PhotoController');
 
你可以傳遞一個數組給 `apiResources` 方法來同時注冊多個 API 資源控制器:
Route::apiResources([
    'photos' => 'PhotoController',
    'posts' => 'PostController'
]);
 
要快速生成不包含 `create` 或 `edit` 方法的用於開發接口的資源控制器,請在執行 `make:controller` 命令時使用 `--api` 開關:
php artisan make:controller API/PhotoController --api
 
命名資源路由:
默認情況下,所有的資源控制器行為都有一個路由名稱。你可以傳入 names 數組來覆蓋這些名稱:
Route::resource('photos', 'PhotoController')->names([
    'create' => 'photos.build'
]);
命名資源路由參數:
 
默認情況下,`Route::resource` 會根據資源名稱的「單數」形式創建資源路由的路由參數。你可以在選項數組中傳入 `parameters` 參數來輕松地覆蓋每個資源。`parameters` 數組應該是資源名稱和參數名稱的關聯數組
Route::resource('users', 'AdminUserController')->parameters([
    'users' => 'admin_user'
]);
 
上例將會為資源的 `show` 路由生成如下的 URI :
/users/{admin_user}
 
php artisan make:controller Api/ResController --resource
php artisan route:list
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM