How to access the Laravel Request like a pro

How to access the Laravel Request like a pro

Laravel implements a fluent way to access the HTTP request with the Illuminate\Http\Request class. It enables you to work with the current request in an object-oriented style instead of using PHP superglobals $_GET, $_POST, $_REQUEST and $_FILES. Let’s take a closer look at the Request object to unleash its real power.

Get the query parameters

Query parameters are stored in the $_GET global variable in PHP. The Request class in Laravel has the query() method to get them out from the $_GET array.

// Retrieving $_GET['page']
$request->query('page');

You can pass a second argument to the query() method to be used as the default value when the mentioned query parameter is empty or not set. That is helpful when you want to set default values for filtering or sorting. Look at the following example that sorts the results by created_at attribute by default when sort attribute is not set in the query.

public function index(Request $request)
{
  $sortingAttribute = $request->query('sort', 'created_at');
  $articles = Article::orderBy($sortingAttribute)->all();

  return view('articles.index', [
    'articles' => $articles
  ]);
}

Retrieve data from request body

The Request class is smart enough to part Similar to query(), use the post() method to retrieve the data from HTTP request body.

public function store(Request $request)
{
  $article = new Article;

  // Retrieving $_POST['title']
  $article->title = $request->post('title');
  // Retrieving $_POST['content']
  $article->content = $request->post('content');

  $article->save();

  return view('articles.show', [
    'article' => $article
  ]);
}

Also, you may use the input() method to get data from any type of request.

$article->category = $request->input('category', 'None');

Both the post() and input() methods accept a second argument, which is the default value returned when the specified key is not found.

To make it further easier, the Request allows accessing the input data by using the keys as attributes of the request object itself. You can replace the above code with:

$article->category = $request->category;

I do not encourage this though. Because you have less control over the input data that way. But, this can be handy if you validate or check for availability of the input data before accessing them.

$request->validate([
  'category' => 'required'
]);

$article->category = $request->category;

What about JSON data?

The Request class is smart enough to parse form-data, as well as json data, comes in the request body. It utilizes the Content-Type header to identify the data type. If the Content-Type header is set to application/json, Request class parses the content in the request body and makes them available through the same methods you would use to access form-data.

Perform actions based on the existence or availability of data

You cannot expect the request to always carry the data you need. It’s a good practice to check for their existence before accessing them. Of course, you can use the default value as we saw a moment ago. But, what if the key exists in the request with an empty value? You better check for both.

Check for the existence of a particular key:

if ($request->has('title')) {
  // now you can safely access title
  $article->title = $request->input('title');

  // Or
  $article->title = $request->title;
}

Also, you can use the exists() method in the place of has(). They both serve the same purpose.

Though they checks for the existence of the key, it doesn’t mean the key has a value. Use the filled() method to check if a key has a value:

if ($request->filled('title')) {
  // now we are sure title has a value
  $article->title = $request->title;
}

There can be a scenario you need to pre-process request data only if their respective key exists or is filled with a value. The whenHas() and whenFilled() methods got you covered. Both of these methods accept two callback functions as second and third arguments. First is used for the success case and other for the failure.

Do something only when a key is available in the request data:

public function create(Request $request)
{
  $subject = $request->whenHas('subject', function($subject) {
    return 'Fw: ' . $subject;
  }, function() {
    return 'Your subject here';
  });

  return view('email.create', [
    'subject' => $subject
  ]);
}

Do something only when a key has a value:

public function create(Request $request)
{
  $subject = $request->whenFilled('subject', function($subject) {
    return 'Fw: ' . $subject;
  }, function() {
    return 'Your subject here';
  });

  return view('email.create', [
    'subject' => $subject
  ]);
}

Retrieve files from the request

Laravel Request wraps incoming files with the UploadedFile (Illuminate\Http\UploadedFile) class that provides a comprehensive set of functions to manage uploaded files.

Attempt saving a file only when it is uploaded:

// Save the avatar only when a file is uploaded
if ($request->hasFile('avatar')) {
  $avatar = $request->file('avatar');
  $avatar->store($pathToStore);
}

Get all files:

$pictures = $request->allFiles();

Support for debugging

Laravel Request class has dd() and dump() methods to help debugging. You can use them instead of dd() helper function.

// Dumps the value of key `name` and die
$request->dd('name');

// Dumps values of keys `name` and `subject` and die
$request->dd(['name', 'subject']);

// Dumps all request data and die
$request->dd();

// Dumps the value of key `name`
$request->dump('name');

// Dumps values of keys `name` and `subject`
$request->dump(['name', 'subject']);

// Dumps all request data
$request->dump();

The only difference is dd() strops the execution of script immediately while dump() does not.

Headers and cookies

Something we can’t forget when working with HTTP requests is headers and cookies. Laravel Request has methods for accessing them too.

Get the value of a header:

// Retrieve the value of the header
$request->header('Content-Type');

// Retrieve the value of the header, use the default value when header is missing
$request->header('Content-Type', 'application/json');

Similar to has(), you can use hasHeader() to check if a particular header is set on the request.

Some applications use the Authorization header to pass user credentials to the server. The value of this header can be in multiple formats. Unlike the other cases, when it caries a bearer token, the value has two parts that you need an additional step to extract the token. You can avoid that extra string operation using the bearerToken() method.

$token = $request->bearerToken();

Also, you can’t forget cookies. Get a cookie:

$hideIntro = $request->cookie('hide-intro', false);

You can use hasCookie() method to check the existence of a cookie before attempting to get its value with the cookie() method.

I hope this article will help you to work smart with the Laravel Request. Happy coding!

Saranga
Saranga A web developer and highly passionate about research and development of web technologies around PHP, HTML, JavaScript and CSS.
comments powered by Disqus