How to set proper namespace for external class (FPDF) - php

So I'm really lost at the moment, trying to find a way to use FPDF library that I got with composer. It's confused in my head so I hope I will be clear enough.
I have this composer file :
{
"require": {
"phpmailer/phpmailer": "^6.0",
"stripe/stripe-php": "^6.16",
"setasign/fpdf": "1.8.1"
},
"autoload": {
"psr-4": {
"PsyQuimper\\":"src/calendrier/php/"
}
}
}
And an php file to require once all my classes from composer :
require_once $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';
I want to create bills with FPDF library. Here's the bill.php file start :
<?php
use \setasign\fpdf\FPDF;
class Bill extends FPDF {
private $billString;
private $billDate;
function __construct($date) {
$this->billDate = $date;
parent::__construct();
}
Yet when I create a new Bill('2015-05-05') I have an error message :
Class 'setasign\fpdf\FPDF' not found
I don't understand what I am doing wrong. Anyone willing to enlight me here ?
EDIT :
I replaced use \setasign\fpdf\FPDF;
with use FPDF
simple as that. Thanks

setasign/fpdf does not use any namespaces: https://github.com/Setasign/FPDF/blob/1.8.1/fpdf.php.
You should pretend class name with \ to indicate that class from global namespace should be used:
class Bill extends \FPDF
or import this class:
use FPDF;
However in your case your Bill class is not namespaced, so you can just remove use \setasign\fpdf\FPDF; and everything will use global namespace by default.
It is not strict convention to use than same namespace as package name - you need to look into documentation/code/composer.json to find actual namespace for dependencies.

Related

Class Not Found in PHP Laravel 6.x when another class extends

I always get the class not found exception in php laravel 6 when i create a class and extend a parent class named A which is located in the same directory.
However, another child class that is located in same directory could extend class A successfully.
In addition, i couldn't also instantiate the class A due to class not found exception in another .php file.
Please help me on this.
Thanks in an advance.
Parent class: myContext
<?php
namespace config\models;
class myContext {
public static $conn;
...
}
Class myUser: extension is fine.
<?php
namespace config\models;
class myUser extends myContext {
private $name;
...
}
Class oauth: extension returns myContext class not found.
<?php
namespace config\models;
class oauth extends myContext {
private $user;
}
Instantiate the class - returns class not found.
<?php
use config\models\myContext as context;
$cont = new context();
Check whether the namespace is added correctly when the parent class is imported.
Refer
https://www.quora.com/What-is-namespaces-and-use-in-Laravel
external classes and PHP files in Laravel - Class not found
Laravel - Model Class not found
Laravel 6: Class 'Form' not found
To get the provided example codes to work you need to use require_once
<?php
require_once('models/myContext.php');
use app\config\models\myContext as context;
$test = new context();
A search on SO brought me to this source
You try to add this line of code in the composer.json file, then execute the composer dumpautoload command on the command line
In composer.json file,
"autoload": {
"psr-4": {
"App\\": "app/",
"config\\models\\": "config/models"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
After that composer dump-autoload.
have you add autoload for config/ folder in composer.json. Laravel only default autoload for app/

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();
}
}

Composer autoload doesn't find class

H, my composer json file autoload with psr-4 a Class, but when a Call that Class, php return error: Error: Class 'ClassA\Tae' not found
Here json autoload
"autoload": {
"psr-4": {
"ClassA\\": "includes/ClassA/",
"": "includes/"
}
}
and my php class that require ClassA is this
require_once __DIR__ .'/../vendor/autoload.php';
use ClassA\{ Rate, Tae, Taeg };
class TestTaeg extends \PHPUnit\Framework\TestCase {
public function test_tae() {
$obj = Tae::init( 5, 12 );
}
Do you know why I cannot find ClassA ?
I run the code with phpunit on cli, with this syntax (is the first time that I use phpunit)
../vendor/phpunit/phpunit/phpunit ./test-general.php
Thx
Are you namespacing your classes right ? To be honest your psr-4 autoloading looks a bit messy, I am asuming you are autoloading everything even when you dont need those.
So if you please share a screenshot of your folder structure, I can try to recreate your issue and probably suggest a solution.

What is autoload in composer.json and how can we use this in laravel?

I am just start working with Laravel, want to create a custom class and want to call this class in every controller. For this, I create a Customer class in app/Library/ folder.
When I tried to autoload this library via composer, json it's giving an error:
Could not scan for classes inside "App/Library/Customer" which does not appear to be a file nor a folder.
How can we use autoload class in controllers?
Customer.php
<?php
namespace App\Library;
use App\Model\User;
class Customer
{
public function login($user_name,$password){
$data = User::where('email', $user_name)
->where('password', $password)
->first();
return $data->id';
}
}
Autoload section of Composer.json
{
"autoload": {
"classmap": [
"database",
"app/Library/Customer"
],
"psr-4": {
"App\\": "app/"
},
"files" : [
"app/Helper/helper.php"
]
}
}
I think you're not understanding what the composer autoload is there for. You use this to include libraries and their dependencies, not really for classes you've created in your app.
What you're better off doing is when you create the controller add in the class you want to use eg:
<?php
use App\Library\Customer;
You will need to put this in every controller.
You should remove it from the classmap group and just add the proper namespace and class. You can see all the psr-4 standards here: http://www.php-fig.org/psr/psr-4/
Lets say you have a folder structure like this:
app
-> Library
-> Customer.php // namespace App\Library; class Customer{}
-> Model
-> User.php // namespace App\Model; class User{}
And all the files should autoload as long as you use the proper namespace and class names.
By the way you should use the Auth facade instead: https://laravel.com/docs/5.4/authentication
There is no need to classmap as already psr-4 autoloading is in place. You've to understand how it works. then you can simply import your classes using use keyword, like this
<?php
use App\Library\Customer;
For more information read PSR-4: Autoloader and take this Tutorial

Codeception/AspectMock Parent class not found by locator

I have a problem with Codeception/AspectMock.
When using custom autoloader and try to create an instance of a class which has parent form the same custom namespace I have this error:
PHP Fatal error: Uncaught InvalidArgumentException: Class [parent
class name] was not found by locator in
vendor/goaop/parser-reflection/src/ReflectionEngine.php:112
I have very simple setup:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$kernel = AspectMock\Kernel::getInstance();
$kernel->init([
'debug' => true,
'includePaths' => [__DIR__. '/lib'],
]);
$kernel->loadFile(__DIR__ . '/autoload.php'); // custom autoloader
$b = new \lib\B();
Class \lib\B:
namespace lib;
class B extends A {}
Class \lib\A:
namespace lib;
class A
{
public function getName()
{
return static::class;
}
}
Class B is loaded via my custom autoloader, but then the locator tries to load parent class A via composer autoloader and returns this error. Is this a bug, or I'm doing something wrong?
The topic starter has already got an answer on GitHub.
In order to use custom autoloader you should re-init ReflectionEngine with composite class locator that will be able to locate your classes or you can use CallableLocator with closure for resolving paths.
Or, even better you could switch your code base to the PSR0/PSR-4
For example:
$kernel->loadFile(__DIR__ . '/autoload.php'); // custom autoloader
\Go\ParserReflection\ReflectionEngine::init(
new class implements \Go\ParserReflection\LocatorInterface {
public function locateClass($className) {
return (new ReflectionClass($className))->getFileName();
}
}
);
$b = new \lib\B(); // here you go
If you can easily do a find and replace on your codebase, maybe you could refactor your code to PSR-4 autoloading standards and do away with the need for a custom autoloader altogether.
This is the spec https://www.php-fig.org/psr/psr-4/. I'll try and explain it as simply as possible.
Imagine changing your lowercase namespace lib to Lib, and setting that namespace to the src/ directory in your composer.json:
"autoload": {
"psr-4": {
"Lib\\": "src/"
}
}
After setting that, run composer dumpautoload. Then all you need to do is search and replace namespace lib;, replacing with namespace Lib;.
An example class located in src/Form.php would have namespace Lib; at the top, followed by class Form.
<?php
namepace Lib;
class Form
{
// code
}
Namespaces use the folder naming convention. All classes directly in src/ have namespace Lib;. If there are subdirectories, the directory name becomes part of the namespace. For example a file in src/Form/Field/Text.php would have namespace Lib\Form\Field; class Text {}.
<?php
namepace Lib\Form\Field;
class Text
{
// code
}
You can see the full convention in the link above, but the general rule is make any folders begin with a capital letter, as with your classname, and the autoloader should be able to find all of your classes.
This is probably the best practice solution for you, and again as I said, only requires a little bit of file renaming and namespace tweaking. Good luck!

Categories