Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a good way to use Namespaces in PHP

Tags:

namespaces

php

I have studied the use of Namespaces in PHP a while back but recently looking at a project that used the use keyword and then accessed the namespaced object as if they were normal without namespace.

My question is, is the code below correct, it hs a file index.php and uses the namespace MyLibrary\Base it then uses use to bring in \MyLibrary\Registry \MyLibrary\User and \MyLibrary\Request

It then can access any of these object without putting there namespace in front of them, so the actual code below the use section looks like a normal pre-namespace php file.

I am asking if this is how you use namespaces? Or am I missing something?

File: index.php

<?php
namespace MyLibrary\Base;

use \MyLibrary\Registry;
use \MyLibrary\User;
use \MyLibrary\Request;


class Base
{
    public $registry;

    function __construct($registry)
    {
        $this->registry = $registry;
        $this->user = New User;
        $this->request = new Request;
        # code...
    }
}
?>

File: registry.class.php

<?php
namespace MyLibrary\Registry;

class Registry
{
    public $user;

    function __construct($user)
    {
        $this->user = $user;
        # code...
    }
}
?>
like image 443
JasonDavis Avatar asked Dec 22 '11 20:12

JasonDavis


2 Answers

Yes. The use-statement imports the class- or namespace-name into the current scope. To write everything that short is the reason, why the PHP-devs implemented namespaces ;)

namespace MyFirstNamespace {
    class Foo {}
}
namespace MySecondNamespace {
    use \MyFirstNamespace\Foo as Bar;
    $foo = new Bar;
}

a) it make everything more readable, because its much shorter, than Vendor_Package_Foo_Bar_XyzClass and b) you can exchange the classes to use very fast.

# use \MyFirstNamespace\Foo as Bar; // I don't like Foo anymore
use \MyFirstNamespace\SimilarToFoo as Bar;
like image 61
KingCrunch Avatar answered Oct 10 '22 16:10

KingCrunch


Namespacing has a lot of advantages to it.

The first on is you can reuse method names and even class names if it makes sense provided they exist within a different namespace. Example:

namespace \myNamespace\data\postgres;

class DataBase extends \PDO
{
}

namespace \myNamespace\data\mysql;

class DataBase extends \PDO
{
}

You could even reuse names that are normally reserved for PHP functions

namespace \myNamespace\dir;

function makedir ()
{
    if (// some condition is true)
    {
        \makedir ();
    }
}

All of this is intended to make it easier to use code from different sources together without having to worry about naming conflicts. Provided programmers are courteous enough to observe a few simple rules then the chances of name conflicts are hugely reduced. Actually, pretty much the only rule you need to concern yourself with to avoid naming conflicts is to make the first level of your namespace your own. For example, use your company name, or some other way of identifying you as a unique vendor as the first level of your namespace and everything should be good.

For example I use \gordian as the root namespace in all the code I write, as I can then call my classes under that namespace anything I like without worrying about them colliding with someone who chose a different root namespace.

So what's wrong with PEAR conventions, you might ask? A lot of projects follow them, including the popular Zend framework.

The answer is names become very unwieldy very quickly. For instance, Zend, as it follows the PEAR convention, uses a sort of pseudo-namespacing. All the classes in the collection start with Zend_ and with each level of class hierachy add a further part to the name.
Ze As a result, you end up with class names like Zend_Db_Adaptor_Abstract and Zend_Dojo_Form_Decorator_TabContainer.

Should Zend update their framework to use namespaces (which I'm told is happening with Zend Framework 2.0) then they'd be replaced with \Zend\Db\Adaptor\Abstract and \Zend\Dojo\Form\Decorator\TabContainer instead. So what, you might ask? The answer is that you can alias them to much shorter names with the Use keyword, as you've already seen. This means you don't have to keep writing the full class name out, but only as far as to what you've aliased.

use \Zend\Dojo\Forn\Decorator as Dec;

$a = new Dec\TabContainer; // Not easy to do without namespaces!

Further more, if you're already in a given namespace, then you don't even have to use the use keyword to access other items within the same namespace by a short name, as it happens automatically for you in that case. For framework writers this is a huge timesaver.

For example, you might see something like the followign in Zend Framework 2 (as I'm not working on it in any way, this is purely an example and not from the actual ZF2 source).

namespace \Zend\Db\Adaptor;

class Postgres extends Abstract // We don't need to use \Zend\Db\Adaptor\Abstract here because it's in the same namespace already anyway
{
}

There are other benefits too, such as it makes autoloaders ridiculously simple to make (provided your namespace structure maps exactly onto your filesystem directory structure).

Namespaces can seem like one of those features that aren't really very important, or don't even seem to make any sense, but after using them for a little while their usefulness will suddenly become very obvious.

like image 30
GordonM Avatar answered Oct 10 '22 16:10

GordonM