I'm creating a web app with Slim and Twig. The libraries I use work perfectly, I can call them easily with no problem. However my own classes are not found by composer.json autoload psr-4 (psr-0 doesn't find them either)
Here is my file system:
project
|composer.json
|src
|public
| |index.php
|classes
| |Application.php
| |middlewares
| |SecurityMiddleware.php
|templates
|TemplateController.php
|main
|MainController.php
Here is my composer.json:
{
"authors": [
{
"name": "Jean-Marc ZIMMER",
"email": "#################gmail.com",
"role": "Developer"
}
],
"require": {
"slim/slim": "^3.11",
"slim/extras": "*",
"twig/twig": "^2.5",
"slim/twig-view": "^2.4",
"slim/views": "^0.1.3"
},
"autoload": {
"psr-4": {
"src\\": "src",
"middlewares\\": "src/classes/middlewares",
"classes\\": "src/classes",
"templates\\": "src/templates"
}
}
}
Then src/classes/Application.php:
<?php
namespace classes;
class Application extends \Slim\App {
public function __construct($container = array()) {
parent::__construct($container);
}
}
And finally my index.php file:
<?php
require '../../vendor/autoload.php';
$app = new \classes\Application([
"settings" => [
"displayErrorDetails" => true
]
]);
$app->run();
When I run composer dump-autoload, the command outputs:
Generated autoload files containing 0 classes
then exits with status code 0. It should find 4 classes, right ?
And running the app shows the error:
Fatal error: Uncaught Error: Class 'classes\Application' not found in /opt/lampp/htdocs/project/src/public/index.php:5
I'm sure I'm missing something, indicating a namespace or something. Can anyone help me ?
Edits:
I tried using the --optimize or the --classmap-authoritative option for dump-autoload. Changed nothing.
Adding a '/' to the folder names in composer.json doesn't change anything.
I got a solution from another source. I don't personally like it, but it works.
The file system wasn't changed.
composer.json autoload:
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
src/public/index.php:
<?php
require '../../vendor/autoload.php';
$app = new \App\classes\Application([
"settings" => [
"displayErrorDetails" => true
]
]);
$app->run();
src/classes/Application.php:
<?php
namespace App\classes;
class Application extends \Slim\App {
public function __construct($container = array()) {
parent::__construct($container);
}
}
I'm going to work from this functional base and see if I can get the result I want. If I do, I'll edit this answer.
Ensure your composer.json references your deployment paths. For example:
Dockerfile
FROM php:7.2-apache
COPY src /var/www/html
COPY vendor /var/www/vendor
composer.json
{
"autoload": {
"psr-4": {
"Acme\\": "html/classes/"
}
}
}
i.e. html/classes/ not src/classes/
Related
I have an app with laravel 7, and i upgrade composer 1.10 to composer 2.0, and i have this problem:
Illuminate\Contracts\Container\BindingResolutionException
Target class [DatabaseSeeder] does not exist.
at vendor/laravel/framework/src/Illuminate/Container/Container.php:807
803|
804| try {
805| $reflector = new ReflectionClass($concrete);
806| } catch (ReflectionException $e) {
> 807| throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
808| }
809|
810| // If the type is not instantiable, the developer is attempting to resolve
811| // an abstract type such as an Interface or Abstract Class and there is
+37 vendor frames
38 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
I tried many solution (even for Laravel 8 ...) without success.
Here is the autoload of the composer.json
"psr-4": {
"App\\": "app/",
"DatabaseSeeder\\": "database/seeds"
},
"files": [
"app/helpers.php"
]
}
Thx !
EDIT
Here is what I just found: When I add in the composer.json :
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories",
"Database\\Seeds\\": "database/seeds",
"DatabaseSeeder\\": "database/seeds/",
} },
and that I modify line 84 of SeedCommand.php 'src/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeedCommand.php', it work !!!
$class = $this->laravel->make($this->input->getOption('class'));
by
$class = $this->laravel->make('Database\\Seeds\\DatabaseSeeder');
But this is absolutely not maintainable...
So the problem is, there is a problem when DatabaseSeeder is set.
6An idea ?
I found the solution:
Laravel documention : https://laravel.com/docs/7.x/seeding#introduction
All seed classes are stored in the database/seeds directory.... By default, a DatabaseSeeder class is defined for you.
This folder is not compatible with the PSR-4, so you have to use the classmap in the composer.json with Laravel 7.
It is therefore also necessary to remove the namespaces in the files of seeds.
Here is my composer json:
"autoload": {
"psr-4": {
"App\\": "app/",
},
"classmap": [
"database/seeds",
"database/factories"
],
"files": [
"app/helpers.php"
]
}
I solved it as follows:
I followed what the documentation said regarding Sedeers and factories
I ran composer dump-autoload
Update composer to version 2
I've tried now some different approaches and read articles here and elsewhere but i can't figure out what i'm doing wrong.
I'm developing a package and I want it to be installed via symlink in a different project to develop both parts simultaneously without the need of updating the dependencies over and over again.
The thing I cant get to work is the autoloading.
Here is my setup:
Project composer.json
{
"repositories": [
{
"type": "path",
"url": "../../FormTableComponent",
"options": {
"symlink": true
}
}
],
"require": {
[...]
"bluechord/formtablecomponent": "#dev"
}
}
FormtableComponent Folder Structure
FormTableComponent/
src/
| Container.php
composer.json
FormtableComponent composer.json
{
"name": "bluechord/formtablecomponent",
"description": "...",
"autoload": {
"psr-4": {
"BlueChord\\FormTableComponent\\": "src/"
}
},
"require" : {
[...]
}
}
FormtableComponent Container.php
<?php
/**
* FormTable Container. The Container Class that registers all Parts of the
* Component.
*/
namespace BlueChord\FormTableComponent;
class Container {
function __construct() {
}
}
When I try to use the class and instantiate it I get
Uncaught Error: Class 'BlueChord\FormTableComponent\Container' not found
Thanks for your help!
ADDITIONAL INFO:
A simple Test.php which reproduces the error inside the project
<?php
require_once 'bin/vendor/autoload.php';
echo "BCOSP Test";
use DebugBar\StandardDebugBar;
use BlueChord\FormTableComponent\Container;
$debugbar = new StandardDebugBar(); --> WORKS
echo StandardDebugBar::class ."\n";
$container = new Container(); --> ERROR
echo Container::class . "\n";
Composer
The vendor/composer/autoload_psr4.php does NOT contain any array key for my package.
If I run composer dump-autoload inside my main project nothing changes.
If I run composer dump-autoload inside my package it creates the correct autoload_psr4.php
I am using Laravel 5.8 and I created a custom class named StatusLib.php in the app/library folder.
StatusLib.php
namespace App\library;
class StatusLib
{
CONST SUCCESS = '100';
CONST SUCCESSWITHMESSAGE = '101';
}
I can call this status .
StatusLib::SUCCESS
When I add this following use code in the controller.
use app\library\StatusLib;
How can I add this StatusLib class in autoload and access from anywhere in the project?
Namespaces are case-sensitive.
In your StatusLib class you have App\library;, however, in your controller you've used app\library -- these are not the same.
Change your use statement in your controller to be:
use App\library\StatusLib;
You may also need to run:
composer dumpautoload
Just FYI, Laravel comes with the app directory already set up for autoloading.
In your composer.json file, after the classmap array, add a psr-0:
"autoload" :{
"classmap": [
...
],
"psr-0": {
"library": "app/"
}
}
Run composer dump-autoload.
Hope it helps.
where do you want to use it?
it will be automatically autoloaded because app folder is loaded in composer.json
here:
"autoload": {
"psr-4": {
"App\\": "app/"
},
},
I use composer for autoloading classes but autoload didn't work. My structure of project looks like like this:
Commandos:
src:
here is located php classes
inside commandos folder composer json file.
{
"require": {},
"autoload": {
"psr-4": {"Commandos\\": "/src"}
}
}
In every class I use namespace like this namespace Commandos\Some; and require _autoload.php
Where is I was mistake?
I fix it my mistake.
I should use in composer.json
{
"require": {},
"autoload": {
"psr-4": {"commandos\\": "src"}
}
}
and in every my class in folder src use namespace begin from namespace commandos;
In composer.json I have the following data:
{
"require": {
"slim/slim": "2.*",
},
"autoload": {
"psr-0": {
"lib": "lib/"
}
}
}
lib folder resides beside vendor folder. Inside of lib I have a class named Decorator.php and my class name is Decorator as below:
namespace lib;
class Decorator
{
public function OutputDecorate()
{
return true;
}
}
I ran php compooser.phar update and get the message Nothing to install or update blah blah blah.
And to have a better understanding, this is a part of project folder structure:
Now when I want ti instantiate my class I cannot access my class.
use lib;
class Collection {
public $decorator;
public function __construct() {
$this->decorator = new Decorator();
}
You should be doing:
use lib\Decorator;
if you want to be able to do new Decorator(); in your code.
The PHP use statement only includes a single class, it doesn't import whole namespaces.
Are you a recovering Java programmer?
Also for PSR-0, the declaration in the composer.json of where classes are needs to point at containing directory not the top level namespace. e.g. I think it should be:
"psr-0": {
"lib": "./"
}
or
"psr-0": {
"lib": ""
}
I used psr-4 instead and then my classes are loading perfectly.
Here is my composer.json.
{
"autoload": {
"psr-4": {
"ComposerTest\\Models\\": "App/Models",
},
}
}
And the Folder structure is
-->App
-->Models
-->Product.php