I have a base abstract class, say Base.php located at /lib/Helper/Base.php. Now, I have another class, say Awesome.php located at /lib/Helper/Awesome/Awesome.php, and this class needs to extend Base.
I have defined my namespaces as follows:
Base.php
<?php namespace Helper;
abstract class Base
{
}
Awesome.php
<?php namespace Helper\Awesome;
class Awesome extends Base
{
}
Right now, this says that class Base was not found. I tried to use require_once and/or include to the path of Base.php and they also didn't work. What am I doing wrong?
You are including the file, and that is the right thing to do. But you are also using
namespaces.
the namespace is not a folder, that means the namespace 'Helper' is not a folder but a logical hierarchy. In order to use the class Base in he logical namespace Helper the Awesome class needs to extend the Base class with the full logical path i.e. \Helper\Base.
namespace Helper\Awesome;
class Awesome extends \Helper\Base {
}
or use the use/as keyword instead (like c# using statement) .
namespace Helper\Awesome;
use \Helper\Base as Base;
class Awesome extends Base
{
}
more information can be fount at the php.net site.
here is a direct reference: http://php.net/manual/en/language.namespaces.importing.php
Related
I encountered the topic called 'namespace' in php after I started working with Laravel. While trying to understand namespace I found that to extend a class under a namespace, I need to include that class in my current page. Like the following:
directory '..\teacher\Teacher.php'
namespace Teacher;
class Teacher{
public $headTeacher='mr X';
}
to extend the calss i need to include that page as well as use the namespace
directory '..\studnet\student.php'
use \Teacher\Teacher; //use the namespace
include('../teacher/Teacher.php'); // include the page
class mathTeacher extends Teacher{
public function headTeacherName(){
echo $this->headTeacher;
}
}
$student=new mathTeacher();
$student->headTeacherName();
I am wondering how Laravel only use namespace to include classes. Like if I create a controller called 'userController'. The structure of the page is
namespace App\Http\Controllers;
class userController extends Controller{
}
They never included the php page which holds the 'controller' class. But they were able to extend it somehow. Also I can use "View" ,"Auth" just by using the use View or use Auth command. How is it done? How can I implement the same with the code I have provided? Thanks in advance.
Laravel uses composer.php for autoloading the classes. All classes in the autoload directory will be pre loaded. So you can just use the namespace and consume anywhere across the application.
Learn more about composer, composer config can be found on composer.json in your root path for the application
I have a Symfony bundle where I will have to use a custom class. This class does not have to be accessible from all the website, but just in a controller of this bundle.
I have seen a few solutions relative to the vendors, but this is quite heavy and not necessary in my case.
Does someone have a simpler solution?
This is what namespaces are for.
From php.net:
What are namespaces? In the broadest definition namespaces are a way of encapsulating items.
Simply put, include your namespace at the top of your custom class.
src/Acme/DemoBundle/Model/MyClass.php
<?php
namespace Acme\DemoBundle\Model;
class MyClass { // ...
and use it in your Controller:
src/Acme/SomeOtherBundle/Controller/DefaultController.php
<?php
namespace Acme\SomeOtherBundle\Controller;
// ...
use Acme\DemoBundle\Model\MyClass; # can be used in any class in any bundle
// ...
class DefaultController extends Controller { // ...
Class must be created in Acme\Bundle\Model namespace and folder, not \Class! Who says this?!
// ../src/Acme/Bundle/Model/Utility.php
<?php namespace Acme\Bundle\Model;
class Utility:
..
Using in controllers:
<?php ..
use Acme\Bundle\Model\Utility;
$x = new Utility(); // FINE!:)
Name of file (Utility.php) must be equal to the class name.
I am working on a php sdk rewrite project and the client wants to get PSR standards done. I am looking at the standards page here
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
One thing what i am not able to understand, if i use name spaces in my class do i still need to use include or require or use. I mean the whole reason of autoload beats the purpose right ?
For example, say i have a class this way,
namespace Employee\Department;
Class Department
{
//code
}
and i have another class which uses this class by extending it,
namespace Employee\community;
Class Community extends Department
{
//code
}
so does the above code make it to psr-0 standard considering that i have an autoload function exactly thats on the link above.
The second example is going to assume Department is in the Community namespace so in this case you would need a use statement. Also both of your examples would use the namespace Employee not Employee\Whatever for example lets assume the following layout:
Employee/
Community.php
Community/
Manager.php
Department.php
Department/
Manager.php
Then we would see the class/namespaces like the following
namespace Employee;
class Department {
}
///////////
namespace Employee;
class Community extends Department {
}
/////////////
namespace Employee\Department;
class Manager {
}
/////////////
namespace Employee\Community;
use Employee\Department\Manager as BaseManager;
Class Manager extends BaseManager {
}
For your understanding, autoloading works by registering the autoload function in the autoload stack via spl_autoload_register; this allows the function to be invoked whenever a new Class() statement is executed (more info).
On the other hand, the FIG standard for autoloading, PSR-0, defines how a namespace will be translated into a filename by a PSR-0 autoloader function. For example, given the namespace Vendor\Foo, the autoloader will look for the file Vendor/Foo.php having the following code
namespace Vendor;
class Foo
{
public function do()
{
echo "Foo";
}
}
Therefore, following the mandatory requirements, a PSR-0 compliant namespace resolves to the correct PHP file which could otherwise have been included using a require or include.
If I read your intentions correctly, you just need the following namespace in both code snippets:
namespace Employee;
Of course, this is not a PSR-0 namespace because there is no vendor name (unless your vendor name is 'Employee'). Anyway, using this namespace in your two code snippets will work fine.
However, if you intended to keep them in separate namespaces, then the autoloader won't figure out Department in extends Department in the second snippet. You will have to either import the namespace or explicitly specify it as so:
namespace Employee\community;
class Community extends Employee\Department\Department
{
//code
}
I imagine that you did not expect the full class names from your snippets to be Employee\Department\Department, and that is why I first suggested keeping the same namespace for your purposes.
When using the pseudo namespacing pattern of PEAR and Zend, it is common to come across class heirarchies that look like this:
Zend/
Db.php
Db/
Expr.php
Where DB.php contains a class named Zend_Db and Expr.php contains a class named Zend_Db_Expr. However, when you try to convert the old 5.2 psuedo namespacing into PHP 5.3 namespacing you are presented with a case where a namespace and a class share a name. Since the use operator can import either a namespace or a classname this leads to ambiguity.
Here's an example of an app I'm working on converting:
App/
Core.php
Core/
Autoloader.php
Here the base directory and namespace are App. In the top level of the name space is a Core class:
namespace App;
class Core { }
In the Core directory are various other core classes, some of which use the main Core. Under the pseudo namespacing pattern, this isn't a problem. But in the real namespacing pattern it creates this situation:
namespace App\Core;
use App\Core as Core; // What is this importing? Namespace or class?
class Autoloader {
public function __construct(Core $core) {}
}
Is this defined? What is actually imported here?
Simply both. It is not real import, just a hint for compiler, that every encounter of this alias in class related operations should be expanded to this declaration. In php namespace is just part of class so just think of it like this
$alias = 'Zend_Db';
$zendDB = new $alias;
$aliasExpr = $alias . '_Expr';
$expr = new $aliasExpr;
I have been searching websites to try and get a handle on using PHP namespaces, but they all seem quite vague but what they're trying to do is easy to understand!
My question is: I have a file called people.php and in it is defined class called people. If I create another file called managers.php in the same folder can I define a class again called people which extends the original people class but in the namespace of managers, if so do I have to 'include' the original people.php and if so do I put the include after the writing: namespace managers?
Namespaces are a way to group your related classes in packages. What you describe could best be put under a single namespace like
<?php // people.php
namespace com\example\johnslibrary\people;
abstract class People {
}
and then
<?php // manager.php
namespace com\example\johnslibrary\people;
require_once 'path/to/People.php'; // can better use autoloading though
class Manager extends People {
}
because a Manager is a subclass of People, so there is not much of a reason to put them into their own namespace. They are specialized People.
If you want to Managers to be in their own namespace, you can do so, but have to use the fully qualified name when using the extends keyword, e.g.
<?php // manager.php
namespace com\example\johnslibrary\managers;
require_once 'path/to/People.php';
class Manager extends \com\example\johnslibrary\people\People {
}
or import the People class first
<?php // manager.php
namespace com\example\johnslibrary\managers;
use com\example\johnslibrary\People as People;
require_once 'path/to/People.php';
class Manager extends People {
}
See the PHP Manual on Namespaces for extensive documentation.
// people.php
<?php
namespace People;
class People {}
// managers.php
<?php
namespace Managers;
require_once __DIR__.'/people.php';
class People extends \People\People {}
I have old PHP Class and i need to use it in new PHP file as for example:index.php has to use iClass.php. But before using the OLD iClass.php i have to modify it as below, so that i can use it in index.php.
iClass.php:
namespace ic;
class iClass {
public static function callMeFromClass() {
echo 'OK - you have called me!';
exit;
}
}
index.php
namespace inex;
require_once 'iClass.php';
use ic\iClass;
iClass::callMeFromClass();