composer psr-4 autoload with same key - composer-php

i have this setup into composer.json
"autoload": {
"psr-4": {
"": "src/",
"App\\": "src/App"
}
}
with this folder structure:
src
---App
------MyClass.php --> namespace \App;
---Somedir
------Otherdir
---------OtherClass.php --> no namespace
File under src/App folder will be loaded, file under Somedir not.
There is something wrong?

You can use combinations of autoloaders, so adjust your composer.json to use both a PSR-4 autoloader for classes with namespace, and use classmap autoloader for those that do not have namespace:
{
"autoload": {
"classmap": [
"src/SomeDir"
],
"psr-4": {
"App\\": "src/App"
}
}
}
For reference, see https://getcomposer.org/doc/04-schema.md#autoload.
The disadvantage of using a classmap autoloader is that if you add or remove classes in the directories which are loaded via classmap autoloader, the classmap needs to be regenerated:
$ composer dump-autoload

Related

Trying to override the method of laravel passport package by the help autoload psr-4 but does not get expected result

Composer.json
"autoload": {
"exclude-from-classmap": [
"vendor\\laravel\\passport\\src\\Http\\Controllers\\AccessTokenController.php"
],
"psr-4": {
"App\\": "app/",
"Laravel\\Passport\\": "app/Override/" //tried "Passport//" only also
}
},
I have file AccessTokenController.php which lie in vendor\laravel\passport\src\Http\Controllers\ and i create Override folder inside App directory on where i copied that file and make changes in code
And finally when i do :
composer dump-autoload
i get error as :Class Laravel\Passport\Http\Controllers\AccessTokenController located in ./app/Override/AccessTokenController.php does not comply with psr-4 autoloading standard. Skipping.
seems problem with namespace which i couldn't figure out though trying some of the ways ..
Anyone can help me ?
I would simply override the route from within the app as mentioned here. No need for the approach you mentioned above.
However, if you want to keep going this route you can try the following.
"psr-4": {
"App\\": "app/",
}
"exclude-from-classmap": [
"Laravel\\Passport\\Http\\Controllers\\AccessTokenController"
],
"files": [
"app/Override/AccessTokenController.php"
],
I solved it by including complete namespace of AccessTokenController.php.so final code would look like this:
"autoload": {
"exclude-from-classmap": [
"vendor\\laravel\\passport\\src\\Http\\Controllers\\AccessTokenController.php"
],
"psr-4": {
"App\\": "app/",
"Laravel\\Passport\\Http\\Controllers\\":"app/Override/"
}
}

Autoloading of classes of a local TYPO3 extension

In my following composer.json I am requiring extensions, which are in the same Git repository as the whole project. So I add in the repositories section and later I do composer req vendor/site_package:#dev in order to require my local extension.
Now I realized, that some classes of the extension are not autoloaded.
Do I need to additional add the autoload part as shown below in the composer.json of the project?
{
"name": "site-package",
"description": "Base composer.json",
"repositories": [
{
"type": "path",
"url": "./packages/*"
}
],
"require": {
"typo3/cms-backend": "^10.4",
"typo3/cms-belog": "^10.4",
"typo3/cms-beuser": "^10.4",
"typo3/cms-core": "^10.4",
...
"vendor/site_package": "#dev",
"georgringer/news": "^8",
...
},
"autoload": {
"classmap": [
"public/typo3conf/ext/site_package/Classes"
],
"psr-4": {
"Vendor\\SitePackage\\": "public/typo3conf/ext/site_package/Classes"
}
},
"extra": {
"typo3/cms": {
"root-dir": "public",
"web-dir": "public"
}
},
"config": {
"vendor-dir": "vendor",
"bin-dir": "bin"
},
"scripts": {
"typo3-cms-scripts": [
"typo3cms install:generatepackagestates",
"typo3cms install:fixfolderstructure"
],
"post-autoload-dump": [
"#typo3-cms-scripts"
]
}
}
In ext:site_package I have the following autoload section as well:
"autoload": {
"psr-4": {
"Vendor\\SitePackage\\": "Classes",
}
},
Do I need both? Why?
You should never mix those 2 composer.json.
As you already follow the approach of having a directory packages (which is a good thing) each extension inside there needs an own composer.json file which of course also needs a section
"psr-4": {
"Vendor\\MyExt\\": "Classes"
}
By requiring this package, this autoload information will be used.
If you would still have the custom extension inside typo3conf/ext/my_ext, that composer.jsonfile would not be taken into account and you need something like
"psr-4": {
"Vendor\\MyExt\\": "typo3conf/ext/myext/Classes"
}
The autoload part is only needed in your site package composer.json. It's not necessary to put it also in the composer.json in your root folder.
Please refer to the documentation how the composer.json of your site package should look like.
If you still have problems with autoloading, try composer dump-autoload or remove the extension and require it again. And make sure to check the upper-/lowercase of your namespace. It's case sensitive. If you change that after you required the site package, you need to remove and require the package again.

