Autoload parent class from a different directory - php

I´m having a hard time trying to autoload parent classes
this is my directory structure
controllers
--- Homepage.php
core
--- Controller.php
index.php
This is the content of my index.php
function __autoload($class_name)
{
$file_name = str_replace("\\", DIRECTORY_SEPARATOR, $class_name) . '.php';
include $file_name;
}
$homepage = new \Controllers\Homepage();
$homepage->index();
This is the content of my controllers/Homepage.php file
namespace Controllers;
class Homepage extends Controller
{
public function index()
{
echo 'Homepage::index';
}
}
and this is my core/Controller.php
namespace Core;
class Controller
{
protected function something()
{
echo 'blablabla';
}
}
when i run index.php the autoloader loads Hompege correctly but is looking for Controller.php in the controllers directory I tried extending from class Homepage extends Core\Controller but now is trying to get it from controllers/core

This is how the namespaces are resolved:
class Homepage extends Controller
Controller is resolved to Controller\Controller because it is a non-qualified class name (like a relative file path), and the current namespace is used.
class Homepage extends Core\Controller
Core/Controller is resolved to Controller\Core\Controller because it also is a non-qualified class name and a sub-namespace of the current namespace is used
class Homepage extends \Core\Controller
\Core\Controller is a fully qualified class name and will be resolved to Core\Controller
use Core\Controller; class Homepage extends Controller
Here the use statement specifies that a non-qualified Controller is treated as Core\Controller
Variants 3 and 4 will work as intended.

Related

Cannot declare class mPDF, because the name is already in use

I'm trying to include a library/plugin named mPDF. Here is my code:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class HomeController extends Controller {
public function cert() {
require_once base_path('App/Http/Controllers/mpdf/mpdf.php');
$mpdf=new mpdf\mPDF();
return true;
}
}
I keep getting the error:
Cannot declare class mPDF, because the name is already in use
When I comment out the require_once line, I get:
Class 'App\Http\Controllers\mpdf\mPDF' not found
mpdf.php has a class named mPDF. It only has one class with this name. This class appears nowhere else in my project. No other classes have the same name.
Update the name space of your
App/Http/Controllers/mpdf/mpdf.php file
put something on top of the file like :
namespace App\Http\Controllers\MyPDF;
After defining name space in your library class file App/Http/Controllers/mpdf/mpdf.php file, include that class into your controller as
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Http\Controllers\MyPDF\mPDF;
class HomeController extends Controller {
public function cert() {
//require_once base_path('App/Http/Controllers/mpdf/mpdf.php');
$mpdf=new mPDF();
return true;
}
}
I would recommend not to create library class as a controller or inside controller directory, create library classes in /app/ directory and provide your own namespace.
Actually Namespaces are same as package name in JAVA, you just need to define proper name space for your class and include your class without any conflict if there are same classes. Same class name and different name space will not cause conflict.
Within App/Http/Controllers/mpdf/mpdf.php file make sure you have the namespace.
namespace App\Http\Controllers\mpdf;
Then change your code to:
namespace App\Http\Controllers;
class HomeController extends Controller {
public function cert() {
$mpdf=new mpdf\mPDF();
return true;
}
}
The use use App\Http\Controllers's within the above code are not required as you're already in the namespace.

Importing custom class inside a controller

I created a class at Controller folder of Cake project like this:
<?php
class Hi
{
function __construct(){ }
public function hi()
{
echo "hi!";
exit;
}
}
Then in a controller, I tried to include it:
<?php
namespace App\Controller;
use App\Controller\AppController;
include_once "Hi.php";
class MyController extends AppController
{
public function sayHi()
{
$a = new Hi();
$a.hi();
}
}
Here is the error I'm having:
Fatal error: Cannot declare class Hi, because the name is already in use in path\api\src\Controller\Hi.php on line 2
What's going on?
MyController.php and Hi.php are in the same folder. I'm using PHP 7.
Including a file won't make the classes in that file part of the current namespace, as namespaces are a per-file functionality.
http://php.net/...namespaces.importing.php#language.namespaces.importing.scope
Your Hi class will be declared in the global namespace, and your new Hi() will cause PHP to look for it in the current namespace, ie it will look for App\Controller\Hi, which doesn't exist, hence the composer autoloader kicks in, and will map this via a PSR-4 namespace prefix match to src/Controller/Hi.php, which will include the file again, and that's when it happens.
http://www.php-fig.org/psr/psr-4/
Long story short, while using new \Hi() would fix this, you better not include class files manually, or declare them in paths where they do not belong. Instead declare your files and classes in a proper autoloading compatible fashion, that is for example with a proper namespace in a path that matches that namespace, like
namespace App\Utils;
class Hi {
// ...
}
in
src/Utils/Hi.php

Namespace A - floder A / subfolder B- sub namespace B ?

I am new with php namespaces and I encounter an issue. Here is a resume of my code :
In folder controller:
namespace controller;
require_once 'templates/Singleton.php';
class OrderConfirmationController extends Singleton {
...
}
In sub folder controller/templates:
// class out of any namespace
class Singleton {
...
}
I always have an error message even if I extends OrderConfirmationController with \Singleton.
I am not sure to understand why.
Make sure you include the namespace reference when you extent the singleton class. An easy way would be with a use statement at the top of your controller and and appropriate alias.
use \SingletonNamespace\Singleton as Singleton;
Or
class OrderConfirmationController extends NameSpace\Singleton {

how to make a directory in controller - laravel

I created a Panel directory inside Controller directory .
there is a login function inside AdminController.php
class AdminController extends Controller
{
//
public function login()
{
return 'test';
}
}
in routes.php I wrote a route like this:
Route::get('/cp/login','Panel\AdminController#login');
but when I run below url I got some errors that there isn't exist this controller :
http://localhost:8000/cp/login
ReflectionException in Route.php line 280: Class
App\Http\Controllers\Panel\AdminController does not exist
Try adding the appropriate namespace to the top of the AdminController file, you will also need to specify the namespace for the Controller class that it extends, as they are under different sub-namespaces.
You can read more about PSR-4 autoloading here http://www.php-fig.org/psr/psr-4/.
Based on the directory structure that you have there it should read
<?php
namespace App\Http\Controllers\Panel
use App\Http\Controllers\Controller;
class AdminController extends Controller {
//..
}
you should add the namespace to the contorller
Change you namespace to
namespace App\Http\Controllers\Panel;
Laravel will resolve controllers based on your name spacing, not on your directory structure.

Putting a base model extended class in the application/models folder

I created a base_model extends CI_Model class and put it in application/model. Then, I created another class that extends base_model, but I get the following error:
Cannot find this class
Other resources told me to put the base_model in:
application/core
or:
application/libraries
However, I would like to put it in application/models for convenience. Can I put this class in application/models and still have it work correctly?
Try putting a MY_Model class in your application/core folder instead. First-level inheritance was built into CI by default, i.e.:
{APPATH}/core/MY_Model.php:
<?php
class MY_Model extends CI_Model {
public function __construct()
{
parent::__construct();
}
}
In that same file, if you want alternate parent classes, try:
...
class Base_model extends MY_Model {
public function __construct()
{
parent::__construct();
}
}
...
If you don't put it in MY_Model, YOU ARE RESPONSIBLE for loading the base model first (before an extended class references it), AND you can't have a file in your models/ folder called Base_model.php, for example.

Categories