I have created a php file under the Models folder provided by Laravel.
Inside I have:
// Filename: Models/Shoopy.php
namespace Whatever\Something;
class Shoopy
{
public function Toot(){};
}
Now in another Model file I am using that namespace:
use \Whatever\Something\Shoopy;
class AnotherModel
{
public function Spop()
{
$harr = new Shoopy();
}
}
It comes up with a Laravel error:
class Whatever\Something\Shoopy not found
Any ideas?
I know this is an older issue, but if you go into your composer.json file, you'll probably see something like...
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
What you can do is tell composer where Whatever should be, say if it was a different location (or sub-folder) from where Laravel normally keeps it's files.
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Whatever\\": "app/Whatever",
}
},
Classes need to exist in files with directory paths that match their namespace. This is according to the PSR-0 Standard. In your example, try placing your Shoopy class in the file:
app/models/Whatever/Something/Shoopy.php
And then see if the autoloader can find it.
Related
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"]
}
}
I'm trying to implement a clean architecture in laravel, thus I'm moving my own code to a src folder.
My controller is located in src\notebook\infrastructure but when i call it from routes\web.php this way:
Route::get('/notebook', 'src\notebook\infrastructure\NotebooksController#show');
i got this error:
Illuminate\Contracts\Container\BindingResolutionException
Target class [src\notebook\infrastructure\NotebooksController] does not exist.
http://127.0.0.1:8000/notebook
i also changed the namespace value in the class RouteServiceProvider from:
protected $namespace = 'App\Http\Controllers';
to
protected $namespace = '';
This is my notebook controller class:
namespace src\notebook\infrastructure;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class NotebooksController extends Controller
{
public function show($id)
{
echo 'controller from infrastructure folder';
}
}
My laravel and php version in composer.json are:
"php": "^7.2.5",
"laravel/framework": "^7.24",
I feel like i'm missing something stupid but can't figure it out what.
Did you add src folder into the autoload?
In composer.json file, you must have something like this:
"autoload": {
"psr-4": {
"App\\": "app/",
"Src\\": "src/" // add this
},
"classmap": [
"database/seeds",
"database/factories"
]
},
After changing it run composer dump-autoload.
And also don't forget to follow psr-4 rules and use Studly case namespace and class names.
namespace Src\Notebook\Infrastructure;
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.
I have autoload setup via PSR-4 which works perfectly fine. However I want to be able to add a specific class on top of that, that I can access from anywhere in the application.
This is what I have currently:
"autoload": {
"psr-4": {
"App\\": "app"
}
}
However I want to add a class called 'Redis' which is located in app/Lib/Redis.php so that from any Controller I can call Redis::method(); without having to add 'use App\Lib\Redis;' to the top of each file.
Is this possible?
This can't be done directly.
You could create a global function redis() and register than with composer:
"autoload": {
"psr-4": {
"App\\": "app"
},
"files"" {
"app/functions.php",
}
}
If this redis() function returned an instance of your Redis class, then I think that you could then do:
redis()->method();
Whether you should do this or not is another matter - unit testing becomes highly problematic. Personally, I would have a use statement and inject an instance of the Redis object into the constructors of the classes that need it.
Is it possible in some way to instantiate a class inside a namespace, in a method in another class inside another namespace? And with the requested class instantiated from a variable?
Example:
Class to be loaded from loader-class:
namespace application/pages;
class loader
{
private function __construct()
{
echo 'Class loaded...';
}
}
Loader-class:
namespace system/loader;
class loader
{
private $vars;
private function __construct($vars)
{
$this->vars = $vars;
}
private function load_class()
{
require(CLASSES . $this->vars['namespace'] . '/' . $this->vars['class'] . ".php");
use $this->vars['namespace'];
return new \$this->vars['namespace']\$this->vars['class']();
}
}
Sorry for the bit confusing formulation, but i couldn't think of better way to ask the question.
Thanks.
This is the general way to load in namespaces:
http://www.php.net/manual/en/function.spl-autoload.php
However there is a more popular way of doing it using Composer.
Download composer.phar and inside your project directory run: php composer.phar init
Following the interactions.
In your project root, create a src directory then add this to your composer.json file which generated: "autoload": { "psr-0": { "": "src/" } }
Your composer.json file should now look like this:
{
"name": "acme/sample",
"authors": [
{
"name": "Person",
"email": "person#example.com"
}
],
"minimum-stability": "dev",
"autoload": {
"psr-0": { "": "src/" }
},
"require": {
}
}
Run: php composer.phar install, which will generate a vendors directory and an autoload script.
Create your primary load php file and include the autoload.php file inside.
Now, your namespaces inside the src directory and any imported libraries in vendor, will be exposed to your application.
Checkout symfony/symfony-standard to see a full framework example.