mhvvzmak1
mhvvzmak1

Reputation: 317

PHP - Namespace not found, autoload project with composer

I'm quite new to autoloading and namespaces, and attempting to add namespaces to my MVC project.

So In my composer I added:

"autoload": {
    "psr-0": {
        "prj\\app\\": "app/",
        "prj\\app\\controller\\": "app/controller/",
        "prj\\app\\classes\\": "app/classes/"
    }
}

And then updated composer and ran the autodump command.

I then went back to my app to try use one of these namespaces however I just get the following back:

use \app\classes\engine; // use statement I tried

Fatal error: Uncaught Error: Class 'app\classes\engine' not found in C:\inetpub\wwwroot\web\index.php:87 Stack trace: #0 {main} thrown in C:\inetpub\wwwroot\web\index.php on line 87

I'm not sure why it is unable to find the class using the namespace, here's my entire folder structure if it may be of any use:

PRJ
├───app
│   ├───classes
│   └───controller
├───web
│   └───index.php
├───vendor
│   ├───bin
│   ├───composer
│   ├───...
└───view
    ├───bootstrap
    └───default

/app stores the logic such as controllers and classes.

/web is the web root - the index.php is the page which visitors see and also everything is handled through here.

/vendor is the composer directory where my dependencies are stored.

Upvotes: 1

Views: 1131

Answers (1)

Oldskool
Oldskool

Reputation: 34837

There are several things going wrong. First of all, you're adding duplicate namespaces in your composer.json:

The lines:

"prj\\app\\controller\\": "app/controller/",
"prj\\app\\classes\\": "app/classes/"

Are unnecessary as they are already covered by:

"prj\\app\\": "app/",

As long as the directory under app matches the name of the namespace you use, there is no need to define it explicitly. So you can just add:

"autoload": {
    "psr-0": {
        "prj\\app\\": "app/"
    }
}

Secondly, your use statement seems off, you're trying:

use \app\classes\engine;

The leading slash should not be neccessary here, if you are already in the same namespace. Additionally, you're autoloading your namespaces as prj\app and not app, so you're missing the prj bit. It should look something like this (when this is a file inside the app folder):

<?php

namespace prj\app\controller;

use prj\app\classes\engine;

class MyController
{
    /**
     * @var engine
     */    
    private $engine;

    public function __construct()
    {
        // This should now work since engine should be autoloaded
        $this->engine = new engine();
    }
}

Also take a look at the PSR-0 naming conventions as you don't seem to follow them. Class names and namespace folders should be capitalized, like App\Classes\Engine instead of app\classes\engine.

Upvotes: 3

Related Questions