0

I'm having no end of trouble with setting up class auto-loading with Composer, I've read and watched millions of reference materials at this point & somehow I appear to still be missing something crucial.

Some quick version information:

  • PHP - v5.6.17
  • Composer - v1.0-dev (alpha11, global install)
  • PHPUnit - v4.2.6
  • Temperament - frustrated

The project layout is relatively simple:

. ├── composer.json ├── framework │   ├── classes │   │   ├── Test1.php │   ├── config │   │   ├── Test2.php │   ├── financial.html │   ├── form.html │   ├── index.php │   ├── models │   │   ├── Base.php │   ├── sample.html │   └── services │   └── validate.service.php ├── phpunit.xml ├── test │   └── FormTest.php └── vendor ├── autoload.php ├── composer │   ├── autoload_classmap.php │   ├── autoload_files.php │   ├── autoload_namespaces.php │   ├── autoload_psr4.php │   ├── autoload_real.php │   ├── ClassLoader.php │   ├── installed.json │   └── LICENSE └── constants.php 

"composer.json" currently contains the following:

{ "name": "testframework", "require": { "PHP": ">=5.6.17" }, "autoload": { "psr-4": { "Config\\": "framework/config/", "Classes\\": "framework/classes/", "Models\\": "framework/models/" }, "files": [ "vendor/constants.php" ] } } 

Whenever I make changes to the directory structure, rename classes or modify "composer.json" I run:

% composer validate (only when modifying "composer.json") % composer dump-autoload -o 

I'm aiming to auto-load all classes from the "classes", "config" and "models" folders within "framework"; "index.php" currently implements "framework/models/Base.php", this is shown below.

<?php require_once( dirname( __DIR__ ) . '/vendor/autoload.php' ); use Models\Base; $derp = new BaseModel(); ?> 

I've verified that the above points to the correct location & returns: "/var/www/testproject/vendor/autoload.php"

Base.php contains the following script:

<?php namespace Models; class BaseModel { public $submitAction = null; protected $complete; public function __construct() {} /** * Expose * Exposes the error code names for external processing. * * @return An array containing all error code names in this object. */ public static function Expose() { $reflector = new ReflectionClass( 'ErrorCodes' ); return $reflector->getConstants(); } } 

I've gone through every permutation of the namespacing I can think of, have been endlessly modifying the "composer.json", adding and removing segments as per the documentation, working purely with classmap (which didn't work), testing "PSR-0" (also didn't work), using a bigger hammer (also didn't work).

Obviously I'm doing something horrifically wrong, I just don't seem to be able to puzzle out what; can anyone see where I'm going astray?

Many thanks, N00b

Edit: Huge oversight, the "vendor/composer" directory contains the following relating to Composer's auto-loading.

"autoload_classmap.php":

<?php // autoload_classmap.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'Models\\BaseModel' => $baseDir . '/framework/models/Base.php', ); 

"autoload_files.php":

<?php // autoload_files.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'a9da57e70f975fe4a3c7dad63939dcd8' => $vendorDir . '/constants.php', ); 

and "autoload_psr4.php":

<?php // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'Models\\' => array($baseDir . '/framework/models'), 'Config\\' => array($baseDir . '/framework/config'), 'Classes\\' => array($baseDir . '/framework/classes'), ); 

The errors I'm seeing are, from PHP:

Fatal error: Class 'BaseModel' not found in /var/www/testproject/framework/index.php on line 8

and from PHPUnit:

user% phpunit PHPUnit 4.2.6 by Sebastian Bergmann.

Configuration read from /var/www/testproject/phpunit.xml

PHP Fatal error: Class 'BaseModel' not found in /var/www/testproject/test/FormTest.php on line 6

1 Answer 1

2

In your index.php you're not importing the right class:

use Models\Base; $derp = new BaseModel(); 

You should import the Models\BaseModel class:

use Models\BaseModel; $derp = new BaseModel(); 

Also, the file name should match the class name. The BaseModel class should be located in the framework/models/BaseModel.php file instead of framework/models/Base.php.

Note that you don't need to optimise the autoloader during development (that's what -o flag is doing). Only use it in production, otherwise you'll have to dump the autoloader each time you add a new class.

More about the autoloading standards can be read here:

Sign up to request clarification or add additional context in comments.

1 Comment

$*?!£&*+£!&$%^!!!!! Thank you, I knew it was going to be something incredibly stupid. I swear I'd tried this already & moved on... I knew about the -o flag, hearing that I don't need to run the autodump command each time I add a new class is news (if the flag is omitted) however so thank you again, I'll have a play with that. I've been trawling through php-fig.org for the last couple of days, sometimes having your hand held is infinitely more helpful than endless documentation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.