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;
Related
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
i'm a newbie at composer, so just bear with me,
So i have a package, which i'm loading from local folder, and while using it, i get the following error:
Fatal error: Class 'mypkg\Layer\EasyCPT' not found in
C:\xampp\htdocs\testwp\app\Cpt\location.php on line 5
My Composer.json:
"repositories": [
{
"type":"vcs",
"url":"C:/xampp/htdocs/mypkg"
}
],
"require": {
"php": ">=7.0.0",
"mypkg/particles": "master"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
Package's Composer:
"minimum-stability": "dev",
"authors": [
{
"name": "Talha Abrar",
"email": "talha#themegeek.io"
}
],
"autoload": {
"psr-4": {
"Mypkg\\": "particles/"
}
}
Psr 4:
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Mypkg\\' => array($vendorDir . '/Mypkg/particles/particles'),
'App\\' => array($baseDir . '/app'),
);
how i am using it:
<?php
namespace App\Cpt;
use Mypkg\Layer\EasyCPT;
class Location extends EasyCPT{
protected $plural = 'locations';
}
Main auto-loading file:
require __DIR__.'/vendor/autoload.php';
use App\Init\EasyWP;
new EasyWP();
You use the namespace as:
use Particles\Layer\EasyCPT;
but in autoload section defining as:
"Mypkg\\": "particles/"
which is not consistent.
You should replace Mypkg with the right namespace name, e.g.
"autoload": {
"psr-4": {
"Particles\\": "particles/"
}
}
So requesting Particles\Layer\EasyCPT namespace will look for class in particles/Layer/EasyCPT.php file.
As per Composer's PSR-4 documentation:
Under the psr-4 key you define a mapping from namespaces to paths, relative to the package root. When autoloading a class like Foo\\Bar\\Baz a namespace prefix Foo\\ pointing to a directory src/ means that the autoloader will look for a file named src/Bar/Baz.php and include it if present. Note that as opposed to the older PSR-0 style, the prefix (Foo\\) is not present in the file path.
If your project doesn't follow PSR-4 approach, use classmap instead to scan for all of your classes, e.g.
"autoload": {
"classmap": ["particles/"],
"exclude-from-classmap": ["/tests/"]
}
To regenerate autoload manually, run:
composer dump-autoload -o
and check autoload files in vendor/composer/ whether the references to classes were generated correctly.
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
I've been testing getting my packages up to Packagist with a simple class I made. Whenever I require it in a different project, it says the class cannot be found. Is something wrong with my composer.json autoload block?
Here's my project repo file structure:
- src
- prodikl
- View.php
- .gitignore
- composer.json
And here's my composer.json:
{
"name":"prodikl/simple-view",
"description":"A simple to use, basic View object.",
"require" : {
"php" : ">=5.3.0"
},
"autoload": {
"psr-4": {"prodikl": "src/"}
}
}
And finally, in my View.php:
<?php
namespace prodikl;
class View
{
...
}
But whenever I require it into a project and do require "vendor/autoload.php" and use use prodikl\View; it it keeps saying not found
You just need to point your autoloader down one more directory:
"autoload": {
"psr-4": {"prodikl": "src/prodikl/"}
}
This means "classes that belong to the \prodikl namespace can be found in the src/prodikl/ directory."
You might need trailing backslashes on the namespace name too, not sure how picky Composer is about it:
"psr-4": {"prodikl\\": "src/prodikl/"}
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.