PSR-4 autoloading trouble - php

I want to load HomeController class from lib directory:
root/
-lib/
--/HomeController.php
-vendor/
-composer.json
-index.php
Composer.json
"autoload": {
"psr-4": {
"Lib\\": "lib/"
}
}
HomeController.php
namespace Lib;
class HomeController {}
index.php
var_damp(new \Lib\HomeController.php);
It doesn't find the class.
But if I put HomeController.php inside Controllers directory:
root/
-lib/
--/Controllers/HomeController.php
And update the namespaces: index.php to var_damp(new \Lib\Controllers\HomeController.php); and HomeController.php to:
namespace Lib\Controllers;
class HomeController {}
It works perfect.
It's weird, I can't find any docs talking about it. I don't need additional directories, in this case I want the HomeController class directly inside lib directory.
How can I make it works inside lib folder?

I think the trailing slash in the path reference is your problem. Change the autoload section in composer.json to this:
"autoload": {
"psr-4": {
"Lib\\": "lib"
}
}
...then run composer dump-autoload.

Related

Using Doctrine ORM with namespaces

Official guide explains how to use Doctrine ORM with /src directory and it works okay, however, I have a project with a structure like this:
vendor/
src/
Entities/
Category.php
public/
.htaccess
index.php
bootstrap.php
cli-config.php
composer.json
And I want to have namespace App so I can do this from public/index.php:
use App\DB\Entities\Category;
How should I configure autoload option and bootstrap.php to do this? Composer file currently has this autoloader:
"autoload": {
"psr-4": "/src/Entities"
}
You should update your autoload section in the composer.json file with this configuration:
"autoload" : {
"psr-4" : {
"App\\DB\\Entities\\" : "src/entities/",
}
}
And your entity class should look like this:
<?php
namespace App\DB\Entities;
class Category
{
function __construct(){
}
...
}
Ok, following what composer's documentation says you should have something like this:
"autoload": {
"psr-4": {
"App\\": "./src"
}
}
and Category.php must be created like this:
<?php
namespace App\Entities;
class Category
{
}
Folder structure example

Class file not found by composer and psr-4

I am having very hard times understanding how to use autoloading by psr-4.After loading vagrant and setting and testing all variables in Homestead.yaml I have prepared a file structure as the following:
\app
\folder
-- test.php
\vendor
\composer
-- autoload.php
-- index.php
-- composer.json
and the following are my codes:
index.php
<?PHP
namespace app;
require('vendor/autoload.php');
$object = new folder\test();
composer.json
"autoload":{
"psr-4":{
"app\\": "app"
}
}
test.php
<?php
namespace app\folder;
class test
{
function __construct ()
{
echo 'construction done right.';
}
}
But, after trying to visit the page, these are the error message displayed on the page:
(!) Fatal error: Uncaught Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6
( ! ) Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6
Would you help me understand and fix this error?
It doesn't work because you have told Composer that the classes from the app namespace are in the app subdirectory but there is no app subdirectory.
The entire application is stored in the app directory and it's name doesn't really matter for the application. The classes of the app namespace are stored in the current directory and the sub-namespaces are stored in subdirectories with the same name.
Accordingly, your composer.json file should read:
"autoload": {
"psr-4": {
"app\\": ""
}
}
Or, to be more clear, you can put . (the current directory) as the location of the app\ namespace:
"autoload": {
"psr-4": {
"app\\": "."
}
}
After you make the change run composer dump-autoloader in the main application directory and it will start working.
To fix it for your current setup, use the following:
"autoload":{
"psr-4":{
"app\\": ""
}
}
Your composer.json is in the app-directory, so there's no subdirectory named app to reference.
I would actually recommend to change your directory structure to the following:
\app
\src
\folder
-- test.php
-- index.php
\vendor
\composer
-- autoload.php
-- index.php
-- composer.json
And then in composer.json, set the following:
"autoload":{
"psr-4":{
"app\\": "src"
}
}
This makes sure that all files belonging to your 'app' namespace are contained within a single subdirectory.
Finally, I would recommend you to use a vendor namespace to prevent conflicts, and to use the naming guidelines from PSR-2.
I think you won't need PSR-4 just add classmap
classmap parameter for example :
"autoload": {
"classmap": [
"app"
]
}
After adding this run composer dump-autoload and you should see a number of classes being added.
Hope this helps.
in composer.json try to set
"autoload":{
"psr-4":{
"": "src/"
}
}
then do execute this command
composer dump-autoload -o

Psr-4 composer autoload own class - no found

