PHP Adding Custom Namespace Using Autoloader from Composer

PHP adding custom namespace using autoloader from composer

You actually don't need custom autoloader, you can use PSR-4.

Update your autoload section in composer.json:

"autoload": {
"psr-4": {
"Classes\\Weather\\": "Classes/CronJobs/Weather"
}
}

To explain: it's {"Namespace\\\": "directory to be found in"}

Don't forget to run composer dump-autoload to update Composer cache.

Then you can use it like this:

include(LIBRARY .'autoload.php');

$weather = new Classes\Weather\WeatherSite();

How to use Composer's autoloader to autoload arbitrary classes/namespaces not configured in composer.json?

With this file structure:

Sample Image

Where class Test1 is:

// out/Test1.php
class Test1
{
public function foo(): string
{
return "foo bar baz";
}
}

and class FooBar/Console/Test2 is:

// psr4/someroot/Console/Test2
namespace FooBar\Console;

class Test2
{
public function bar(): string
{
return "fizz buzz";
}
}

and having this on the test script (test.php)

// test.php

require __DIR__ . '/vendor/autoload.php';
$loader = new \Composer\Autoload\ClassLoader();

$loader->add('Test1', __DIR__ . '/out');
$loader->addPsr4('FooBar\\', __DIR__ . '/psr4/someroot');

$loader->register();

$t1 = new Test1();
$t2 = new \FooBar\Console\Test2();

echo $t1->foo(), "\n";
echo $t2->bar(), "\n";

I can run php test.php perfectly fine.

So something else must be misconfigured in your project. Use the above example as a guide to fix it.

Custom code management with the Composer auto loader?

This is actually very simple. Excluding vendors directory from your repository is the right approach. Your code should be stored in a separate place (like src).

Use the autoload property to make that composer recognizes your namespace(s):

{
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
}
}

Assuming you have class names following the psr-4 standard, it should work. Below some example of class names and their locations on the file system:

  • Acme\Command\HelloCommand -> src/Command/HelloCommand.php
  • Acme\Form\Type\EmployeeType -> src/Form/Type/EmployeeType.php

Remember to define a namespace for each class. Here's an example of Acme\Command\HelloCommand:

<?php

namespace Acme\Command;

class HelloCommand
{
}

Don't forget to include the autoloader in your PHP controllers:

<?php

require 'vendor/autoload.php';

Read more on PSR-4 standard on PHP Framework Interoperability Group.

Note that if you edit composer.json, you need to either run install, update or dump-autoload to refresh the autoloader class paths.

Custom package's class won't auto-load with composer autoloader

I would suggest you to use PSR-4 autoloading. Keep in mind that you have to put trailing backslashes at the end of the namespace declaration:

"autoload": {
"psr-4": {
"Gabyfle\\": "src/"
}
},

Quote from the composer docs:

Note that as opposed to the older PSR-0 style, the prefix (Foo\\) is not present in the file path.

And also:

Namespace prefixes must end in \ to avoid conflicts between similar prefixes. For example Foo would match classes in the FooBar namespace so the trailing backslashes solve the problem: Foo\ and FooBar\ are distinct.

So keep that in mind if you switch from psr-0 to psr-4

Custom autoload conflicts with Composer's autoload?

You might be able to replace your custom autoloader function with a classmap autoloader in your composer.json:

{
"autoload": {
"classmap": ["classes/"],
"files": ["custom_funcs.php"]
}
}

This map is built by scanning for classes in all .php and .inc files in the given directories/files.

Whenever you create a new class, you might have to update composer's autoloader by using composer dump-autoload for it to be picked up. I am not sure if this is the case by default or only when optimizing the autoloader, though. In any case this could be solved by adopting PSR-0 or PSR-4 naming conventions for new classes.

edit: Since all files will be autoloaded for you with composer's autoloader, it should not be necessary anymore to require them manually. Therefore you could also remove the setupBeforeClass-method

How to use multiple autoload functions for composer?

I want to use vendor/autoload.php - for composer files, but only my autoload-my-func.php for classes with my custom namespace. (My_Custom_Namespace)

You should use composer's auto loader for both and define your custom namespace in your composer.json file. If you are stuck with a poorly designed legacy system, and you need something to bridge a gulf of stupidity until you can create a better solution, then you should take a look at the documentation for spl_autoload_register. Specifically, the line about "if there must be multiple autoload functions, spl_autoload_register() allows for this. It effectively creates a queue of autoload functions, and runs through each of them in the order they are defined." When you include composers autoload.php, you eventually get a few calls to spl_autoload_register(), so simply register your custom autoloader after including composer's.

How to define custom autoloader in composer?

Simply don't include it if you don't want to use it. Keep in mind you'll have to handle autoloading on your own.

If your autoloader can work with it, you can use namespaces file generated by composer:

Composer provides its own autoloader. If you don't want to use that one, you can just include vendor/composer/autoload_namespaces.php, which returns an associative array mapping namespaces to directories.

Reference: Autoloading in the composer docs.



Related Topics



Leave a reply



Submit