Class not found - PSR-4 namespaced autoloading - php

I wanted to set up PSR-4 autoloading for a class I wrote. However I keep getting the error Fatal error: Class 'Glowdemon1\Translxtor\LangParserXML' not found in C:\xampp\htdocs\translator\index.php on line 5
Folder structure(can't post img yet):
LangParserXML.class.php
namespace Glowdemon1\Translxtor;
class LangParserXML extends ErrorHandler implements ParserInterface{
...
index.php
require_once('vendor/autoload.php');
$translator = new Glowdemon1\Translxtor\LangParserXML('nl.xml');
composer.json
"autoload": {
"psr-4": {
"Glowdemon1\\": "src/"
}
}
autoload_psr4.php
return array(
'Glowdemon1\\' => array($baseDir . '/src'),
);
I have looked trough countless posts, yet no solutions. This is also posted on https://github.com/glowdemon1/translxtor in case you want a deeper look. Thanks.

Updates your composer.json to :
"autoload": {
"psr-4": {
"Glowdemon1\\Translxtor\\": "src/"
}
}
Or add a src/Transxtor/ directory before your LangParserXMl
Also, your filename cannot contain ".class". It should just be called LangParserXML.php.

I think you should have a Translxtor folder within src containing LangParserXML.class.php and Translator.class.php:
The contiguous sub-namespace names after the "namespace prefix" correspond to a subdirectory within a "base directory", in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.
Source: http://www.php-fig.org/psr/psr-4/
`

Related

Configure composer to use class names with prefixes

I have a folder structure like this:
Root-Folder/backend/user/class-user.php
Root-Folder/backend/profile/class-profile.php
Root-Folder/backend/login.php
Sample class-user.php content:
namespace myapp\user;
class User{
....
}
In my composer.json:
...
"autoload": {
"psr-4": {
"myapp\\": "backend/"
}
},
...
But this way the files are not included because they have a class- prefix in the file name. If I change the file names to user.php and profile.php, they work.
How can I configure composer to include class-user.php too?
PSR-4 requires classes names to be the same as file name that contains it.
In this case you need to use "classmap" directive instead of PSR-4
https://getcomposer.org/doc/04-schema.md#classmap
{
"autoload": {
"classmap": ["backend"]
}
}

CakePHP 4 custom plugin dont find classes

I try to create a Custom Plugin for CakePHP 4. But everytime i become a error that the plugin cant find the classes of the plugin.
I load the plugin in the Application.php
use Wirecore\CakePHP_JWT\Plugin as CakePHPJwt;
$plugin = new CakePHPJwt();
$this->addPlugin($plugin);
In the composer.json file of cake its also loaded:
"autoload": {
"psr-4": {
"App\\": "src/",
"Wirecore\\CakePHP_JWT\\": "./plugins/CakePHP-JWT-Plugin/src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Test\\": "tests/",
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/",
"Wirecore\\CakePHP_JWT\\Test\\": "./plugins/CakePHP-JWT-Plugin/tests/"
}
}
and i create a file in /plugins/CakePHP-JWT-Plugin/src/Middleware/JwtMiddleware.php with example code of the documentation Middleware. I changed the namespace of the example code to
namespace Wirecore\CakePHP_JWT\Middleware;
after this i try to load the middle in the middleware function of the plugin but everytime i become this error:
Class 'Wirecore\CakePHP_JWT\Middleware\TrackingCookieMiddleware' not found
here the code of the middleware function:
use Wirecore\CakePHP_JWT\Middleware\TrackingCookieMiddleware;
$middlewareQueue->add(new TrackingCookieMiddleware());
return $middlewareQueue;
i have tried to change the namespace but it does not work, and i try it with composer dumpautoload but again it changed nothing. Any ideas ?
The autoload section in the composer file is what tells PHP how to find your namespaces on disk. Your namespace prefix for the class, Wirecore\CakePHP_JWT, is not the namespace you listed in the autoload section, you listed Wirecore\CakePHP-JWT-Plugin. Either fix the namespace declaration to match autoload, like so:
use Wirecore\CakePHP-JWT-Plugin\ .. etc
.. or change fix the autoload section to match the name listed in your namespace declaration:
"autoload": {
"psr-4": {
"Wirecore\\CakePHP_JWT\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Wirecore\\CakePHP_JWT\\Test\\": "tests/",
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/"
}
}
Also, I'm not positive what standards your following here, but they potentially don't look right.
Is this a standalone plugin? If so, I'd mirror the structure from another standalone plugin like https://github.com/dereuromark/cakephp-geo/
If this isn't a standalone plugin (which is what seems more probable), but just a custom plugin being put directly into an existing CakePHP app, you're classes should be stuck in /plugins not /src, per the docs https://book.cakephp.org/4/en/plugins.html#creating-your-own-plugins
You might want to just use the Bake utility as a starting point (that'll solve your autoload issues too!) and copy your code into the classes it creates instead.

Composer psr-4 autoload issue

I have problem with autoloading with composer when i use psr-4 autoloading it doesn't work and give me error.
I tried:
$ composer dump-autoload
and a lot of other thing but it doesn't work without
require one;
error:
You are now a master builder, that knows how to autoload with a
classmap!
Fatal error: Uncaught Error: Class 'VegithemesLibraryGreeting' not
found in /home/vaclav/Server/vssk/VSSK/project/aldemo/index.php:10
Stack trace: #0 {main} thrown in
/home/vaclav/Server/vssk/VSSK/project/aldemo/index.php on line 10
composer.json:
{
"autoload": {
"files": ["mylibrary/functions.php"],
"classmap": [
"classmap"
],
"psr-4": {
"one\\": "src/"
}
}
}
greeting.php (file with class to load):
<?php
namespace one;
Class Greeting
{
public function hi()
{
return "We got you covered";
}
}
index.php file:
<?php
require 'vendor/autoload.php';
echo lego();
$cm = new Cmautoload;
echo $cm->classmap();
$vt = new oneGreeting;
echo $vt->hi();
It is generally good practice to capitalize the first letter of a class name. It also adheres with the rules of PSR-1.
Change your composer.json file to look like this:
{
"autoload": {
"files": [
"mylibrary/functions.php"
],
"classmap": [
"classmap"
],
"psr-4": {
"One\\": "src/"
}
}
}
Now, in your index file. We are going to import the autoloader. To do this simply require it:
require 'vendor/autoload.php';
Now that you have included the autoloader, go into every class and set the namespace.
The classes in your src/ == namespace One;
Check your classes in src/ and make sure they are all namespaced. Meaning that they should all have the following line of code at the top:
namespace One;
As mentioned before, update your file names to Foo.php and class names to
class Foo to adhere to PSR. (This is not required but highly recommended and standard procedure.)
To use one of your classes you would say use One\Greeting;
$greeting = new Greeting();
echo $greeting->hi(); //"We got you covered"
I found the problem, there was missing:
use One\Greeting;
In a lot of tutorials there isn't a word about it.
Another relevant detail about this is the namespace must match with the folder structure.
If not it will throw the warning.
In my case the filename was
src/One/GreetingClass.php
but the class name was in lowercase, causing this error:
class Greetingclass {
Changing the class declaration as GreetingClass fixed the issue.

Composer autoload not including my custom namespaces (Silex)

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

Composer psr-0 autoloading of custom namespaces does not work

I have trouble adding my own namespaces to composer with PSR-0. I have read this and this but I still can't make it work
composer.json
{
"require": {
"klein/klein": "2.0.x",
"doctrine/orm": "2.4.4"
},
"autoload": {
"psr-0": {
"mynamespace": "src/"
}
}
}
The src folder is placed inside the same directory as composer.json
The src directory has the following structure
src
└── mynamespace
├── Keys.php
Keys.php
<?php
namespace mynamespace\Keys;
define ("API_KEY", "XXXXXXXXXXXX");
?>
index.php
use Klein\Klein;
use mynamespace\Keys;
require_once __DIR__ . '/vendor/autoload.php';
$klein = new Klein(); // works
echo API_KEY; // Undefined constant
You can only load classes, interfaces and traits with autoloading.
Because all you do is add a use clause which does not do anything by itself with autoloading (i.e. it does not load something), and you do not use a class, nothing happens.
I recommend using class constants. They may be put into classes or interfaces:
namespace mynamespace;
interface Keys {
const API_KEY = 'XXXXXXXX';
}
use mynamespace/Keys;
echo Keys::API_KEY;

Categories