Laravel Middleware Explained: What It Is & How to Create One

Learn what middleware is in Laravel, why it’s essential, and how to create custom middleware for handling requests efficiently. Step-by-step guide included.

Middleware provides a convenient mechanism for inspecting and filtering HTTP requests entering your application. It’s best to envision middleware as a series of “layers” for HTTP requests that must pass through before they hit your application. Each layer can examine the request and even reject it entirely.

For example, Laravel includes a middleware that verifies the authenticity of the user of your application. If the user is not authenticated, the middleware will redirect the user to your application’s login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.

To perform different tasks, we can develop many middlewares besides authentication. For example, a logging middleware might log all incoming requests to your application. 

Laravel framework has included many middlewares, including middleware for authentication and CSRF protection. All of these middlewares are located in the app/Http/Middleware directory.

Create a custom middleware

To create a middleware, we can use the following command,

php artisan make:middleware <middleware-name>

For example, if we want to create a middleware for checking transactions, we can run the following command,

php artisan make:middleware CheckTransaction

 After successful execution of the command, a middleware class will be created under the app/Http/Middleware directory.

In this class, we can define methods to check transactions. If the transaction is not completed, we can redirect the user back to the failed transaction page. However, on the successful transactions, we can allow users to proceed to the next page.

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class CheckTransaction
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('status') !== 'completed') {
            return redirect('transaction-failed');
        }
 
        return $next($request);
    }
}

As you can see, if the transaction status does not set to “completed”, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application.

To pass the request deeper into the application (allowing the middleware to “pass”), you should call the $next callback with the $request.

Find Bugs Efficiently with PHPStan Static Analyzer

Learn how to detect bugs early in your PHP codebase using PHPStan, a powerful static analyzer. Improve code quality with practical tips and examples.

With PHP being an interpreted language it has a downside when it comes to finding bugs in your code. It will not show you errors in your software until you actually run it. PHPStan tries to solve this problem by doing static analysis on your code. It was recently created by Ondrej Mirtes.

Running PHPStan will tell you about bugs in your codebase almost instantly (yes, it’s very fast). At the time of writing this article, PHPStan currently checks your code on:

  • The existence of classes and interfaces in an instance of, catch type hints, other language constructs, and even annotations. PHP does not do this and just stays silent instead.
  • Existence of variables while respecting scopes of branches and loops.
  • Existence and visibility of called methods and functions.
  • Existence and visibility of accessed properties and constants.
  • Correct types assigned to properties.
  • The correct number and types of parameters are passed to constructors, methods, and functions.
  • Correct types returned from methods and functions.
  • The correct number of parameters passed to sprintf/printf calls is based on format strings.
  • Useless casts like (string) ‘foo’.
  • Unused constructor parameters – they can either be deleted or the author forgot to use them in the class code.
  • That only objects are passed to the clone keyword.

As you can see, it contains a lot of useful checks which will warn you of potential bugs before you even run your code.

Installing PHPStan

Installing PHPStan is as easy as including it in your project through composer:

$ composer require --dev phpstan/phpstan

We can now run PHPStan from the base directory of our project:

$ vendor/bin/phpstan analyze -l 4 src

A breakdown of this command:

  • vendor/bin/phpstan is the executable
  • analyze tells PHPStan to analyze all files in the given directories
  • -l 4 means that we want to analyse on the most strict level
  • src is the directory we want to analyse

Try running this in your own project and see what kind of potential errors are living in your codebase.

Integrating PHPStan into CI

It’s super easy to use PHPStan in Continuous Integration. For most of my personal projects, I use TravisCI. Since we’ve included PHPStan as a dev-dependency in our composer.json file we just have to add the PHPStan executable to the scripts that the CI-software needs to run.

For TravisCI, this means just changing the default script in a .travis.yml like this:

language: php
php:
  - '8.0'
install: composer install

# Simply add these lines
script:
    - vendor/bin/phpunit
    - vendor/bin/phpstan analyse src tests --level=4

The default script that TravisCI runs for PHP projects is simply phpunit. Now we’ve added PHPStan to it. If PHPStan finds any errors within your project, the build will fail.

Advanced Error Handling in PHP (Part 2)

Explore advanced techniques for error handling in PHP including exceptions, custom error handlers, and best practices in Part 2 of this series.

Now that we know, how to log errors in any system developed in PHP, we can move to our next section for keeping track of these logged errors. If you haven’t read how to log errors, read part 1 of error handling in PHP.

To keep track of these logged errors, we need to create a script to read those log files in a systematic way. Refer to the below code to read log files,

public function errorLogs($filePath = 'error.log') {

        $fileContent = file($filePath);

        $errorsArray = array();
        if(sizeof($fileContent) == 0) {
            return false;
        }

        foreach($fileContent as $row) {
            $errors = explode(":  ", $row);

            if(empty($errors[1])) continue;
            $errorsArray[] = $errors;
        }

        return array_reverse($errorsArray, true);
}

