Tìm hiểu Laravel (P10) - HTTP Requests

Indexs

  • Ở bài trước ta đã cùng nhau tìm hiểu về controller và có nhắc khá nhiều đến request. Vì thế ở bài này ta sẽ tìm hiểu chi tiết về HTTP Request.

1. Truy cập vào Request

  • Để lấy đối tượng hiện tại của HTTP request thông qua dependency injection, ta cần type-hint vào class Illuminate\Http\Request trong class controller. Các request đến sẽ được tự động injected bởi service container:

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class UserController extends Controller
    {
        /**
         * Store a new user.
         *
         * @param    Request  $request
         * @return  Response
         */
        public function store(Request $request)
        {
            $name = $request->input('name');
    
            //
        }
    }
    

Dependency Injection & Route Parameters

  • Nếu phương thức controller của bạn cũng cần lấy input từ tham số route thì bạn phải liệt kê danh sách tham số route vào sau các dependencies. Ví dụ, nếu route của bạn định nghĩa như sau:
    Route::put('user/{id}', '[email protected]');
    
  • Bạn vẫn phải type-hint Illuminate\Http\Request và truy cập vào tham số route id bằng cách định nghĩa phương thức trong controller như sau:
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class UserController extends Controller
    {
        /**
         * Update the specified user.
         *
         * @param    Request  $request
         * @param    string  $id
         * @return  Response
         */
        public function update(Request $request, $id)
        {
            //
        }
    }
    

Truy cập vào Request qua Route Closures

  • Bạn cũng có thể type-hint class Illuminate\Http\Request trong route Closure. Service sẽ tự động inject các request Closure khi nó sẽ được thực thi:
    use Illuminate\Http\Request;
    
    Route::get('/', function (Request $request) {
        //
    });
    

Đường dẫn Request & Phương thức

  • Đối tượng Illuminate\Http\Request cung cập một số phương thức để kiểm tra HTTP request cho ứng dụng và kế thừa class Symfony\Component\HttpFoundation\Request . Chúng ta sẽ thảo luận một số phương thức quan trọng dưới đây.
  • Nhận đường dẫn Request: Phương thức path trả về thông tin đường dẫn của request. Vì vậy, Nếu request gửi đến là http://domain.com/foo/bar, phương thức path sẽ trả về foo/bar:
    $uri = $request->path();
    
  • Phương thức is sẽ cho phép bạn xác nhận những request gửi đến có đường dẫn khới với pattern hay không. Bạn có thể sử dụng ký tự * khi sử dụng phương thức này:
    if ($request->is('admin/*')) {
        //
    }
    
  • Nhận Request URL: Để nhận đường dẫn đầy đủ URL từ request gửi đến bạn có thể sử dụng phương thức url or fullUrl. Phương thức url sẽ trả về URL không có string query, trong khi phương thức fullUrl bao gồm cả string query:
    // Without Query String...
    $url = $request->url();
    
    // With Query String...
    $url = $request->fullUrl();
    
  • Nhận phương thức Request: Phương thức method sẽ trả về phương thức HTTP tương ứng với request. Bạn có thể sử dụng phương thức isMethod để xác thực phương thức HTTP khớp với string:
    $method = $request->method();
    
    if ($request->isMethod('post')) {
        //
    }
    
  • Tiêu chuẩn của PSR-7 standard: tiêu chuẩn này quy định interfaces cho HTTP messages, bao gồm cả requests và responses. Nếu bạn muốn lấy một đối tưởng chuẩn của PSR-7 request thay vì một request Laravel, Đầu tiên bạn cần cài đặt một vài thư viện. Laravel sử dụng component Symfony HTTP Message Bridge để chuyển đổi requests và responses của Laravel thành PSR-7:
    composer require symfony/psr-http-message-bridge
    composer require zendframework/zend-diactoros
    
  • Khi bạn đã cài thư viện trên, bạn có thể lấy được PSR-7 request bằng cách type-hinting request interface trên route Closure hoặc phương thức controller:
    use Psr\Http\Message\ServerRequestInterface;
    
    Route::get('/', function (ServerRequestInterface $request) {
        //
    });
    

