Namespaces
lang_of_article_differ
want_proper_trans
Short history
Did you ever see the old-style php libs with classes like SomeLib_That_Can_Do_Something
? I've had. And that was the time when php didn't support namespaces (before PHP 5.3
). Why did people name their classes in such way? If you think that in such way they wanted to put in class name as much as possible information that class can do - you're wrong. People used such names to avoid names overriding.
For example i wrote a library called chat and the main class is Chat
. Someone want to use my library but noticed he already have such class, his application is big and many other parts make use of it. The only way to use my library for him - to change the name of my class everywhere its used in my lib.
Sounds pretty awful, yeah. And yes, its terrible. At least to modify external library, even if its only the class names;
To avoid such situations, people started to use such long names for classes, where at the begining was name of the vendor or name of the product followed by some architectural parts finishing with actual name of the class. That was awfull to - you needed to write such long class names in your programs but it worked!
In June 2009 guys from Zend
thought that they're fed up with such long names and implemented namespaces in php 5.3. There was a long time before they become the number one part of each application that deserves your attention.
It took some time for me, computer science student in that early 201Xs to understand what the namespaces about which everybody wrote want from me.
What are the namespaces
Namespaces as for me are the part of the code that have its own visibility enclosed. Or simplify - names of classes in each namespaces are only visible to this namespace. This means you can have same named classes but they should be in different namespace. For example :
<?php
namespace Catchmetech;
class Loader {
}
namespace Blog;
class Loader {
}
Its a working php 5.3+ code which declares two classes:
\Catchmetech\Loader
and \Blog\Loader
, and we can use them only by saying what exactly class we want to use :
$loader = new \Catchmetech\Loader();
When we try to create instance of simply Loader
:
new Loader();
php would say that such class not exists. And that's right, because there is no \Loader
class in \
(root) namespace. Lets consider a namespace as the part of class's name, it would be easier to understand them.
Whats the difference
You would ask me, so what's the difference ?
Why using \Catchmetech\Loader
is better that Catchmetech_Loader
?
In the second variant there is no disgusting slashes, why i must use namespace instead?
The answer is simple - php has few features concerning namespaces.
-
you can use namespaces to ommit actually namespace in class name:
<?php use Catchmetech\Loader; // this statement says to script that `Loader` is a class Catchmetech\Loader $loader = new Loader(); // this is ok now
If you're familiar with c++
use
statement is analog of theirusing namespace
. In java its analog ofimport
statement. -
you can give aliases to classes when going to
use
them:<?php use Catchmetech\Loader as Downloader; // Now Downloader is the name for Loader class $loader = new Downloader(); // this is ok
This is the most helpfull feature for situation when you have two different classes with the same names. You can rename one of them when declaring namespaces usage
-
In
PHP 7
you can group theuse
statements (you can't import whole namespace like in java:import org.catchmetech.*;
)<?php use Catchmetech\{Loader,Logger as MyLogger}; // use two class from namespace $logger = new MyLogger(); // its actually instance of \Catchmetech\Logger class
There is analogs of namespace in other languages as i admitted early: packages in java
, also namespaces in c++
, packages in golang
and others.
Namespaces should be declared on the top of the file:
<?php
namespace Catchmetech;
use AnotherNamespace\Model;
$model = new Model();
And not in the reverse order (next is the syntax error):
<?php
use AnotherNamespace\Model;
namespace Catchmetech; // that's error
$model = new Model();
You can use
namespaces inside other namespaces as showed in example above, or use it in root namespace (when it's not set with namespace X;
it means root):
<?php
// this code inside the root \ namespace
use AnotherNamespace\Model;
$model = new Model(); // its ok
You can use nested namespaces like Catchmetech\Libraries
or even Catchmetech\Core\Libraries
:
<?php
namespace Catchmetech\Libraries; // it's not obligated to use starting slash in namespace declaration
use Catchmetech\Core\Library; // this `imports` Library class from another namespace to \Catchmetech\Libraries namespace (current);
class ZipLibrary extends Library {
}
Getting current namespace name
PHP provide predefined constant __NAMESPACE__ which holds current namespace name:
<?php
namespace Catchmetech\InternalNS;
echo __NAMESPACE__; // \Catchmetech\InternalNS
Some drawbacks
Namespace system in php was very progressive back in 2009. But there are few problems that preventing it to be ideally thing:
-
Before
php 5.6
you can't use function and constants from another namespaces:<?php namespace Catchmetech; const MyConst = 10; // it's not visible from anywhere outside this namespace function AddTwoInts($a,$b) { // its not visible too return $a+$b; }
there is no possibility to use
MyConst
andAddTwoInts
outside theCatchmetech
namespace.In
PHP 5.6
and higher you canuse
functions and constants as well:<?php use function Catchmetech\AddTwoPoints; use const Catchmetech\MyConst; // ...
- As mentioned before - there is no way to group
use
statements beforePHP 7
. - Using everything from namespace as analog to
Namespace.*
is not possible at all
Namespaces are great possibility to separate your code, when it goes through the very big projects they literally saves you. Nevertheless its two lines program or thouthand files project use them!