phplaravelrefactoring

How to use Laravel routes as fallback when physical file does not exist


I want to migrate a very old-fashioned PHP app gradually to Laravel. The application does not yet use a general entry point, but uses direct file URLs to work. So, in order to gradually move over functionality, I would like to check first in my routes whether the url exists as a physical file on the server. If that is the case, execute that file. If not, go through the laravel routes.

I have been looking into both the excellent 'Legacy to Laravel' blogpost by Tighten and an older article on PHPArch 'Migrating Legacy Web apps to Laravel'. They both assume there is one front-end controller, which isn't the case in my application.

What would be the cleanest way of implementing this in Laravel 11?


Solution

  • This should be trivially simple. If you're using Apache, you probably don't have to do anything special, Laravel should already work this way. In Laravel's /public dir, you'll get an .htaccess file that contains something like this:

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    

    Note the conditions. If the requested filename isn't a directory and and isn't a file, then redirect to the front controller. I.e., if the requested filename already exists, Apache will just serve it as is, and you'll completely bypass Laravel. The only thing you might need to do is adjust the name of one of the index files. You probably already have index.php for your legacy site, but Laravel is going to want to use it. So, you could keep your existing legacy index.php, rename Laravel's index.php to laravel.php and then change the .htaccess:

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ laravel.php [L]
    

    In nginx, it might look something like this:

    location / {
        try_files $uri $uri/ /laravel.php?$args;
    }
    

    So: