PHP adding custom namespace using autoloader from composer - php

Here is my folder structure:
Classes
- CronJobs
- Weather
- WeatherSite.php
I want to load WeatherSite class from my script. Im using composer with autoload:
$loader = include(LIBRARY .'autoload.php');
$loader->add('Classes\Weather',CLASSES .'cronjobs/weather');
$weather = new Classes\Weather\WeatherSite();
Im assuming the above code is adding the namespace and the path that namespace resolves to. But when the page loads I always get this error:
Fatal error: Class 'Classes\Weather\WeatherSite' not found
Here is my WeatherSite.php file:
namespace Classes\Weather;
class WeatherSite {
public function __construct()
{
}
public function findWeatherSites()
{
}
}
What am I doing wrong?

You actually don't need custom autoloader, you can use PSR-4.
Update your autoload section in composer.json:
"autoload": {
"psr-4": {
"Classes\\Weather\\": "Classes/CronJobs/Weather"
}
}
To explain: it's {"Namespace\\\": "directory to be found in"}
Don't forget to run composer dump-autoload to update Composer cache.
Then you can use it like this:
include(LIBRARY .'autoload.php');
$weather = new Classes\Weather\WeatherSite();

Related

Can't call global class from namespaced class in PHP. Using Composer's autoload

I'm using composer to create an autoload file, and all that jazz works as expected.
The problem is: when I try to call a globally defined class, it keeps looking inside the namespace, instead of the global scope. Even though I use the \ escape as in "new \WC_Order();"
I've configured composer.json to autoload MyNamespace in the correct dir and include 'vendor/autoload.php' in my wordpress theme's function.php, and create a new instance, which works. Everything about this process works.
include 'vendor\autoload.php';
$myclass = new MyNamespace\MyClass()
Here's where the error occurs in the file 'MyNamespace\MyClass.php:
namespace MyNamespace;
class MyClass {
public function __construct()
{
$order = new \WC_Order(1234);
}
}
PHP throws a fatal error:
Fatal error: Uncaught Error: Class 'MyNamespace\WC_Order' not found in ...\MyNamespace\MyClass.php
Any tips or hints would be greatly appreciated!
Edit: My composer/directory setup
composer.json
{
"autoload": {
"psr-4": {
"MyNamespace\\": "MyNamespace"
}
},
"require": {
"guzzlehttp/guzzle": "^6.3"
}
}
functions.php is in the root and the class is in MyNamespace/MyClass.php
I figured it out. Since this is Wordpress, I should have hooked into an action. Woocommerce hadn't been loaded yet. As soon as I used add_action('init', 'doMyStuff'); it worked.
I still find it strange that the message was that it couldn't find the class inside the namespace though.
Try:
include 'vendor\autoload.php';
$myclass = new \MyNamespace\MyClass();
Or:
include 'vendor\autoload.php';
use MyNamespace\MyClass;
$myclass = new MyClass();
You can find a guide here: https://www.php.net/manual/en/language.namespaces.importing.php

How to add custom class in laravel 5.4.10

I am new in laravel.
I am writing following code in the controller method.
include_once(app_path() .'/Classes/Pgp_2fa.php');
$pgp = new Pgp_2fa();
Following errors are shown.
FatalThrowableError in AuthController.php line 146: Class
'App\Http\Controllers\Pgp_2fa' not found
You have to use the correct namespace for your class.
If you are not using any namespace, you should add a \ in front of the class to let php know that the class exists in the root namespace. Otherwise php will look in the current namespace which is App\Http\Controllers when you are in a controller.
$pgp = new \Pgp_2fa();
This is not just Laravel behavior but php in general.
When you add new classes there are couple way to use them. (I mean, load them)
If your classes has unique name and don't use namespace, then you can add backslash \ start of the class.
$class = new \Pgp_2fa;
But if you want to define them namespaces and use with same name so
many times, then you have to add these classes in composer.json. Open your
composer.json and come into "autoload" section and define class
directory in classmap
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"app/Classes", // so all classes in this directory are going to load
],
And don't forget to say composer dump-autoload after these changes and creating new classes
If you don't want to dump your composer when you add a new class,
then you may want add those classes inside of the psr-4 section in composer
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\Classes\\": "app/Classes",
}
},
you need to add namespace for your custom class
or just add slash on your class name. like :
$pgp = new \Pgp_2fa();
You can call inside the constructor like below, and you can use the
$Pgp_2fa variable in remaining function
class controllername extends Controller
{
public function __construct(Route $route,Request $request)
{
$Pgp_2fa = new \Pgp_2fa();
}
}
You can easily add your custom classes by added it to Composer's autoload array. Go to composer.json and add it to:
"autoload": {
"files": [
"app\\Classes\\Pgp_2fa.php"
]
},
Now in your app folder, under classes folder add your Pgp_2fa.php file which will have your class. You can use it anywhere you want, it should be automatically auto-load-ed.
After adding your class write command:
composer dumpautoload to refresh autoload class mapping.
For example, There is our class Common.php in a directory called Mylibs in app directory.
app/mylibs/Common.php
we need to namespace App\Mylibs;
namespace App\Mylibs;
class Common {
public function getSite() {
return 'AmirHome.com';
}
}
Now, you can access this class using the namespace within your classes just like other Laravel classes.
use App\Mylibs\Common
in Controller:
namespace App\Http\Controllers;
use App\Mylibs\Common;
class TestController extends Controller {
protected $common;
public function __construct(Common $common) {
$this->common = $common;
}
public function index() {
echo $this->common->getSite();
}
}

