I am struggling with PHP Namespaces and Auto loading in Laravel 5.4. I actually decided to put the models that I need to use in a definite and named folder as app/Models:
php artisan make:model Models/Customer
I have set Customer model's namespace to namespace Models;
Then, I created a route as follows:
Route::get('customer', function () {
$customer = \App\Models\Cutomer::find(1);
echo $customer;
});
To do auto loading work I opened the composer.json file located in the very root folder of the Laravel project and made the autoload to be as follows:
"autoload": {
"classmap": [
"database",
"app/Models"
],
"psr-4": {
"App\\": "app/",
"App\\Models\\": "App/Models"
}
},
After all of this I checked if my composer is an update version and ran dump-autoload:
composer self-update
composer dump-autoload -o
There is also worth of notice the contents of vendor/composer/autoload_classmap.php:
'App\\Models\\Customer' => $baseDir . '/app/Models/Customer.php',
'App\\Models\\Test\\Test' => $baseDir . '/app/Models/Test.php',
My problem is that whenever I execute the url: http://127.0.0.1:8000/customer I will encounter the following error output:
(1/1) FatalThrowableError
Class 'App\Models\Cutomer' not found
Would you please help me understand where of my work has been incorrect, and how to fix it? Thank you very much in advance.
The namespace in the model should be namespace App\Model; (hence why you call the class as \App\Models\Cutomer)
When you use php artisan make:model Models/Customer it should have set the namespace correctly then.
Also, you don't need to edit your composer.json to do this. Remove the additions you've made to your composer.json file for the autoloading and then run composer dumpautoload from the command line.
Hope this helps!
First, you have an error in your PSR-4 setup.
"App\\Models\\": "App/Models"
This does not map to a valid directory. Secondly, and more importantly, there is no need to autoload a nested namespace of one that is already declared. By autoloading App you will already autoload any nested namespaces as long as they conform to PSR-4 standards i.e namespace as directory name and filename as class name.
Composer setup only needs to be the following:
"psr-4": {
"App\\": "app/"
}
Related
I can't change the namespace of my application in Laravel 5.8.
I'm using artisan to change it:
php artisan app:name TestApp
Result is: There are no commands defined in the "app" namespace.
Looking at php artisan you should have a php artisan app:name NewNamespace
command to change the namespace. Make sure that you are on the latest laravel version.
Old answer
To change the namespace of your app you have to edit the composer.json file:
"autoload": {
"psr-4": {
"CustomNamespace\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
but you also have to edit each file in the app subfolders and in the various configurations files (for example in config/app.php, config/auth.php, etc).
After you have done all of that you can run: composer dump-autoload
Keep in mind that this is an error prone method, because if you forget to replace a namespace in any of your files anything can stop working as expected.
Another option would be to create a custom package with the name you want and register it with a custom namespace. For example:
Create a lib/yourpackage/src folder in the root of laravel installation
Edit the composer.json file to load your custom code:
"autoload": {
"psr-4": {
"App\\": "app/",
"CustomNamespace\\": "lib/yourpackage/src/",
},
"classmap": [
"database/seeds",
"database/factories"
]
},
Run composer dump-autoload as before
You can now use anywhere your files in your project by referring to the custom namespace you have choosen.
laravel change this command to app:namespace
you have to do this
php artisan app:namespace TestApp
Are you trying to change the namespace of your application or just the name ?
What do you want to change exactly in the namespace ?
EDIT
I think you must have touched something in your application because the command php artisan app:name AppName should work, I just tested it.
Have you ever tried before to change the namespace by yourself?
Otherwise, try composer dump-autoload before to make sure your autoloading is up to date.
This feature has been removed as of Laravel 6. It's not recommended to change the namespace.
However if you want to do it, you can add the command to your Console/Commands directory
https://gist.github.com/isluewell/b824c0aef32f5007170fcd0d8498b657
I am having very hard times understanding how to use autoloading by psr-4.After loading vagrant and setting and testing all variables in Homestead.yaml I have prepared a file structure as the following:
\app
\folder
-- test.php
\vendor
\composer
-- autoload.php
-- index.php
-- composer.json
and the following are my codes:
index.php
<?PHP
namespace app;
require('vendor/autoload.php');
$object = new folder\test();
composer.json
"autoload":{
"psr-4":{
"app\\": "app"
}
}
test.php
<?php
namespace app\folder;
class test
{
function __construct ()
{
echo 'construction done right.';
}
}
But, after trying to visit the page, these are the error message displayed on the page:
(!) Fatal error: Uncaught Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6
( ! ) Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6
Would you help me understand and fix this error?
It doesn't work because you have told Composer that the classes from the app namespace are in the app subdirectory but there is no app subdirectory.
The entire application is stored in the app directory and it's name doesn't really matter for the application. The classes of the app namespace are stored in the current directory and the sub-namespaces are stored in subdirectories with the same name.
Accordingly, your composer.json file should read:
"autoload": {
"psr-4": {
"app\\": ""
}
}
Or, to be more clear, you can put . (the current directory) as the location of the app\ namespace:
"autoload": {
"psr-4": {
"app\\": "."
}
}
After you make the change run composer dump-autoloader in the main application directory and it will start working.
To fix it for your current setup, use the following:
"autoload":{
"psr-4":{
"app\\": ""
}
}
Your composer.json is in the app-directory, so there's no subdirectory named app to reference.
I would actually recommend to change your directory structure to the following:
\app
\src
\folder
-- test.php
-- index.php
\vendor
\composer
-- autoload.php
-- index.php
-- composer.json
And then in composer.json, set the following:
"autoload":{
"psr-4":{
"app\\": "src"
}
}
This makes sure that all files belonging to your 'app' namespace are contained within a single subdirectory.
Finally, I would recommend you to use a vendor namespace to prevent conflicts, and to use the naming guidelines from PSR-2.
I think you won't need PSR-4 just add classmap
classmap parameter for example :
"autoload": {
"classmap": [
"app"
]
}
After adding this run composer dump-autoload and you should see a number of classes being added.
Hope this helps.
in composer.json try to set
"autoload":{
"psr-4":{
"": "src/"
}
}
then do execute this command
composer dump-autoload -o
I've been testing getting my packages up to Packagist with a simple class I made. Whenever I require it in a different project, it says the class cannot be found. Is something wrong with my composer.json autoload block?
Here's my project repo file structure:
- src
- prodikl
- View.php
- .gitignore
- composer.json
And here's my composer.json:
{
"name":"prodikl/simple-view",
"description":"A simple to use, basic View object.",
"require" : {
"php" : ">=5.3.0"
},
"autoload": {
"psr-4": {"prodikl": "src/"}
}
}
And finally, in my View.php:
<?php
namespace prodikl;
class View
{
...
}
But whenever I require it into a project and do require "vendor/autoload.php" and use use prodikl\View; it it keeps saying not found
You just need to point your autoloader down one more directory:
"autoload": {
"psr-4": {"prodikl": "src/prodikl/"}
}
This means "classes that belong to the \prodikl namespace can be found in the src/prodikl/ directory."
You might need trailing backslashes on the namespace name too, not sure how picky Composer is about it:
"psr-4": {"prodikl\\": "src/prodikl/"}
I have the following error while trying to run my controller
Controller class not found
I have this code in my routes.php file
Route::get('cms/create-page', 'AdminCMSController#create_page');
Route::post('cms/createpage','AdminCMSController#createpage');
Route::controller('cms','AdminCMSController');
And this is the code in my Controller
class AdminCMSController extends BaseController {
public function create_page() {
}
public function createpage() {
}
}
How can I fix it?
If you didn't move the controllers directory from the original location (which is «project_root»/app/controllers/, you must guarantee that:
Laravel's autoload has the controller directory. Navigate to «project_root»/app/start/global.php. You need to have something like this:
(...)
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
));
(...)
Take notice to this line app_path().'/controllers'. It must exist.
Also, open your composer.json file and verify that the following lines exist:
(...)
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
(...)
Make sure that you have the line with app/controllers
If you have this lines and you still get the same message, go to your project root and run the following command from the command-line composer dumpautoload -o.
Laravel works with Composer, which is a dependency management tool for PHP. It also prepares an autoload file for all your project classes (see composer docs). When you run the composer dumpautoload command, it will create some files within «project_root»/vendor/composer.
Make sure that you can find the class AdminCMSController in the file «project_root»/vendor/composer/autoload_classmap.php. You should see something like this:
'AdminCMSController' => $baseDir . '/app/controllers/AdminCMSController.php',
If you have changed the default location of your controllers directory, you have to do either one of the following steps. However, since you are not defining a namespace in your class, it doesnt seem likely that this is your problem:
Use PSR-0 for autoloading classes. Imagine that you have the following folder structure:
/app
/commands
/config
/database
/Acme
/controllers
You have to specify the Acme folder in your composer.json, like this:
"autoload": {
"classmap": [
"app/commands",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-0": {
"Acme": "app/"
}
},
After this you need to update you composer autoload files with the command composer dumpautoload.
If you do not want to use the PSR-0 for autoloading, you need to change your routes file from this
Route::controller('cms','AdminCMSController');
to this:
Route::controller('cms','Acme\controllers\AdminCMSController');
IF you use PSR-0, you need to namespace your classes like this:
<?php namespace Acme\controllers;
class AdminCMSController extends BaseController {
(...)
}
Curious about the Acme reference? I was too. Refer to the wikipedia.
I'm trying for a while to import an own bundle via composer but I got a few problems. I got following bundle:
<?php
namespace Platform\Bundle\PollBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class PlatformPollBundle extends Bundle
{
}
The bundle is in vendor/platform/pollbundle/.
In the "main" composer.json I definied the namespace for autoloading:
"autoload": {
"psr-0": {
"": "src/" ,
"Platform\\": "vendor/platform"
}
},
and in the composer.json from the bundle I definied:
{
"name" : "platform/pollbundle",
"type": "symfony-bundle",
"extra": {
"servicePath": ""
},
"autoload": {
"psr-0": {
"Platform\\Bundle\\PollBundle": ""
}
},
"target-dir": "pollbundle"
}
In the autoload_namespaces there is correctly following line:
'Platform\\' => array($vendorDir . '/platform'),
But I got the error:
Fatal error: Class 'Platform\Bundle\PollBundle\PlatformPollBundle' not found in ........Controller.php on line 13
I tried about 100 solutions but nothing works. Would be great if somebody can help me.
Bundles aren't loaded by composer, but instead are handled by the Symfony kernel itself. In the app directory, edit AppKernel.php like this:
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
...,
new Platform\Bundle\PollBundle\PlatformPollBundle()//<-- add this
);
}
In the app/autoload.php file, meanwhile, register the new namesepace. It used to be done through the $loader instance, by calling $loader->registerNameSpaces(), but now, you have to call a static method on the AnnotationRegistry class:
AnnotationRegistry::registerAutoloadNamespace('PollBundle', 'path/to/PollBundle');
A hacky fix I suggested, which is apparently what fixed it for you, would be to run php app/console generate:bundle in the console, to generate a new bundle with the same name, and then simply replace that bundle's directory (in src/) with your bundle.
It is wrong to define ANY autoloading in the main application for anything pointing into the vendor folder! That's what composer is for. Composer will read the autoload declaration for every package contained in there and add the appropriate autoloading automatically. There is no need to add this yourself.
And even if you have to use software that didn't yet add a composer.json file, the autoloading of only that package should go into the package definition block, not into the autoload definition.