Using Laravel to upload a file

Learn how to handle file uploads in Laravel, including validations and best practices.

Uploading a file in any programming is a challenge. In this post, we focus on uploading a file and some validations to use with file upload using Laravel.

To upload a file using Laravel, you can follow these steps:

Create a new form in your Laravel view with an input field for the file:

<form method="POST" action="{{ route('file.upload') }}" enctype="multipart/form-data">
    @csrf

    <input type="file" name="file">

    <button type="submit">Upload</button>
</form>

In above code, we have added file.upload route as an action of the form. So, we need to define this route in routes/web.php file. This route should point to the controller method that will handle the file upload.

The following code will define a new route in your routes/web.php file:

Route::post('/file/upload', [App\Http\Controllers\FileController::class, 'upload'])->name('file.upload');

Above code has defined a route, which points to the upload method of the FileController. So, create a new controller FileController and method upload inside that to handle the file upload as follows:

class FileController
{
    public function upload(Request $request)
    {
        // Validate the uploaded file
        $request->validate([
            'file' => 'required|file|max:1024', // limit file size to 1 MB
        ]);

        // Store the uploaded file in the storage/app/public directory
        $path = $request->file('file')->store('public');

        // Generate a URL for the uploaded file
        $url = Storage::url($path);

        // Redirect back with a success message
        return back()->with('success', 'File uploaded successfully: ' . $url);
    }
}

In the upload() method, we first validate that the uploaded file meets our requirements. So, we have added some validations for our file. These validations are as follows:

required:

The field under this validation must be present in the input data and must not empty. A field is “empty” if it meets one of the following criteria:

  • The value is null.
  • The value is an empty string.
  • The value is an empty array or empty Countable object.
  • The value is an uploaded file with no path.

file:

The field under this validation must be a successfully uploaded file.

max:1024:

The field under this validation must be less than or equal to a 1024 bytes. Here, 1024 is value of file size. You can change it according to your requirements.

We then use the store() method on the uploaded file to store it in the storage/app/public directory. This directory is publicly accessible, so we can generate a URL for the file using the url() method on the Storage facade. Finally, we redirect back to the form with a success message that includes the URL of the uploaded file.

You can now test the file upload functionality by navigating to the form and selecting a file to upload. If the file meets the validation requirements, it will be uploaded and a success message will be displayed. You can then access the uploaded file at the generated URL.

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.

Detecting Bugs in PHP Code with PHPStan: A Static Analysis Tool

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

Writing clean, bug-free code is a goal for every developer — but manual testing and reviews aren’t always enough. That’s where static analysis tools like PHPStan come in. PHPStan helps you catch bugs in your PHP code without executing it. By analyzing your source files, it detects potential issues before they ever become runtime errors.

In this article, we’ll explore what PHPStan is, how it works, and how you can integrate it into your PHP projects to improve code quality.

What is PHPStan?

PHPStan is a static analysis tool specifically designed for PHP. It scans your codebase and finds problems such as:

  • Type mismatches
  • Undefined variables or methods
  • Dead or unreachable code
  • Incorrect method calls

Unlike traditional debuggers, PHPStan doesn’t execute your code — it reads and analyzes your PHP files directly, looking for structural or logical inconsistencies based on static rules.

Why Use PHPStan?

Here are a few reasons to integrate PHPStan into your development workflow:

  • Early bug detection: Spot bugs before running the code.
  • Improved code quality: Enforce strict typing and coding standards.
  • Reduced runtime errors: Catch potential issues during development.
  • Better refactoring: Safely restructure code with confidence.

PHPStan becomes especially powerful when used alongside modern PHP features like type hints, union types, and generics.

Getting Started with PHPStan

Installing PHPStan is very easy. You can install it in your project through composer:

$ composer require --dev phpstan/phpstan

This installs PHPStan as a development dependency.

Running PHPStan

We can now run PHPStan from the base directory of our project. To analyze your code, use the following command:

$ vendor/bin/phpstan analyze src

Replace src with the directory containing your PHP files.

A breakdown of this command:

  • vendor/bin/phpstan is the executable
  • analyze tells PHPStan to analyze all files in the given directories
  • 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.

By default, PHPStan analyzes the code with a conservative level of strictness. However, you can make it more strict using levels from 0 (lenient) to 8 (strictest):

vendor/bin/phpstan analyse src --level=5

Configuration with phpstan.neon

For more control, you can create a phpstan.neon configuration file in your project root:

parameters:
    level: 5
    paths:
        - src
        - app
    ignoreErrors:
        - '#Call to an undefined method.*#'

This allows you to customize which folders to analyze, define rules to ignore, and adjust the strictness level.

Common Issues Caught by PHPStan

PHPStan can detect a wide range of issues:

  • Calling methods or accessing properties that don’t exist.
  • Passing the wrong type of arguments to a function or method.
  • Returning values of the wrong type.
  • Forgetting to return a value in non-void functions.
  • Using undefined variables.

These issues often lead to hard-to-find bugs in production. Catching them early saves time and effort.

Integrating PHPStan into CI

To make PHPStan even more effective, integrate it into your CI/CD pipeline. This ensures code is analyzed automatically on every push or pull request, helping maintain a high standard across your team.

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=5

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

Similarly, in GitHub Actions:

- name: Run PHPStan
  run: vendor/bin/phpstan analyse --level=5

Conclusion

PHPStan is a must-have tool for modern PHP development. It helps you catch bugs early, write cleaner code, and reduce technical debt over time. Whether you’re maintaining a legacy project or starting a new one, integrating PHPStan into your workflow is a smart move.

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.