How to change the Modules "Modules" folder name?

I am using Laravel Modules
https://github.com/nWidart/laravel-modules
This is the Folder Structure with Modules.
Is there any way to change it? Like I want to create
Admin\Category
Means my Modules folder name will be Admin
"autoload": {
"psr-4": {
"App\": "app/",
"Modules\": "Admin/",
"Database\Factories\": "database/factories/",
"Database\Seeders\": "database/seeders/"
}
},
I tried with this but not working!
Thanks
Based on documentation of package yes you can.
First step run this command
php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"
Second Step in Config/laravel-modules.php will find ["Modules path","Modules assets path","Default Namespace"] you can customize them
Last Step in composer.json
"autoload": {
"psr-4": {
"App\": "app/",
"Admin\": "Admin/",
"Database\Factories\": "database/factories/",
"Database\Seeders\": "database/seeders/"
}
},
then run composer dump-autoload

Getting autoload to work for repository package

I've tried everything classmap, psr-0, psr-4 but can't seem to get autoload to work for the when using a package from a git repository
{
"repositories": [
{
"type": "package",
"package": {
"name": "michaeljs1990/bitcoin-php-api",
"version": "dev-master",
"source": {
"url": "https://github.com/michaeljs1990/Bitcoin-PHP-API",
"type": "git",
"reference": "master"
},
"autoload": {
"psr-0": {"Bitcoin": "src/Bitcoin"}
}
}
}
],
"require": {
"michaeljs1990/bitcoin-php-api": "dev-master"
}
}
The class is defined in src/Bitcoin directory using namespace Bitcoin but this always fails
<?php
include 'vendor/autoload.php';
$test = new \Bitcoin\Bitcoin($null);
?>
The repository you are referring already has a composer.json file, so there is no need to use type:package for your entry in repositories, it is easier to simply use:
{
"type": "vcs",
"url": "https://github.com/michaeljs1990/Bitcoin-PHP-API"
}
This will use the Composer data directly from that repository, and it will work, because you declare the autoloading wrong:
"autoload": {
"psr-0": {"Bitcoin": "src/Bitcoin"}
},
The original one:
"autoload": {
"psr-0": { "": "src/" }
},
For optimal performance, this should be used:
"autoload": {
"psr-0": { "Bitcoin": "src/" }
},
What's the difference? PSR-0 needs the prefix it should try to search, and the directory from which to start searching for the complete classname converted into a pathname. A class named Bitcoin\Bitcoin will be expected in the relative path Bitcoin/Bitcoin.php.
Your autoloading told Composer that classes with Bitcoin could be found in src/Bitcoin, which is wrong for this class: src/Bitcoin/ + Bitcoin/Bitcoin.php does not exist.
The original autoloading tells Composer that ANY class may be found in src/, which is also wrong for most of them, but true for that Bitcoin class. Even though this works, it will try to search for plenty of other classes inside that directory before searching in different directories, thus wasting disk I/O.
My suggested optimum restricts this directory to classes starting with Bitcoin.

A non-empty PSR-4 prefix must end with a namespace separator

I'm trying to setup PSR-4 with Composer but I'm just getting A non-empty PSR-4 prefix must end with a namespace separator.
My autoload in my composer.json looks like this:
"autoload": {
"psr-4": {
"Acme\\models" : "app/models"
}
},
app/models is empty.
What am I doing wrong? How can I fix this?
Someone made a comment but removed it. He mentioned I was missing \\ at the end of Acme\\models. Acme\\models\\ will get rid of the message and work as it should.
As others said PSR-4 requires the trailing slash
Though I had to convert / to \\ in Windows (should work fine on Linux):
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
A non-empty PSR-4 prefix must end with a namespace separator.
namespace separator means \\
Method-1
Incorrect ⬇️⬇️⬇️
"autoload": {
"psr-4": {
"Acme\\models" : "app/models"
}
},
Correct ⬇️⬇️⬇️
"autoload": {
"psr-4": {
"Acme\\models" : "app/models/"
}
},
Method-2: If this doesn't work try deleting vendor + composer.lock and reinstall dependencies
Method-3: Delete the autoload_psr4.php file in the libraries folder - it probably was created before the update and it had issues before.
Know more about PSR-4: Autoloader

Resources