PSR-4 Autoloading in Laravel - php

Working on an application that will be used to extend the Chatter package
Issue is, I want to make modifications to the package but don't want to do is directly to the package. Changes won't persist after a composer update.
Now from my understanding extending the package would require me to exclude the specific file from auto-loading and load my own files/directories...
composer.json
I made changes to composer.json to accommodate to Mac/Unix and Windows file path syntax:
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"exclude-from-classmap": [
"vendor/devdojo/chatter/src/Controllers/ChatterDiscussionController.php",
"vendor/devdojo/chatter/src/Models/Discussion.php",
"vendor\\devdojo\\chatter\\src\\Controllers\\ChatterDiscussionController.php",
"vendor\\devdojo\\chatter\\src\\Models\\Discussion.php"
],
"psr-4": {
"App\\": "app/",
"Forum\\": "app/forum"
}
},
folder structure
.
+-- app
| +-- Console
| +-- Exceptions
| +-- Forum
| +-- Chatter
| +-- Controllers
| +-- ChatterDiscussionController.php
| +-- Models
| +-- ...
| +-- Helpers
| +-- Http
| +-- ...
+-- bootstrap
+-- ...
Custom ChatterDiscussionController.php
<?php
namespace Forum\Chatter\Controllers;
use Auth;
use Carbon\Carbon;
use DevDojo\Chatter\Events\ChatterAfterNewDiscussion;
use DevDojo\Chatter\Events\ChatterBeforeNewDiscussion;
use DevDojo\Chatter\Models\Models;
use Event;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as Controller;
use Validator;
use App\User;
class ChatterDiscussionController extends Controller
{...
test
To test this, I placed dd("Custom") in my custom DiscussionController and dd("Original") within the package version of DiscussionController. And as you may already surmise, this continues to hit the package version of the DiscussionController.
The only way I got this to work was to add the specific file to files key within autoload section "files": ["app/Helpers/Chatter.php"] <~~ This is an example. This will be a managing nightmare once I start extending more and more packages. From my understanding this can be accomplished by creating a ServiceProvider, but I am unable to find a suitable example of getting this to work using that method.
Has anyone had this issue before? What was the fix. Any help in the right direction is much appreciated.

Related

PHP class_exists() cannot find a class that truly exists

I am trying to write a CakePHP Authentication plugin and am following and structuring it after this repository: https://github.com/ADmad/cakephp-jwt-auth
I am still at the early stages, trying to get my plugin to load during cakePHPs constructAuthenticate() method. I have narrowed down my issue to this method never finding my class when it calls class_exists()
I have Project structure as follows:
App/
plugins/
src/
Controller/
AppController.php
Model/
vendor/
Admad/
cakephp-jwt-auth/
src/
Auth/
JwtAuthenticate.php
composer.json
nates/
cakephp-total-auth/
src/
Auth/
TotalAuthenticate.php
composer.json
TotalAuthenticate is the class I'm trying to load, and it's namespace as defined in TotalAuthenticate.php is:
namespace nates\TotalAuth\auth;
After some debugging I have found that the Path being passed to classs_exists() is:
nates\TotalAuth\Auth\TotalAuthenticate
I have compared all of this info to the Admad/JwtAuth plugin and the relative paths all match up, and that plugin loads just fine so I'm really at a loss at whats going on here and why my plugin won't load.
My Autoload in App/composer.json Looks as such:
`"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Test\\": "tests/",
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/"
}
},`
And my Plugins composer.json :
`"autoload": {
"psr-4": {
"nates\\TotalAuth\\": "src"
}
},
"autoload-dev": {
"psr-4": {
// "ADmad\\JwtAuth\\Test\\": "tests"
}`
PSR-4 autoloading standard requires that the namespace matches the file structure case-sensitive. You define your namespace in composer.json with capitals nates\TotalAuth, but in your class as nates\totalauth\....
Make sure all casings match and the casings match the file structure.

Class not found after auto loading in Laravel

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/"
}

Class not found with Composer autoload and PSR-0