Explanation:

$fileContent = file($filePath);

This line of code will read the file line by line from the provided file path.

if(sizeof($fileContent) == 0) {
    return false;
}

After reading the file, if the size of the file content is 0 then, the function will return false. So, the purpose of this function is to stop the execution of the function if the provided file is empty and returns false.

foreach($fileContent as $row) {
      $errors = explode(":  ", $row);

      if(empty($errors[1])) continue;
      $errorsArray[] = $errors;
}

This part of the function will loop through the log contents row by row. For each row, it will explode the line with ‘:’ to separate the date and actual error details.

If the error details are empty for any row, it will skip that row. Otherwise, it will collect the errors in another array.

return array_reverse($errorsArray, true);

The last line of the function will reverse the error data and returned the reversed result. So, that we can see the latest errors first.

This way we can create a simple function to display the list of errors in a tabular format from the error log files we generated for each of the modules in the application system.

Beginner’s Guide to Error Handling in PHP – Part 1

Learn the basics of error handling in PHP. Understand types of errors, how to display them, and the use of error_reporting() and ini_set() functions.

Error handling is an important part of any developer as it provides vital flaws about the program developed by the developer. So, it becomes very crucial to learn the techniques to manage it.

As a developer, we have been told that you should not show errors on the production server because of the security risk due to the path displayed by the PHP errors displayed on the screen. So, we add the following code for the production server,

ini_set('error_reporting', 0);
error_reporting(0);

ini_set('display_errors', FALSE);

But, without error logs, developers cannot able to know actual problems or flaws in the system. So, rather than hiding errors, developers should store them in the log files. We can achieve this using the following code,

ini_set('error_reporting', E_ALL);
error_reporting(E_ALL);
ini_set('log_errors', TRUE);
ini_set('html_errors', FALSE);
ini_set('error_log', LOG_PATH.'error.log');
ini_set('display_errors', FALSE);

This way, we can manage error logs and hide errors on the production server. We can manage separate log files for the different modules of the project.

Get Last Executed Query in CodeIgniter PHP

Learn how to retrieve the last executed query in CodeIgniter’s built-in query methods developed in PHP. Helpful for debugging and query optimization.

When developing applications with CodeIgniter, retrieving the last executed SQL query becomes the most useful features for debugging and performance tuning. Whether you’re trying to diagnose a bug, optimize performance, or log queries for later review, CodeIgniter makes it easy to access the most recent database query.

In this article, we’ll explore how to get the last executed query in both CodeIgniter 3 and CodeIgniter 4, with examples.

Why Retrieve the Last Executed Query?

Here are a few scenarios where getting the last executed query is helpful:

  • Debugging incorrect or unexpected results.
  • Profiling SQL performance issues.
  • Logging queries for auditing purposes.
  • Building custom query logs for admin or developer panels.

CodeIgniter 3: Getting the Last Query

CodeIgniter 3 provides a simple method from the database class:

$this->db->last_query();

For Example:

public function getUser($id)
{
    $query = $this->db->get_where('users', ['id' => $id]);
    echo $this->db->last_query(); // Outputs the SQL query
    return $query->row();
}

Output:

SELECT * FROM `users` WHERE `id` = '1'

You can also store it in a variable to use it for logging:

$last_query = $this->db->last_query();
log_message('debug', 'Last Query: ' . $last_query);

CodeIgniter 4: Getting the Last Query

In CodeIgniter 4, the approach is slightly different. You can use the getLastQuery() method from the Query Builder object.

Example:

$db = \Config\Database::connect();
$builder = $db->table('users');

$query = $builder->where('id', 1)->get();
echo $db->getLastQuery(); // Outputs the last SQL query

Output:

SELECT * FROM `users` WHERE `id` = 1

getLastQuery() returns a CodeIgniter\Database\Query object, so you can also format it if needed:

echo $db->getLastQuery()->getQuery(); // returns query string

Pro Tips

  • Use this feature only in development mode or behind admin-only views.
  • Avoid exposing raw SQL queries in production environments for security reasons.
  • Combine it with CodeIgniter\Debug\Toolbar for enhanced SQL visibility in CI4.

Logging All Queries in CodeIgniter

You can also log all database queries automatically:

CodeIgniter 3:

In application/config/database.php, set:

$db['default']['save_queries'] = TRUE;

Then access them:

print_r($this->db->queries); // array of all executed queries

CodeIgniter 4:

Use the Debug Toolbar, or manually:

$db = \Config\Database::connect();
$queries = $db->getQueries(); //returns an array of all queries

Conclusion

Accessing the last executed SQL query in CodeIgniter is a powerful feature that can significantly speed up debugging and development. Whether you’re using CodeIgniter 3 or 4, the framework provides convenient tools to track your database interactions.

Make sure to leverage this feature wisely, especially when you’re optimizing queries or tracking down elusive bugs.

Do you use query logging in your CodeIgniter project? Share your tips or challenges in the comments below!