Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ligonsker's avatar

Is there an easy way to convert the Routes from the old string syntax to the newer callable syntax?

Hello,

There are many routes in web.php. Is there an easy way to convert them all to the callable syntax:

https://laravel.com/docs/8.x/upgrade#routing

(Upgraded Laravel version)

thanks

0 likes
8 replies
LaryAI's avatar
Level 58

Yes, there is an easy way to convert the routes from the old string syntax to the newer callable syntax. You can use the Route::getRoutes() method to get all the routes defined in your application, and then loop through them to update the syntax.

Here's an example of how you can do it:

use Illuminate\Support\Facades\Route;

$routes = Route::getRoutes();

foreach ($routes as $route) {
    $action = $route->getAction();

    if (isset($action['uses'])) {
        $action['uses'] = str_replace('@', '::', $action['uses']);
        $route->setAction($action);
    }
}

This code will loop through all the routes and update the uses key in the action array to use the new callable syntax. It does this by replacing the @ symbol with ::.

Note that this code assumes that all your controllers are in the App\Http\Controllers namespace. If your controllers are in a different namespace, you'll need to update the code accordingly.

Once you've run this code, all your routes should be updated to use the new callable syntax.

Ligonsker's avatar

@LaryAI Doesn't work, I get this error:

str_replace(): Argument #3 ($subject) must be of type array|string, Closure given

dacfabre's avatar

@Ligonsker i think larry's answer is what you need, for your error. you might want to check your routes if there are closures like:

Route::get('/', function () {
    return Inertia::render('welcome');
});
Ligonsker's avatar

@tykus It's a bureaucratic organization, things like Shift are hard things to get šŸ˜…

YuvrajTimalsina's avatar

METHOD I :

You may use a script or a seeder to convert your routes from the old string syntax to the newer callable syntax :

<?php

use Illuminate\Support\Facades\Route;

$routes = Route::getRoutes();

foreach ($routes as $route) {
    $action = $route->getAction();

    if (isset($action['controller'])) {
        [$controller, $method] = explode('@', $action['controller']);
        $route->setAction([
            'uses' => [$controller, $method],
        ]);
    }
}

Route::save();

You can save this script as a PHP file and run it from the command line using the php command :

php convert-routes.php

METHOD II :

Or, you may use database seeder to achieve the same :

<?php

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Route;

class ConvertRoutesSeeder extends Seeder
{
    public function run()
    {
        $routes = Route::getRoutes();

        foreach ($routes as $route) {
            $action = $route->getAction();

            if (isset($action['controller'])) {
                [$controller, $method] = explode('@', $action['controller']);
                $route->setAction([
                    'uses' => [$controller, $method],
                ]);
            }
        }

        Route::save();
    }
}

To use this seeder, save it to a file named ConvertRoutesSeeder.php in the database/seeds directory of your Laravel project. Then, add it to the DatabaseSeeder class's run() method like this:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(ConvertRoutesSeeder::class);
    }
}

Don't forget to run the seeder:

php artisan db:seed --class=ConvertRoutesSeeder
1 like
jlrdw's avatar

Just adjust RouteServiceProvider.php and use as is.

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{

    /**
     * The path to the "home" route for your application.
     *
     * Typically, users are redirected here after authentication.
     *
     * @var string
     */
    public const HOME = '/home';

    protected $namespace = 'App\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, and other route configuration.
     */
    public function boot(): void
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('api')
                    ->prefix('api')
                    ->group(base_path('routes/api.php'));

            Route::middleware('web')
                    ->namespace($this->namespace)
                    ->group(base_path('routes/web.php'));
        });
    }

    /**
     * Configure the rate limiters for the application.
     */
    protected function configureRateLimiting(): void
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }

}

1 like
Ligonsker's avatar

thanks everyone, I ended up using Rector: https://github.com/rectorphp/rector with the extension package for Laravel: https://github.com/driftingly/rector-laravel

Has anyone heard of it? I heard about it today for the first time (both Rector and the extension package).

I ran it and it updated the entire web.php to the new syntax quickly after setting up a config file and running the script.

Just in case, I copied the entire project, installed the extensions there and ran it, then copied the web.php back to the original project

Please or to participate in this conversation.