I'm trying to use PSR-0 instead of classmap in composer but having some difficulty. It appears that my json file is correct yet the class I'm trying to access is not being picked up. Can someone please have a look and see if they can spot where I'm going wrong:
Here is what I have in composer.json:
"autoload": {
"psr-0": {
"MartynBiz\\Slim3Controller\\": "src/"
}
},
Below is my folder structure:
$ tree .
.
|-- README.md
|-- composer.json
|-- composer.lock
|-- phpunit.xml
|-- src
| |-- Controller.php
| |-- Http
| | |-- Request.php
| | `-- Response.php
| `-- Test
| `-- PHPUnit
| `-- TestCase.php
`-- tests
|-- bootstrap.php
`-- library
`-- ControllerTest.php
Here is my Controller class:
<?php
namespace MartynBiz\Slim3Controller;
abstract class Controller
{
Also, I can confirm that composer autoload script has been included.
Use PSR-4 instead. PSR-0 requires the prefix to be included in the document tree (i.e. src/MartynBiz/Slim3Controller/Controller.php).

Laravel 5.1 Namespace for Controller give Reflection Exception

Good Afternoon, I donĀ“t understand this exception
ReflectionException in Container.php line 737: Class app\Http\Controllers\Login\LoginController does not exist
I know thats is related with the namespace but i configured my composer.json autoload. When i changed it to app\Http\Controllers\Login it works ok.
I also did artisan clear-compiled and composer dump-autoload
My Class is like this
<?php
namespace Login;
use Controller;
use Validator;
use Input;
use Auth;
use Redirect;
use View;
class LoginController extends Controller{}
My composer.json autoload
"autoload": {
"classmap":
[ "app/Http/Controllers" , "app/Models" , "database" ],
"psr-4": {
"app\\": "app/"
}
},
My Controllers Directory is like this
- app
-- Http
--- Controllers
---- Login
----- LoginController.php
-- Models
--- User
---- User.php
Thanks in advance
Edit: Why i don't have problems with my model files when i use a namespace like this:
namespace User;
In my config auth i have this:
'model' => User\User:class,
Your controller is in Login namespace, while it should be in app\Http\Controllers\Login namespace.
No entries in composer.json can change the way PHP's namespaces work - the mapping in there can just be used to tell autoloader where to look for physical files from given namespace.

namespace defined in autoload psr-4 using in laravel 5 app.php giving not found error

stucked my heads in some errors.i dont getting where i have done my mistake.
I am using laravel 5 and installed it.I want to use l5-repository so i installed https://github.com/prettus/l5-repository this repository using composer commnad:
composer require prettus/l5-repository
and i made all changes as per installation document and its working fine.
after installing repository using composer my directory structure is as below:
curovis
|-- composer.json
|-- composer.lock
|-- app
|-- bootstarp
|-- config
|-- database
`-- vendor
|-- composer
`-- prettus
`-- l5-repository
|-- src
| `-- Prettus
| `-- Repository
`-- composer.json
after this as per doc i have made following entry in /var/www/curovis/config/app.php:
Prettus\Repository\Providers\RepositoryServiceProvider::class,
and its working fine.
Now i want to change composer.json of root directory entry as following:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Prettus\\Repository\\": "vendor/prettus/l5-repository/src/Prettus"
}
},
and use composer update command. it also works fine.
now i want use same repo with another name so i have change composer.json with follwing:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"RepoTest\\Repository\\": "vendor/repotest/l5-repository/src/RepoTest"
}
},
and add RepoTest\Repository\Providers\RepositoryServiceProvider::class, in app.php file.run composer update command. then it gives following error:
FatalErrorException in /var/www/curovis/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php line 146: Class 'RepoTest\Repository\Providers\RepositoryServiceProvider' not found
i cant understand why laravel is looking for /var/www/curovis/vendor/laravel/framework/src this path instead of provided as "RepoTest\\Repository\\": "vendor/repotest/l5-repository/src/RepoTest" in composer.json.
is anything i am missing or any error in composer.
Thanks for help.
You NEVER add autoloading for the packages you added inside your main composer.json. The path "vendor" should never appear there.
I recognize you are trying to add a package, then modify it and use that instead. You changed the autoloading prefix from "Prettus" to "RepoTest", but did you also change the namespace in the PHP files? Simply renaming the path does not affect the PHP class names and namespaces, so if you rename a file, and inside that file there is no matching class defined, autoloading will fail.
Whatever it is you are trying to do, I think it is a good idea to ask about that instead of asking to fix problems you think are necessary because of the way you do solve your original problem. If you want to know how to modify an existing project and use your variant of it: Ask about it.
sovled above error by changing composer entry:
when i have see autoload_classmap.php and autoload_psr4.php files of /vendor/composer/ folder autoload_classmap.php file does not contain namespace that i require.
so i have made following change in my composer.json:
"autoload": {
"classmap": [
"database","vendor/repotest/src/Repotest/Repository/"
],
"psr-4": {
"App\\": "app/",
"Repotest\\Repository\\": "vendor/repotest/src/Repotest/Repository/"
}
},
so by making entry in "classmap": make entry in autoload_classmap.php and working fine now.
Thanks #sven for your help.
Example:
"autoload": {
"classmap": [
"database"
],
"files": [
"app/helper.php"
],
"psr-4": {
"App\\": "app/"
}
}
Default Composer file to load.

Categories