2. Lấy Input

  • Lấy tất cả dữ liệu Input:

    • Ta có thể lấy tất cả dữ liệu input như một array bằng cách sử dụng phương thức all:
      $input = $request->all();
      
  • Lấy giá trị một Input:

    • Sử dụng một vài phương thức cơ bản, bạn có thể truy cập tất cả các input từ người dùng qua Illuminate\Http\Request mà bạn không cần quan tâm tới các method HTTP được sử dụng cho request. Bất kể nó là phương thức HTTP nào, phương thức input sử dụng có thể lấy được input từ người dùng:
      $name = $request->input('name');
      
    • Bạn cũng có thể truyền giá trị của tham số như là một đối số thứ hai trong phương thức input. Giá trị sẽ được trả về nếu giá trị input không có trong request:
      $name = $request->input('name', 'Sally');
      
    • Khi bạn làm việc với form chứa mảng input, sử dụng dấm "chấm" để truy cập giá trị của mảng:
      $name = $request->input('products.0.name');
      
      $names = $request->input('products.*.name');
      
  • Lấy Input qua thuộc tính động:

    • Bạn có thể lấy input của người dùng bằng cách sử dụng thuộc tính động trong Illuminate\Http\Reques. Ví dụ, Nếu form ứng dụng của bạn có chứa trường name, bạn có thể truy lấy giá trị bằng cách:
      $name = $request->name;
      
    • Khi sử dụng thuộc tính động, đầu tiên Laravel sẽ tìm giá trị tham số trong request. Nếu nó không tìm thấy, Laravel laravel sẽ tìm trong tham số route.
  • Lấy giá trị JSON Input:

    • Khi bạn gửi JSON requests đến ứng dụng, bạn có thể lấy dữ liệu JSON qua phương thức input miễn là Content-Type header của request là application/json. Bạn cũng có thể dùng cú pháp "dấu chấm" để lấy giá trị mảng JSON:
      $name = $request->input('user.name');
      
  • Lấy một phần dữ liệu Input

    • Nếu bạn cần một tập con dữ liệu input, bạn có thể sử dụng phương thức only và except. Cả hai phương thức đều nhận một array hoặc một danh sách các đối số:
      $input = $request->only(['username', 'password']);
      
      $input = $request->only('username', 'password');
      
      $input = $request->except(['credit_card']);
      
      $input = $request->except('credit_card');
      
  • Kiểm tra giá trị Input Value tồn tại

    • Bạn có thể dùng phương thức has để kiểm tra giá trị input tồn tại trong request. Phương thức has trả về true nếu giá trị tồn tại và không phải chuỗi rỗng:
      if ($request->has('name')) {
          //
      }
      

Input cũ

  • Laravel cho phép ta giữ giá trị input từ lần request cũ tới request tiếp theo. Nó rất có ích trong trường hợp ta muốn thiết lập lại form khi validate lỗi. Theo mặc định khi ta sử dụng validate của Laravel thì Laravel đã tự động làm việc này cho ta thông qua built-in validation của Laravel, việc của ta là dùng chúng sao cho hợp lý.
  • Flashing Input tới Session:
    • Phương thức flash trong class Illuminate\Http\Request sẽ lưu input hiện tại vào trong session nên ta có thể dùng chúng trong request tiếp theo:
      $request->flash();
      
    • Nhưng nếu bạn không muốn lưu những thông tin nhạy cảm vào session, chẳng hạn như password thì ta có thể làm như sau:
      $request->flashOnly(['username', 'email']);
      $request->flashExcept('password');
      
  • Flashing Input rồi chuyển trang
    • Đôi khi ta muốn flash input vào session rồi chuyển về trang trước đó, lúc này ta sẽ cần dùng phương thức withInput:
      return redirect('form')->withInput();
      
      return redirect('form')->withInput(
          $request->except('password');
      );
      
  • Lấy input cũ
    • Để lấy flashed input từ request trước, ta sử dụng phương thức old của Request. Phương thức này sẽ lấy dữ liệu flashed input từ trước ra khỏi session:
      $username = $request->old('username');
      
    • Ngoài ra Laravel còn cung cấp sẵn một helper global old để ta có thể dễ dàng lấy ra input cũ từ view:
      <input type="text" name="username" value="{{ old('username') }}">
      
    • Nếu không tìm thấy input cũ thì phương thức old sẽ trả về null.

