The title speaks itself. So here is my project structure:
|src
|Database
|Core
|MySQL.php
|Support
start.php
|vendor
composer.json
index.php
MySQL.php file:
<?php
namespace Database\Core;
//Some methods here
index.php and start.php files:
//start.php file
<?php
require __DIR__ . '/../vendor/autoload.php';
?>
//index.php file
<?php
use Database\Core;
require __DIR__ . '/src/start.php';
$mysql = new MySQL(); // Gets exception Class 'MySQL' cannot found etc.
?>
And finally my composer.json autoload part:
"autoload": {
"psr-4": "Database\\": "src/" // Also tried "src/Database" too
}
Where is the problem? I'm really tired of trying to cope with this situation. Please help guys! Thanks.
You need to include namespace when you are initializing a class:
$mysql = new Database\Core\MySQL();
or
use Database\Core\MySQL;
$mysql = new MySQL();
See Using namespaces: Aliasing/Importing
Aside from not using the right use statement as already mentioned, PSR-4 does not work like that. It is more of an alias. You are essentially saying that src equals Database. So to have a directory named Database in there would imply that the fully qualified namespace + class equals 'Database\Database\Core\MySQL`. You want to use PSR-0 in this case, or adjust your PSR-4 definition.
Related
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.
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:
Move the function into a static method of a class. Classes can be autoloaded.
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
so i have the following structure for what i'm trying to target but what i'm getting is the Fatal error class MainController not found , i'm new to autoload and namespace thing (but getting into them fast) i just need to know why this is happening , hope you guys have bit explained situation for me? i did saw few of answer around stackoverflow but nuthing helped, i know i'm doing something really wrong, but thats how i will learn :). structure:
composer.json
src/controllers/MainController.php
the following is my autoload inside composer.json file:
"autoload": {
"psr-4": {
"controllers\\": "src/controllers/"
}
}
and this is how my MainController.php looks alike :
namespace MainController;
class MainController{
function test($name){
echo 'holaaaa'.$name;
}
}
controller call inside: app/loads/loadController.php :::
use MainController;
$MainController = new MainController();
more info on vendor/autoload.php
it's included inside : index.php and inside index.php i have included mainapp.php and inside mainapp.php i have included loadcontroller.php vich calls the controller
structure screenshot:
Okay, in your Composer file you say the namespace is controllers. In your PHP file you say the namespace is MainController. They need to be the same for the autoloading to work.
If we are to go by your Composer file then the PHP should look like this:
namespace controllers;
class MainController {}
And the class should be called like this:
$MainController = new \controllers\MainController;
Or like this:
use controllers\MainController;
$MainController = new MainController;
Or, if you want a nicer-looking class name:
use controllers\MainController as Controller;
$MainController = new Controller;
In my case I only managed to correct it after deleting my folder from the composer (vendor) and rerunning the command composer dump-autoload
I previously had a pretty simple autoload script working nicely, but as I've noticed that Doctrine2 is using Composer for this, I thought it might be nice to streamline everything. Unfortunately, Composer does not seem to be working as I understood it to.
Here is the relevant part of my composer.json
"autoload": {
"psr-0": {
"": "models/",
"Catalog2\\Config": "class/"
}
}
Note that the "": "models/" line used by Doctrine2 has been working just fine. After I ran composer update , the bottom part of my vendor/composer/autoload_namespaces.php looks like so:
'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib'),
'Catalog2\\Config' => array($baseDir . '/class'),
'' => array($baseDir . '/models'),
So far so good, I think. In my routes.php file (basically a front-controller) I have the following:
<?php
use Catalog2\Config;
//autoload classes
require_once __DIR__.'/vendor/autoload.php';
try {
$router = new Router;
} catch(Exception $e ) {
echo "<strong>Can't create router object</strong><br/>";
}
Here Catalog2\Config\Router should be calling my class/Router.php, which begins as follows:
<?php
namespace Catalog2\Config;
class Router {
protected $resource; //what are we manipulating? A product? An order?
protected $action; //what are we doing with that resource?
When I go to the page I get this:
Fatal error: Class 'Router' not found in /home/tom/Code/productCatalog2/routes.php on line 14
What is going wrong here? I repeat that Doctrine2 was able to autoload my model code from /models, so why aren't my changes working?
According to PSR-0 the namespace prefix will be included to the path.
So the complete filename for your class must be:
class/Catalog2/Config/Router.php
Meanwhile PSR-4 would behave like you expected: it will just match the namespace prefix and will not append it additionally to the given path.
References:
https://getcomposer.org/doc/04-schema.md#autoload
PS: you probably want the namespace prefix to be "Catalog2\\Config\\" (see the trailing slash)
I have the following folder setup
/common
/classes
-sharedClass.php
/project
/classes
-coreClass.php
index.php
bootstrap.php
In my bootstrap.php I'm setting up a namespace
$autoloader = new ClassLoader('CommonFiles', dirname(__DIR__) . '/common/classes/');
$autoloader->register();
In index.php:
require_once 'classes/coreClass.php'
$core = new CoreClass();
in coreClass():
use CommonFiles\SharedClass;
//Other code
I'm getting an error that sharedClass.php can't be found, and the actual namespace is being appended to the file path being checked so that it's:
c:/web/common/classes/CommonFiles/sharedClass.php
So... how do I stop the autoloader from including the namespace as part of the path root it's looking for?
So after some closer review apparently this is just how autoloading works. I reviewed some of the baked in Doctrine samples and it looks like the namespace is appended automatically to all your use statements. This wasn't just a fluke but a design decision and accounting for it meant an easy fix.
I am working with a folder structure as follows:
classes
-common.php
-core.php
modules
-index/index.php
I am trying to use the common.php in my index.php file and I am facing error:
Fatal error: Class 'classes\Common' not found in
D:\xampp\htdocs\devmyproject\modules\index\index.php on line 7
My Code:
commom.php class:
**Directory:/root/classes/common.php**
<?php
namespace classes;
class Common
{
function __construct()
{
}
}
My index.php file which try to use the classes/commom.php
**Directory:/root/modules/index/index.php**
<?php
namespace modules\beneficiary;
use \classes as hp;
include_once 'config.php';
$common = new \classes\Common();
//To Get Page Labels
$labels = $common->getPageLabels('1');
I am includeing common.php in config.php
$iterator = new DirectoryIterator($classes);
foreach ($iterator as $file) {
if ($file->isFile())
include_once 'classes/' . $file;
}
My Try:
It works fine when I use the folder structure as follows:
classes
-common.php
-core.php
modules
-index.php
If I use another folder inside modules it get error? I am not sure about he hierarchy of folders when using namespace can some one help me?
You have to either include common.php in index.php (better: use one of its relatives include_once or require_once) or set up an autoloader using spl_autoload_register() (or, not recommended, writing an __autoload() function).