Posted in Code on August 18th, 2014

An Expanded Laravel Project Structure: The Big Hack

As I mentioned in the initial post on an expanded Laravel project structure, a number of workarounds are required to get there from the default Laravel 4.2.* structure. The one workaround which could aptly be described as a "hack" involves the /sys directory, so we'll begin there.

Laravel Expanded Project Structure

The /sys directory contains the framework bootstrap and configuration files. Unfortunately, Illuminate expects a number of directories (/lang, /config, and /start) as well as the routes.php file to be located in the application path. As a result, the only way to isolate bootstrap and configuration files is to essentially remove everything else from the application path so that only those directories and files remain.

The easiest way to go about this is to first create the /sys directory and then copy over to it the /lang, /config, and /start directories as well as the routes.php file. We also relocate /bootstrap into this newly created directory.

Once we've isolated our bootstrap and configuration within the /sys directory, we modify our index.php file to let Illuminate know where to locate the autoload.php and start.php files:


#index.php

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
*/
    require __DIR__ . '/../sys/bootstrap/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
*/

    $app = require_once __DIR__ . '/../sys/bootstrap/start.php';

Now we need to make similar modifications to the artisan file so we can use the CLI:


#artisan

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
*/
    require __DIR__ . '/sys/bootstrap/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
*/
    $app = require_once __DIR__ . '/sys/bootstrap/start.php';

Next, we need to modify the paths within /sys/bootstrap/autoload.php since the /bootstrap directory is no longer at the top level of our structure:


#autoload.php

/*
|--------------------------------------------------------------------------
| Register The Composer Auto Loader
|--------------------------------------------------------------------------
*/
    require __DIR__ . '/../../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Include The Compiled Class File
|--------------------------------------------------------------------------
*/
    if (file_exists($compiled = __DIR__ . '/compiled.php'))
    {
        require $compiled;
    }

/*
|--------------------------------------------------------------------------
| Register The Workbench Loaders
|--------------------------------------------------------------------------
*/
    if (is_dir($workbench = __DIR__ . '/../../workbench'))
    {
        Illuminate\Workbench\Starter::start($workbench);
    }

Now we make a similar modification to sys/bootstrap/start.php:


#start.php

/*
|--------------------------------------------------------------------------
| Bind Paths
|--------------------------------------------------------------------------
*/
    $app->bindInstallPaths(require __DIR__ . '/paths.php');

Finally, we have to modify the application and base paths in /sys/bootstrap/paths.php. This is the core of the hack - we set the newly created /sys directory as the application path:


#paths.php

/*
|--------------------------------------------------------------------------
| Application Path
|--------------------------------------------------------------------------
*/
    'app' => __DIR__ . '/..',

/*
|--------------------------------------------------------------------------
| Base Path
|--------------------------------------------------------------------------
*/
    'base' => __DIR__ . '/../..',

And that's it in all of it's horrific glory. At this point, the framework will boot and code placed in route closures in the routes.php file will execute.

I'll cover the remainder of the modifications necessary to migrate from the default Laravel 4.2.* directory structure to this expanded structure in a future post, but keep in mind that Laravel 4.3 is only a few months out (and it's going to be awesome!), so this should be viewed primarily as a proof of concept exercise rather than something that I would advise others to use in a real project at this point. If it can influence the direction of 4.3 or it's level of configurability, it'll have been well worth the undertaking.



See Also:
Applies to:
  • Laravel 4.2.*