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

alexpgates's avatar

Where to put one-off scripts?

Greetings! I'm new to Laravel and frameworks in general and I have a question about where in my application to add scripts that would really only need to be used once.

As an example, this evening I wanted to split out a "first name" field between "first name" and "middle name" (since a big chunk of records in my database had middle name part of the first name, separated by a space. (Yes, I know there will be some exceptions here, but lets ignore that for now).

After doing the migration to add the middle name column, I was looking for the best way to update the data in my table. One approach would be just executing a MySQL query, but in this case I wanted to use eloquent and visualize the changes before modifying the records.

I really wasn't sure where to actually add the script to update the record. What I ended up doing was adding a route in routes.php

Route::get('/fix-names', 'StudentsController@update_name');

and a controller method

    public function update_name()
    {
        Student::chunk(200, function ($students) {
            foreach ($students as $student) {
                $first_name =  trim($student->first_name);
                if (strpos($first_name, ' ') !== false) {
                    // okay! we have a space in the first name.
                    echo $first_name.' space detected! --- ';
                    $first_name_array = explode(' ', $first_name);
                    $real_first_name = $first_name_array[0];
                    echo 'so real first name is: '.$real_first_name;
                    $middle_name_array = array_shift($first_name_array);
                    $middle_name = implode(' ', $first_name_array);
                    echo '---- and the middle name is: '.$middle_name.'<br>';
                    $student->first_name = $real_first_name;
                    $student->middle_name = $middle_name;
                    $student->save();
                }
            }
        });
    }

When I finished the update (which worked just fine) I just commented out the route and method.

I can't help but feel gross about the way I handled this (by adding the route and the method to that controller and hitting that URL in my browser). I'm wondering if there's a better approach to these "one-off" types of scripts that may come up from time to time in my projects.

Any feedback would be appreciated!

0 likes
7 replies
jimmck's avatar

@alexpgates I create a bin directory in my Laravel project directory at the same level as my App directory. Then I create scripts that start with this

<?php
use App\MyGlobals;

require dirname(__DIR__) . '/vendor/autoload.php';
require dirname(__DIR__) . '/bootstrap/app.php';

$myGlobals = new MyGlobals();

The MyGlobals class I use for common Stuff in my Laravel apps and scripts.

I call it in App.php and these scripts.

<?php namespace App;

use App\lib\myutils\apputils\mongo\DefaultType;

class MyGlobals
{

    /**
     * MyGlobals constructor.
     */
    static public $APP_ROOT;
    static public $DEFAULTS;

    public function __construct()
    {
        $composer = json_decode(file_get_contents(base_path() . '/composer.json'), true);
        self::$APP_ROOT = array_keys(data_get($composer, 'autoload.psr-4'))[0];
        self::$DEFAULTS = new DefaultType();
    }
}

That way I dont need to create routes for one offs and maintenance stuff.

accent-interactive's avatar

I don't like one-offs to be accessible from the web, so I just create commands for them.

zachleigh's avatar

Are you going to use that for anything other than student names? If the answer is no, Id put it on the Student model. Then you could do something like $student->updateName() and let the student class do it itself.

alexpgates's avatar

Thanks for the feedback!

@jimmck - Interesting. Thanks! I'll need to research this more.. still not sure how you actually execute the script with that setup.

@joostvanveen - An artisan command, yeah? I hadn't considered this. Thanks!

@zachleigh - Interesting. Yes, in this case, it's only for student names so it could live in that model. Would you then just execute this through php artisan tinker ?

jimmck's avatar

@alexpgates I just run from the command line or from inside PHPStorm. Like you I have stuff I want to do, I just don't a route all the time. Or I have PHP daemon I want to start.

davestewart's avatar

I know what you mean about not having commands like this "live", but the URL is so convenient.

I have a "wildcard" routing setup I mainly use as a code playground and allows me to add methods to a controller, then call them in the URL with parameters:

// routes.php
wildcard('test', 'TestController');

// browser
http://localhost/test/foo/1/2/3

I have this wrapped in a check to see if I'm running locally or not, and can simply add new methods as I need to test / run this or that.

Commands, although cool, do require more setup and file management than just adding methods to a controller. The other nicety about running in the browser, is that it's really useful for formatting output, pd()s, etc.

If you want to try that, the code is here: http://laravel-tricks.com/tricks/wildcard-routing-setup

zachleigh's avatar

@alexpgates I suggested the student model because I assumed that you would want to run the script for new sign ups as well. That way you wouldnt have to deal with this again. And then yes, you could run the script for your current database through tinker.

Please or to participate in this conversation.