How can I load a library in Codeigniter via autoload composer?

I have installed autoload via composer in CodeIgniter and I also tested it if the file autoload.php is included and it's. So, if i have a library called Pager in libraries, then how can I instantiate (load) the Pager class? It's a fresh CodeIgniter installation, version 3.1.2
I set in config this:
$config['composer_autoload'] = TRUE;
I have try the following ways in Welcome controller:
$pager = new libraries\Pager(); //Class 'libraries\Pager' not found
$pager = new \libraries\Pager(); //Class 'libraries\Pager' not found
$pager = new \library\Pager(); // Class 'library\Pager' not found
$pager = new Pager(); // Class 'library\Pager' not found
And here is the Pager class from libraries directory:
class Pager {
function __construct()
{
parent::__construct();
echo __CLASS__;
}
}
Thank you for help!
This is in fact unrelated to CodeIgniter.
You need to tell composer that you have your own PHP classes that aren't among autoloaded files.
In your composer.json add one of these:
{
// ...
"autoload": {
"psr-4": { "MyNamespace\\": "src/library/MyNamespace" },
"files": ["src/some/custom/filepath.php"]
}
}
Then run in console update to update autoload.php with your new config:
$ composer update
Now every time you use a class from MyNamespace such as MyNamespace\MyClass it'll look for file src/library/MyNamespace/MyClass.php.
Also, file src/some/custom/filepath.php is always included automatically so you don't need to include it manually. (I don't know what's your usecase).
See for more info: https://getcomposer.org/doc/04-schema.md#autoload
Do you have added it in autoload.php
$autoload['libraries'] = array(
'pager'
);

How to use __autoload function when use composer load

app/Core
contollers
This is my website structure to put the main class, I user composer psr-4 rule to import class under app/Core folder.
composer.json
{
"autoload": {
"psr-4": {
"Core\\": ["app/Core"]
}
}
}
index.php
<?php
include 'vendor/autoload.php';
new Core/Api; // it's work
It works fine, but I want to autoload class under controllers folder without use namespace, so I use __autoload function like:
index.php
<?php
include 'vendor/autoload.php';
function __autoload($class_name) {
include 'controllers/' . $class_name . '.php';
}
new Test // Fatal error: Class 'test'
If I remove include 'vendor/autoload.php'; it will work, so I think the code is correct, I know I can use classmap in composer.json, but it need to dump-autoload everytime I add a new class, how to deal with the conflict?
You do not have to use your own implementation of autoloading. You could use composer autoloading for all classes.
{
"autoload": {
"psr-0": { "": "src/" }
}
}
https://getcomposer.org/doc/04-schema.md#psr-0
Or, you could create class map
https://getcomposer.org/doc/04-schema.md#classmap
p.s. indeed, you could use empty namespace with psr-4.

Laravel Class Not Found FatalErrorException

Here is the error I see.
Class 'A\B\C\D\F\ETypeRequiredException' not found
What I Tried
composer dump
composer dump-autoload & composer dump-autoload -o
Moved the class to A\B\C\D\R and voala! It is working.
Moved back and again, not working.
Code Snippets
The page I see the error:
<?php namespace A\B\C\D\R;
use A\B\C\D\EInterface;
use A\B\C\D\F\ETypeRequiredException;
class E implements EInterface
protected function foo()
{
if(empty($this->bar)) { throw new ETypeRequiredException("Bar is undefined."); }
}
The Page That Never Loaded
<?php namespace A\B\C\D\F;
class ETypeRequiredException extends \UnexpectedValueException {}
If you are using psr-0 to resolve your namespaces:
"psr-0": {
"X": "app"
}
You should be aware that it will use you path structure, so
ETypeRequiredException
Should be put in
app/A/B/C/D/F/ETypeRequiredException.php

Categories