0
votes

I'm developing on a project which uses Monolog, which requires Psr/log. When I use Monolog by autoload, it then complains about missing Psr\Log\LoggerInterface. So I look through the composer generated autoload_namespaces.php, and I couldn't find Psr being registered.

Here's the contents of my vendor/autoload_namespaces.php

return array(
'Symfony\\Component\\Process' => $vendorDir . '/symfony/process/',
'Monolog' => $vendorDir . '/monolog/monolog/src/',
'Imagine' => $vendorDir . '/imagine/Imagine/lib/',
'Gedmo' => $vendorDir . '/gedmo/doctrine-extensions/lib/',
'Gaufrette' => $vendorDir . '/knplabs/gaufrette/src/',
'Evenement' => $vendorDir . '/evenement/evenement/src',
'Doctrine\\ORM' => $vendorDir . '/doctrine/orm/lib/',
'Doctrine\\DBAL' => $vendorDir . '/doctrine/dbal/lib/',
'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/',
'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/',
'Analog' => $vendorDir . '/analog/analog/lib/',
);

Is composer supposed to register namespaces for all projects which has {autoload} defined in their composer.json files? (I checked both Monolog and Psr/Log, they both have {autoload} defined.)

Or am I getting the wrong idea about composer?

3

3 Answers

0
votes

You need to explicitly add

"psr/log": "1.0.0"

in your composer.json require block. The project monolog/monolog doesn't require psr/log [you can verify that in monolog's composer.json file].

Then run composer update to update your autoloader file.

[UPDATE] Made a mistake.

I am using monolog 1.2.* and it doesn't require psr/log. After monolog 1.3.*, it does requires psr/log. In that case, composer should load psr/log namespace in vendor/autoload_namespaces.php.

For example, I just updated my composer.json to have

"monolog/monolog": "1.3.*",

in the require block. Then run composer update monolog/monolog [you can run this command again to see if it fixes your problem]

Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing psr/log (1.0.0)
    Loading from cache

  - Removing monolog/monolog (1.2.1)
  - Installing monolog/monolog (1.3.1)
    Downloading: connection...
    Downloading: 100%

Then in my vendor/composer/autoload_namespaces.php, I found this proper entry:

    'Psr\\Log\\' => $vendorDir . '/psr/log',

This should work. Sometimes I also just run

composer dump-autoload

to re-generate vendor/composer/autoload_namespaces.php file again.

0
votes

I was actually confused by the number of autoload_namespaces.php there are. The one I posted in my question was in vendor/, then I found another one in vendor/.composer/, and finally found the CORRECT one in vendor/composer/.

Sorry for the answering my own (stupid) question but it's worth mentioning in case some other developers have the same trouble.

And thanks to @Chuan Ma for the answer.

0
votes

Composer registers classes based on the autoloadin the project's composer.json file, e.g.

{
  "autoload": {
    "classmap": [
      "path/to/FirstClass.php",
      "path/to/SecondClass.php"
    ]
  }
}

Normally composer update will automatically regenerate autoload_namespaces.php lists all namespaces which your application can use (unless you're using multiple autoloaders).

If the namespaces are missing, here is the command to update the composer autoloader directly:

composer dump-autoload -o

Then you need to make sure you include the autoloader at the top of our scripts:

<?php
require_once __DIR__ . '/vendor/autoload.php';

See: How to directly autoload classes with Composer?

If it's still failing, double check the syntax in the failing project's composer.json file (especially autoload section). To debug, try running composer with -vvv or under XDebug.