Laravel 5 gives us a nifty little command to change our application’s namespace. Out of the box the default namespace is App
. To change it, we simply run:
php artisan app:name Horsefly
However, once you register your app namespace, how do you get it later? Laravel doesn’t save it in config(‘app.name’) or anything like that.
I had this question come up at work, so I searched for an example. After a few minutes of searching the Laravel source code, specifically Illuminate \ Foundation \ Console \ AppNameCommand.php. There I discovered a trait called AppNamespaceDetectorTrait.
Speaking of traits, did you know you can find a list of all the laravel traits here? http://laravel.com/api/5.0/traits.html
By examining the AppNamespaceDetectorTrait we can find out exactly how it works.
{% codeblock https://github.com/laravel/framework/blob/5.0/src/Illuminate/Console/AppNamespaceDetectorTrait.php AppNamespaceDetectorTrait %} trait AppNamespaceDetectorTrait {
/**
* Get the application namespace from the Composer file.
*
* @return string
*
* @throws \RuntimeException
*/
protected function getAppNamespace()
{
$composer = json_decode(file_get_contents(base_path().'/composer.json'), true);
foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path)
{
foreach ((array) $path as $pathChoice)
{
if (realpath(app_path()) == realpath(base_path().'/'.$pathChoice)) return $namespace;
}
}
throw new RuntimeException("Unable to detect application namespace.");
}
} {% endcodeblock %}
From the looks of it, this script loops through the psr-4 namespaces in our project’s composer.json. We can use this trait but I’d personally rather copy and paste the code into a new class. I mean, this trait isn’t doing anything special that we can’t do ourselves. Plus, having it in our class allows us to get a little more flexible with this concept Taylor has provided in his code. The concept is, we can search the composer.json for certain namespaces in our application. There is nothing keeping us from adding additional namespaces to composer.json and searching those.
class NamespaceDetector
{
public function getAppNamespace()
{
return $this->getNamespaceForPath(app_path());
}
protected function getNamespaceForPath()
{
$composer = json_decode(file_get_contents(base_path().'/composer.json'), true);
foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path)
{
foreach ((array) $path as $pathChoice)
{
if (realpath($searchForPath) == realpath(base_path().'/'.$pathChoice)) return $namespace;
}
}
throw new \RuntimeException("Unable to detect application namespace.");
}
}
Now to fetch the application namespace we just use the namespace detector.
$detect = new NamespaceDetector;
$detect->getAppNamespace(); // 'Horsefly'
This begs the question. Why would you need to ever get the app namespace? I mean… the developer set that. So he/she should already know the namespace, right? If you are working in package development or multiple cms applications, a need might arise for it though. One of our developers at work had a need for this. Glad Taylor has got our back. Everytime I look behind the curtains of Laravel source, I find nothing but clean expressive & understable code.