ryancey
ryancey

Reputation: 1057

Composer autoload not including my custom namespaces (Silex)

I'm developing a REST API with Silex and I'm facing a problem regarding autoloading of my custom librairy. It looks like Composer's autoload is not including it, because when I include it myself it works.

# The autoload section in composer.json
# Tried with :
#    "Oc\\": "src/Oc"
#    "Oc\\": "src/"
#    "": "src/"

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

<?php
// api/index.php <-- public-facing API

require_once __DIR__.'/../vendor/autoload.php';
$app = require __DIR__.'/../src/app.php';

require __DIR__.'/../src/routes.php'; // <--

$app->run();

<?php
// src/routes.php

// When uncommented, it works!
//include('Oc/ParseImport.php');

use Symfony\Component\HttpFoundation\Response;

use Oc\ParseImport;

$app->get('/hello', function () use ($app) {
  return new Response(Oc\ParseImport(), 200);
});

<?php
// src/Oc/ParseImport.php

namespace Oc {
  function ParseImport() {
    return 'foobar!';
  }
}

I run composer dumpautoload after each composer.json manipulation, and I do see the line 'Oc\\' => array($baseDir . '/src/Oc') (or anything I tried) in vendor/composer/autoload_psr4.php.

I can't figure out what is wrong.

Upvotes: 0

Views: 119

Answers (1)

Sven
Sven

Reputation: 70863

Almost everything you did was correct.

When trying to autoload classes in a namespace, given that a class is named Oc\Foo and is located in the file src/Oc/Foo.php, the correct autoloading would be "PSR-4": { "Oc\\": "src/Oc" }.

However, you do not have a class. You have a function. And functions cannot be autoloaded by PHP until now. It has been proposed more than once (the one proposal I found easily is https://wiki.php.net/rfc/function_autoloading), but until now this feature hasn't been implemented.

Your alternative solutions:

  1. Move the function into a static method of a class. Classes can be autoloaded.
  2. Include the function definition as "files" autoloading: "files": ["src/Oc/ParseImport.php"] Note that this approach will always include that file even if it isn't being used - but there is no other way to include functions in PHP.

As illustration see how Guzzle did it:
Autoloading in composer.json
Conditional include of functions based on function_exists
Function definition

Upvotes: 2

Related Questions