Why does 'composer dumpautoload -o' fix 'Class not found' PHP error? - php

I have a Laravel 5.8 project that is dependent on a private package.
When I run composer install the package is installed and shows up in the vendor folder.
project composer.json
{
...
"require": {
"php": ">=7.0",
"company/api-request": ">=1.0.0"
}
...
}
package src/ApiRequest.php
<?php
namespace Company;
class APIRequest
{
...
}
package composer.json
{
...
"autoload": {
"psr-4": {
"Company\\": "src/"
}
}
...
}
When I call the package
\Company\APIRequest::run();
I am getting
Message: Class 'Company\APIRequest' not found
I know the PHP syntax is correct because when I run composer dumpautoload -o the error is gone, but why is it necessary?
I expect composer install or composer update should be sufficient; I have no problem with external packages.
Am I missing anything here?

If the class name and file name don't match, that would cause the auto-loading to not work since that is a requirement with PSR-4. From the docs:
The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.
If that's the case, composer dumpautoload -o is probably working around this for you, see this Reddit post:
The reason -o works, is Composer creates a giant associative array where classname = filename

Related

Composer complains about non-compliance to PSR-4, even though everything seems fine

In my project, I'm including a package I'm developing, which has a composer.json, which includes the following autoload entry:
(censored to not get in trouble with my company of course)
{
"autoload": {
"psr-4": {
"Vendor\\Package\\": "src/Package"
}
}
}
The main project and the package both have a composer.json, this is from the package's composer.json
I have also seen some examples that only used "Vendor\\", but this resulted in the exact same issue.
I am requiring the package on version tag (from a git repository), so it should get and install the package correctly.
Any time composer runs autoload, it complains the namespaces don't conform to PSR-4. I have checked the capitalisation, which all checks out. It complains about pretty much every php file in my project. Here's an example of the file structure:
vendor
|- package
|- src
|- Package
|- PackageServiceProvider.php
The namespace of PackageServiceProvider.php is Vendor\Package, and the class is PackageServiceProvider.
As far as I know, this is how it's supposed to be. Yet composer still gives the deprecation notice.
I should probably mention that I have also tried running composer clearcache between all of the things I've tried (which are mainly changing capitalisation), which didn't help.
I am completely out of ideas on how to fix this.
I'm on composer version 1.10.13, and Laravel version 5.8.38.
One of the many deprecation notices I'm getting:
Deprecation Notice: Class Vendor\Package\PackageServiceProvider located in D:/wwwroot/project/vendor/{package-vendor}/package/src/Package\PackageServiceProvider.php does not comply with psr-4 autoloading standard. It will not autoload anymore in Composer v2.0. in phar://C:/Users/me/AppData/Local/ComposerSetup/bin/composer.phar/src/Composer/Autoload/ClassMapGenerator.php:201
As it turns out, the version of the package that's on our git repository, had a mistake in its composer.json which I'd long fixed locally. But since it wasn't fixed on the repo, composer had never finished updating the dependencies, and hadn't updated its links to the packages.
All I had to do was change
{
"autoload": {
"psr-4": {
"Vendor\\": "src/Package"
},
}
}
to
{
"autoload": {
"psr-4": {
"Vendor\\Package\\": "src/Package"
},
}
}
and push it to the repository.
That's wrong approach. That package, which apparently you manually planted in your vendor/ folder (which is, let's say, moderately OK) should be valid composer package with own composer.json file. Then ordinary composer dumpautoload would perfectly suffice to build class map for autoloading. No oddities like yours needed.

Error in composer.json file after installing module

I have run the command to run composer require phpmailer/phpmailer which created a file composer.json and composer.lock, however, the first one shows an error in the opening bracket { and says "Missing property name, missing property description". Why doesn't add those properties automatically or how to add them in a proper way so I don't cause any other issue?
{
"require": {
"phpmailer/phpmailer": "^6.1"
}
}

Composer require-dev requireing dependencies in different packages require-dev

I have some tests that are namespaced being autoloaded in package A using
"autoload-dev": {
"psr-4": {
"Vendor\\PackageA\\PhpUnit\\": "tests/PhpUnit"
}
},
This works fine.
I have another package, package B which also have namespaced tests that require one of the namespaced tests in package A
"autoload-dev": {
"psr-4": {
"Vendor\\PackageB\\PhpUnit\\": "tests/PhpUnit"
}
},
However, when I try and include the file in Package B, the class is not found
use Vendor\PackageA\PhpUnit\MyTestFromA;
class MyTestFromB extends MyTestFromA
{
Making me think that the autoload-dev stuff from other packages is not being loaded.
PHP Fatal error: Class 'Vendor\PackageA\PhpUnit\MyTestFromA' not found in /full/path/to/PackageBClass.php on line 3
When I try and import a file that is being autoloaded using autoload from package B rather than autoload-dev, I get no error.
How can I overcome this?
Part of me is thinking to make a package just for the tests and have it autoloaded in both without autoload-dev but I want to confirm first.
Solution: Composer autoload-dev does not work.
Take a look at the docs. It says: "autoload-dev (root only)". root only means it only applies to the root package. As you included the package, the shown composer.json file is not the root package and the autoload-dev section is thus ignored.

Adding git repository with Composer for development branch where no composer.json present

I have been trying to install a git repository that does not have a composer.json file. I followed the instructions on the composer website and also found in this stackexchange post: Composer - adding git repository without composer.json
However, I am still not able to get it to work. I keep getting an error stating: "The requested package phpredis/phredis could not be found in any version, there may be a typo in the package name.
This is my composer.json file on my system (note that predis/predis loads fine but I want to use the other redis package):
{
"respositories": [
{
"type":"package",
"package":
{
"name":"phpredis/phpredis",
"version":"develop",
"dist":
{
"url":"https://github.com/phpredis/phpredis.git",
"type":"git"
}
}
}
],
"require": {
"predis/predis": "^1.0",
"phpredis/phpredis":"dev-master#dev"
}
}
I know that I must be making a simple error somewhere but I have spent hours and can't figure it out. Thanks for the help.
It's useless to fiddle with any composer.json replacement for this repository because it contains C software that needs to be compiled and installed as a PHP extension. Composer won't do this for you, it can only manage PHP source code.

Class 'Pimple\Container' not found

I am trying to install Pimple in my project following https://github.com/silexphp/Pimple readme file.
Error message I receive is:
Fatal error: Class 'Pimple\Container' not found in E:\www\public\index.php on line 9
My composer.json file is:
{
...
"require-dev": {
"phpunit/phpunit": "5.1.*"
},
"require": {
"pimple/pimple": "~3.0"
}
}
When I do:
composer update
or
composer install
the message is: Nothing to install or update
In vendor/bin I can see only phpunit files. I can see however pimple in composer.lock
My PHP index.php file:
<?php
use Pimple\Container;
$co = new Container();
?>
Could you please help me make it work?
vendor/autoload.php was not included and this caused the error.
Try to delete Vendor content, and install dev again througth composer.

Categories