Composer and his magicians
It is possible yes, but already adding that to do this you must be used to working with the Composer
.
Let’s take the necessary steps:
1 . Add namespaces to each file in the Laravel
. If you don’t want to take risks with your project, I suggest you use a copy to test first (make a new branch on git
, for example).
You must add the namespaces for each folder.
For example:
The files of app/models
will have the namespace App\Models
. And so you will have to do for each folder, which use class, and which you want to add the use of namespaces.
2 . Open your file composer.json
. He’ll probably get a stretch like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
What we will do is the following: All folders where you want to use namespace
, you will remove from this "list" above.
In that case I will remove app/controllers
and app/models
.
"autoload": {
"classmap": [
"app/commands",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
Now, you will add the following snippet to your code
"autoload": {
"classmap": [
"app/commands",
"app/traits",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4": {
"App\\" : "app/",
}
},
After you change your composer.json
, you will now execute a command inside the root folder of your project (the location where the composer.json
).
Execute: composer dump-autoload
or composer dump
.
After that, if you want to do a short test to see if the files have been added to autoload
, just do it like this:
php artisan tinker --env=local
> $model = new App\Models\MeuModel;
If all goes well, the model instance will be displayed on the screen.
Modifying the "Vendor Namespace" of your Project
Short explanation of PSR-4
Note that in the Composer configuration, we add the snippet App\\
.
This is a requirement for Composer to generate autoload for the PSR-4.
In the case, App
is the base namespace (the base name of the namespace), which is part of the standard requirement of the Psr-4.
According to the PSR-4, this is called vendor namespace. That is, it is the first name of the namespace.
Are you confused? So let me give you an example:
namespace VendorNamespace\NomeDoPacote;
class MinhaClasse {}
Therefore, it is not necessary that the vendor namespace is exactly the name of the base folder that we are pointing to to perform autoload. But initially, as an example, come on I did so just so you understand.
Some people don’t like to use App
as vendor namespace, for being very common in some applications.
So if you want to change the name of vendor namespace, no need to change folder name app
- as one might logically think, but it is only necessary to change the definition made in Composer.json.
For example: I don’t want my namespace to be App\Models
, but I want it to be Project\Models
. I mean, I want to change the vendor namespace App
for Project
.
How would I do that?
"psr-4" : {
"Project\\" : "app/",
}
After that, you’ll have to rotate composer dump
again and change vendor namespace of each file .
If I had then a class called Remessa
inside the folders app/models
would have to have that following statement.
#app/models/Remessa.php
namespace Project\Models;
class Remessa extends \Eloquent {}
And the routes?
With the implementation of namespaces in Laravel 4, when you have to use the route definition, things will change a little.
Before it was:
Route::get('/', ['uses' => 'HomeController@getIndex']);
Now it’s:
Route::get('/',[
'uses' => 'App\Controllers\HomeController@getIndex'
]);
I had a similar problem with Yii, in my case (I imagine it is the same) autoload is not done by Poser, but internally by magical methods. So if I have two classes with different signatures, but the same name "Highlight" being instantiated your code will break. That’s why all classes in the framework have prefixes
– rzani
@rzani is one of the things I’ve heard about
Yii
: It has its own class loading management, and it could simply use namespace. I have this solution for theLaravel
, look at my answer below :D– Wallace Maxters
@Wallace, then, that’s not really a problem, from using namespace with vendors without a problem. Remember that Yii (first version) is before namespace in PHP, was a valid solution for the time. The same solution you gave in the answer is also valid for Yii, of course with some adjustments.
– rzani
@rzani this is good. If there was some way to encompass other frameworks as an example, it would be great. But nothing prevents this answer from being linked in the future :D
– Wallace Maxters