shan / artisan-refactor
Rename PHP classes in Laravel and automatically update all references across the project.
Requires
- php: ^8.1
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- nikic/php-parser: ^5.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- pestphp/pest: ^2.0|^3.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0
This package is not auto-updated.
Last update: 2026-05-21 15:53:09 UTC
README
Rename or move PHP classes in your Laravel project and automatically update every reference across PHP files, Blade templates, routes, config files, and service providers.
Installation
composer require shan/artisan-refactor --dev
Laravel auto-discovers the service provider. Optionally publish the config:
php artisan vendor:publish --tag=laravel-refactor-config
Usage
Rename a class
php artisan refactor:rename "App\Models\User" "App\Models\Member"
Move a class to a new namespace
php artisan refactor:move "App\Models\User" "App\Domain\Users\User"
Preview changes without applying (dry-run)
php artisan refactor:rename "App\Models\User" "App\Models\Member" --dry-run
Undo the last operation
php artisan refactor:rename "App\Models\User" "App\Models\Member" --rollback
Override a naming conflict
php artisan refactor:rename "App\Models\User" "App\Models\Member" --force
What gets updated
| Reference type | Example |
|---|---|
use statements |
use App\Models\User; |
new instantiations |
new User() |
extends / implements |
class Admin extends User |
| Type hints & return types | function store(User $user): User |
| Static calls | User::find(1) |
::class constant |
User::class |
| Service provider bindings | $app->bind(User::class, ...) |
| Route controllers | [UserController::class, 'index'] |
Blade @inject |
@inject('u', 'App\Models\User') |
| Quoted FQCN strings in Blade | 'App\Models\User' |
Configuration
// config/laravel-refactor.php return [ 'scan_paths' => [ 'app', 'routes', 'config', 'resources/views', 'database', 'tests', ], 'excluded_paths' => [ 'vendor', 'node_modules', 'storage', 'bootstrap/cache', ], 'backup_path' => 'storage/app/refactor-backups', ];
How it works
- Validates that the source class exists via PSR-4 mappings in
composer.json - Detects conflicts — errors out if the target class already exists
- Scans all configured paths using an AST parser (nikic/php-parser) for PHP files and regex for Blade templates
- Snapshots all affected files for rollback
- Updates all references in-place
- Renames/moves the source file and updates its
namespace/classdeclaration - Runs
composer dump-autoloadautomatically
Error: class already exists
ERROR: Class App\Models\Member already exists at app/Models/Member.php
Rename aborted. Use --force to override (dangerous).
Testing locally before publishing
You can test the package against a real Laravel project before pushing to Packagist.
1. Create a fresh Laravel project (or use an existing one)
composer create-project laravel/laravel my-test-app
cd my-test-app
2. Point Composer at your local package
Add a path repository to composer.json in the Laravel project:
{
"repositories": [
{
"type": "path",
"url": "../laravel-refactor"
}
]
}
The url is the path from the Laravel project to the package directory — adjust it to match your folder layout.
3. Install the package
composer require shan/artisan-refactor:@dev --dev
Composer creates a symlink to your local package. Any change you make in laravel-refactor/src/ is immediately reflected — no need to reinstall.
4. Create test fixtures
Create a few classes and references to exercise the different scenarios:
# Source class php artisan make:model User # A class that references it php artisan make:controller UserController
Open app/Http/Controllers/UserController.php and add a reference:
use App\Models\User; class UserController extends Controller { public function index(): User { return new User(); } }
Optionally add a Blade template:
echo "@inject('user', 'App\Models\User')" > resources/views/users/show.blade.php
5. Run through the checklist
Dry-run first — never skip this step:
php artisan refactor:rename "App\Models\User" "App\Models\Member" --dry-run
Expected output: a list of every file and line that would change. No files are modified.
Apply the rename:
php artisan refactor:rename "App\Models\User" "App\Models\Member"
Check that:
app/Models/User.phpno longer existsapp/Models/Member.phpexists withclass Memberandnamespace App\Modelsapp/Http/Controllers/UserController.phpnow hasuse App\Models\MemberandMembereverywhereresources/views/users/show.blade.phpreferencesApp\Models\Membercomposer dump-autoloadran automatically (verify withphp artisan tinker→App\Models\Member::class)
Roll back:
php artisan refactor:rename "App\Models\User" "App\Models\Member" --rollback
Check that all files are back to their original state.
Move (namespace change):
php artisan refactor:move "App\Models\Member" "App\Domain\Users\Member"
Check that:
app/Domain/Users/Member.phpexists (directory was created)namespace App\Domain\Users;is in the fileapp/Http/Controllers/UserController.phpimportsuse App\Domain\Users\Member
Conflict detection:
php artisan refactor:rename "App\Models\Post" "App\Models\Member"
Expected: an error saying Member already exists. Then:
php artisan refactor:rename "App\Models\Post" "App\Models\Member" --force
Publish and customise config:
php artisan vendor:publish --tag=laravel-refactor-config
Open config/laravel-refactor.php and add a path to scan_paths (e.g. 'src'). Re-run a dry-run to confirm the new path is scanned.
6. Run the package's own test suite
Back in the laravel-refactor directory:
./vendor/bin/pest --no-coverage
All 79 tests should be green before publishing.
Requirements
- PHP 8.1+
- Laravel 10, 11, 12, or 13
License
MIT