Silex autoload psr-4 class does not exist - php

I have this error:
InvalidArgumentException in ControllerResolver.php line 147:
Class "MyProject\API\FrontController" does not exist.
Here is my structure of myproject:
composer.json
api
src
FrontController.php
BundlesFolders
app
web
vendor
clients
My composer.json
"psr-4": {
"MyProject\\API\\": "myproject/api/src",
"MyProject\\Client\\": "myproject/client/src"
}
My routing.php :
// myproject/api/app/config/routing.php
$routes->get('/', 'MyProject\API\FrontController::exec')
FrontController.php :
<?php
// myproject/api/src/FrontController
namespace MyProject\API;
class FrontController {

You've put an extra folder to your psr-4 map. The first myproject directory should not be in your path as this path is relative to the composer.json file and your src code is in api/src and clients/src (the second is just a guess, you didn't post the content of the clients directory).
Let me tell you that IMHO your directory layout is weird. I would have a single src directory and inside put an api and a client subdirectory.
PS: You've listed the client directory in singular but in composer you have it in plural, watch out for this details!
Also run composer dump-autolad after changing your psr-4 parameter.

Related

"Class HelloController not found" error on composer autoload config with psr4

I try to create my own composer library. I've chose to use psr4 for autoloading mechanism. It works fine with the library project but something goes wrong when I add this library to another project as dependency. I expect the library project create an instance of a class which is located in main project. However this class cannot be found by composer autoloader.
My library project source is here : https://github.com/brnogz/kwinsey
My example project which uses this library like that(HelloWorld class is located in controller/HelloWorld.php file) : https://gist.github.com/brnogz/e27a1dd40ba00b818b23fe7ab8815fad
Please move all your sources to a src subfolder and use "src/" as the PSR-4 target folder. Autoloading from a project root folder is pretty much undefined behaviour.

How to distinct vendor classes and native classes in PHP autoload?

How to distinct vector classes and native project classes in PHP autoload?
see a part of the file and namespace structure:
app/
app/Models/
app/Models/User.php
app/Contoller/
app/Contoller/Login.php
vendor/
vendor/company/package/Helper.php
Now PSR-4 says if there a class is needed to be included, autoload must include it from vendor, so how can I include my native project classes like including a model in a controller?
For Example following code:
$user = new App\Models\User();
autoload looks for "App" company (folder) in vendor folder, one approach could be use some conditions in autoload and if the namespace starts with "App" look for class in native project, is it the standard approach?
Second one, what about this, there is a package in vendor which its company name is "App" in vendor name, what is complete way?
The best solution is setting PSR-4 autoloads in your composer.json file as the following example illustrates:
// Part of composer.json
"autoload" : {
"psr-4" : {
"App\\" : "app/"
}
}
Now you don't need to extra autoload, the Composer autoload will do it for you.
When the requested class is under App namespace, Composer looking for it in the app folder as it set in the composer.json file above.

Custom composer namespace doesn't find class