Cookies

  • Lấy Cookies From Requests

    • Tất cả cookies dược tạo bởi Laravel framework đều được mã hóa và ký một mã xác thực, nghĩa là chúng có thể bị coi là không hợp lệ nếu nó bị thay đổi phía dưới client. Để lấy một giá trị cookie từ request, sử dụng phương thức cookie từ Illuminate\Http\Request:
      $value = $request->cookie('name');
      
  • Gắn Cookies vào Responses

    • Bạn có thể gắp một cookie vào Illuminate\Http\Response bằng cách sử dụng phương thức cookie. Bạn có thể truyền tên, giá trị, và số phút cookie sẽ hết hạn vào phương thức:
      return response('Hello World')->cookie(
          'name', 'value', $minutes
      );
      
    • Phương thức cookie ngoài ra còn có một vài đối sô ít được sử dụng. Nói chung, những đối số đó có cùng mục đích và ý nghĩa giống với đối số của setcookie của PHP:
      return response('Hello World')->cookie(
          'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
      );
      
  • Tạo Cookie Instances

    • Nếu bạn muốn tạo một Symfony\Component\HttpFoundation\Cookie có thể response sau một khoảng thời gian, bạn có thể sử dụng helper global cookie. Khi đó cookie sẽ không gửi lại cho client trừ khi nó được gán vào response instance:
      $cookie = cookie('name', 'value', $minutes);
      
      return response('Hello World')->cookie($cookie);
      

3. Files

3.1 Lấy Files Uploaded

  • Ta có thể lấy files uploaded từ một Illuminate\Http\Request bằng cách sử dụng phương thức file hoặc sử dụng thuộc tính động. Phương thức file sẽ trả về một class Illuminate\Http\UploadedFile, nó kế thừa từ SplFileInfo class của PHP và cung cấp một số phương thức để tương tác với file:

    $file = $request->file('photo');
    
    $file = $request->photo;
    
  • Dùng phương thức hasFile để kiểm tra một file có tồn tại trên request hay không:

    if ($request->hasFile('photo')) {
        //
    }
    
  • Validate Uploads thành công

    • Ngoài việc kiểm tra file upload tồn tại, bạn có thể kiểm tra xem có vấn đề gì khi upload file bằng phương thức isValid:
      if ($request->file('photo')->isValid()) {
          //
      }
      
  • Đường dẫn File & Extensions

    • Class UploadedFile ngoài ra còn chứa phương thức lấy đường dẫn đầy đủ và extension của file. Phương thức extension sẽ cho phép đoán extension trên dựa nội dung của file. Extension này có thể khác với extension được cung cấp bởi client:
      $path = $request->photo->path();
      
      $extension = $request->photo->extension();
      

3.2 Lưu Files Uploaded

  • Để lưu một file uploaded, thông thường sử dụng một trong những cấu hình trong file app\config\filesystems.php. Class UploadedFile có phương thức store nó sẽ chuyển file upload từ ổ cứng của bạn đến một nơi có thể là trên local của bạn hoặc ngay cả trên cloud storage như Amazon S3.
  • Phương thức store chấp nhận đường dẫn file nên được lưu trữ đường dẫn tương đối so với thư mục gốc cấu hình của filesystem. Đường dẫn không được chứa tên file, tên sẽ tự động được sinh ra bằng cách sử dụng mã hóa MD5 của nội dung file.
  • Phương thức store ngoài ra còn chấp nhận tham số thứ hai có tên của nơi mà bạn sử dụng để lưu file. Phương thức sẽ trả về đường dẫn tương đối của file đối với thư mục gốc:
    $path = $request->photo->store('images');
    
    $path = $request->photo->store('images', 's3');
    
  • Nếu bạn không muốn tên file được tự động tạo ra, bạn có thể sử dụng phương thứcstoreAs, nó sẽ chấp nhận các đối số như đường dẫn, tên file, và tên nơi lưu:
    $path = $request->photo->storeAs('images', 'filename.jpg');
    
    $path = $request->photo->storeAs('images', 'filename.jpg', 's3');
    

Tài liệu tham khảo Laravel HTTP Request


All Rights Reserved