I have structure directory
autoload composer:
"autoload": {
"psr-4": {
"model\\": "src/"
}
},
my class
namespace model;
class ClientAgent
{
private $pdo;
public function __construct(\PDO $pdo)
{
$this->pdo = $pdo;
}
public function sentAgent()
{
}
}
in index.php i tried add
use model\ClientAgent; but it throw error, not found class? why?
Edit after answer
"autoload": {
"psr-4": {
"model\\": "src/model/"
}
},
my index.php
use model\ClientAgent;
$loader=require_once __DIR__ . '/../vendor/autoload.php';
$clientAgent =new ClientAgent($pdo);
error
Uncaught Error: Class 'model\ClientAgent' not found in C:\xampp\htdocs\Wieloagenty\index.php:15
My suggestion is to introduce a vendor prefix. That might be your developer name, the name of your company or the name of the application.
composer.json
"autoload": {
"psr-4": {
"YourApplication\\": "src/"
}
},
Now, every class inside the src folder and below needs this vendor prefix on it's namespace.
Let's take src\model\ClientAgent.php as example:
namespace YourApplication\Model;
class ClientAgent
{
Now, the FQCN (full qualified class name) is YourApplication\Model\ClientAgent and you might use it as part of a use statment.
// first require the Composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// declare which other classes you are using
use YourApplication\Model\ClientAgent;
$clientAgent = new ClientAgent($pdo);
Important!
After the modifications (to classes and the composer.json file) please regenerate the Composer autoloader with php composer.phar dumpautoload -o.
Composer will scan the complete src folder including subfolders for classes (so you'll have all classes from src\models\ and src\views autoloading ready).
"model\\": "src/" will give you the folder src/ as the base for the model-namespace. So this would give you model\model\Classname.
Change it to:
"psr-4": {
"model\\": "src/model/"
}
When defining psr-4 autoloader in composer, you associate a folder with a specific namespace.
Any sub folders will be a sub-namespace. So if you create a folder in your "model"-folder, the namespace would be: model\new-foldername\Classname and so on.
Note: When ever you update your composer.json file, you always need to run the command: composer dump-autoload to make composer regenerate all it's cached files.

Silex namespaces

I'm still quite new to namespaces and struggle to get my head around how to use them. I'm using Silex Microframework and trying to set up my folder structure. So far I have:
cms/
ACP/
Controller/
HomeController.php
View/
Front/
Controller/
HomeController.php
View/
Template/
page.php
home.php
app.php
bootstrap.php
I'm trying to load the HomeController in the Front/Controller folder. In my app.php file I am calling the controller for home.
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
$app['debug'] = true;
$app->get("/", "cms\Front\Controller\HomeController::index");
$app->get('/test', function() {
return new Symfony\Component\HttpFoundation\Response("Test successful");
});
return $app;
If I go to /test in the browser it works fine. However when I go to / then I get an error.
InvalidArgumentException in ControllerResolver.php line 153:
Class "cms\Front\Controller\HomeController" does not exist.
I've defined cms as a namespace in composer.json and in HomeController I have
<?php namespace cms\Front\Controller;
class HomeController {
public function index() {
return "Hello World, I'm the front page!";
}
}
I've also tried moving the HomeController.php file directly into the cms directory, changing the namespace in the file to just cms and then running $app->get("/", "cms\HomeController::index"); and it still doesn't work. I get the same error that doesn't exist.
Here is my composer file:
{
"require": {
"silex/silex": "~1.1",
// ...other requirements
},
"require-dev": {
"symfony/var-dumper": "dev-master"
},
"autoload": {
"psr-0": {
"cms": "cms/"
}
}
}
What do I need to do to get this working? I can't seem to find anything on the Silex site or Google. Can someone please help me get my head around namespaces and how this works?
You need to add your source folder into the composer autoloading (https://getcomposer.org/doc/01-basic-usage.md#autoloading)
"autoload": {
"psr-4": {"Acme\\": "./"}
}
In your case the path "./" should work (have not tested), if not you should try to put cms folder into a folder like src and set the path to "src/"
Remember to run composer dump-autoload to regenerate the autoload.php

composer autoloader psr-0 namespaces

I have create a custom composer package but I am having troubles to set the correct autoload options for it.
All my classes are under MyNamespace/Common namespace. So for example for including my ArrayHelper class I do use Mynamespace/Common/Helper/ArrayHelper.
This is the relevant part of my composer.json:
"autoload": {
"psr-0": { "MyNamespace\\": "" }
}
I have read this: composer.json / autoload
Any help?
You have to navigate the file location of your namespace.
"autoload": {
"psr-0": { "MyNameSpace": "./<path to your parent directory>" }
}
For example, this is my directory structure:
composer.json
source
\-Data
|-Controller
\-Repository
Then, in the composer.json file:
"autoload": {
"psr-0": { "MyNameSpace": "source/Data" }
}
Then, I can define classes in these namespaces:
/* namespace for classes in controller directory */
namespace MyNameSpace\Controller;
/* namespace for classes in repository directory */
namespace MyNameSpace\Repository;

Categories