I'm trying to use my custom namespace for my personal classes.
The directory structure is (as usual):
my_project/
- src/
|- myComponent.class.php
\- myWrapper.class.php
- vendor
|- OtherLibrary
\- Symfony
- composer.json
- index.php
in my composer.json I specify my own namespace with:
"autoload": {
"psr-0": {
"my_namespace\\": "src/"
}
}`
then in my PHP code I have something like:
myComponent.class.php
namespace my_namespace;
class myComponent
{
.... code
}
index.php
namespace my_namespace;
require_once __DIR__.'/vendor/autoload.php';
$component = new myComponent();
Running this I get a:
Fatal error: Class 'my_namespace\myComponent' not found in /path_to_root/my_project/index.php on line 5
while...
I would expect myComponent to be searched under my_project/src/, as specified in the composer.json and as defined into vendor/composer/autoload_namespaces.php ('my_namespace\\' => array($baseDir . '/src')).
I would expect to directly call my custom myComponent, when I define the namespace to my own namespace. Am I wrong?
What's wrong in my code and my assumptions?
How should I fix it?
You found the errors yourself, but here is a quick collection of what the useful autoload directives in Composer do:
PSR-0 converts the class name into a path name (underscores and backslashes from namespaces are converted into a directory separator), adds ".php" at the end, and tries to find this file in the path that you have given in the composer.json file. A class myNamespace\myClass and "psr-0":{"myNamespace\\": "src"} will try to load src/myNamespace/myClass.php.
PSR-4 only works with namespaces. It removed the namespace prefix given in composer.json from the full class name, and the remainder is converted into a path, ".php" added at the end, and searched in the path given. A class myNamespace\myClass and "psr-4":{"myNamespace\\": "src"} will try to load src/myClass.php.
Classmap autoloading will work by scanning all the files for classes, interfaces and traits (everything that can be autoloaded), and compiles an array map of it. It works with any file name schema and any directory layout, but try to avoid it because it will need an update to the map every time you add a new class. Also, it takes time to scan the files while installing, and it takes some CPU and memory to load and hold that map.

Class not found with composer autoload

I have my file structure as
/
/app/
/app/logs/
/app/templates/
/app/index.php
/public_html/
/public_html/.htaccess
/public_html/index.php
/vendor
/vendor/(all vendor here)
My vhost is pointing to /public_html
in app/Index.php
namespace App;
class Index {}
Composer.json
"autoload":
{
"psr-0":
{
"App\\": "app/"
}
}
Yet it is still showing as ( ! ) Fatal error: Class 'App\Index' not found in C:\wamp\www\project\public_html\index.php on line 34
Line 34:
new \App\Index();
Using Slimframework as well if that matters, can't think what is wrong
Since you were using the PSR-0 standard, PHP was looking for the file app/App/Index.php, which does not exist. Note that in PSR-0, you define a base directory (app in your case) where the mapped namespace (App) can be found. However, the file structure within that base directory should exactly match the fully qualified class names. So class App\FooBar should be in the file app/App/FooBar.php. Note that app is the base directory, and App is the directory that contains all subdirectories and PHP files for that namespace.
Since this is not the case in your application (and also because PSR-0 has been deprecated), you should (as you already did) use PSR-4, the new autoloading standard, instead. In PSR-4, you can directly map a certain namespace to a certain directory. In your case, you have mapped the App namespace to the app directory, so that PHP will open the app/Index.php file if you need to use the App\Index class.

PHP Namespace directory structure

It is my understanding that namespaces are declared as follows : vendor\module\classname.
And directory structure would be:
/Acme
/Module1
/src
/Module1
/Class.php
And a valid way to instantiate the class is : new Acme\Module1\Class();
Are my assumptions correct? If so, what's the benefit of using the src folder?
Convention usually.
If you're using composer and you want to autoload your classes, it looks like you're trying to do PSR-0 autoloading.
So if you have "Acme": "src/"
Then in the same directory as your composer.json file would be a src folder, and in the src folder would be a Acme folder. All files in that folder would be namespace Acme; and all files in subdirectories of that folder would be namespace Acme\Subdirectory;.
In the console you need to type composer dump-autoload every time you make changes to the autoloading part of your composer.json file. (or for classmap autoloading, every time you add new files to directories being autoloaded.) This causes the files generated by composer to be updated. (you can find these files in the vendor/composer directory).
So if there was a src/Acme/Subdirectory/ClassName.php with a class in it named ClassName then to instantiate that class you could type new \Acme\Subdirectory\ClassName();
edit: so if this is your composer.json file
{
"autoload": {
"psr-0": {
"Acme": "src/"
}
}
}
then your directory structure would be something like this
/ProjectRoot
composer.json
/src
/Acme
/Module1
Class.php
And you would create a new instance of your class by typing
new \Acme\Module1\Class();

Categories