PHP Namespaces in under 5 Minutes

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

I've an idea! Let's master PHP namespaces... and let's do it in under 5 minutes. Sip some coffee... let's go!

Meet Foo

Meet Foo: a perfectly boring PHP class:

9 lines Foo.php
... lines 1 - 2
class Foo
{
public function doAwesomeThings()
{
}
}

Say hi Foo! Hilarious.

10 lines Foo.php
... lines 1 - 2
class Foo
{
public function doAwesomeThings()
{
echo "Hi Foo!\n";
}
}

To instantiate our favorite new class, I'll move over to a different file and say - drumroll - $foo = new Foo():

... lines 1 - 2
require 'Foo.php';
$foo = new Foo();

Tada! We can even call a method on it: $foo->doAwesomeThings():

... lines 1 - 2
require 'Foo.php';
$foo = new Foo();
$foo->doAwesomeThings();

Will it work? Of course! I can open a terminal and run:

php some-other-file.php

Namespaces: Making Foo more Hipster

Right now, Foo doesn't have a namespace! To make Foo more hipster, let's fix that. Above the class, add, how about, namespace Acme\Tools:

12 lines Foo.php
... lines 1 - 2
namespace Acme\Tools;
class Foo
{
... lines 7 - 10
}

Usually the namespace of a class matches its directory, but that's not technically required. I just invented this one!

Using a Namespaced Class

Congratulations! Our friend Foo now lives in a namespace. Putting a class in a namespace is a lot like putting a file in a directory. To reference it, use the full, long path to the class: Acme\Tools\Foo:

... lines 1 - 2
require 'Foo.php';
$foo = new \Acme\Tools\Foo();
... lines 6 - 8

just like you can use the absolute path to reference a file in your filesystem:

ls /acme/tools/foo

When we try the script now:

php some-other-file.php

It still works!

The Magical & Optional use Statement

And... that's really! Namespaces are basically a way to... make your class names longer! Add the namespace... then refer to the class using the namespace plus the class name. That's it.

But... having these long class names right in the middle of your code is a bummer! To fix that, PHP namespaces have one more special thing: the use statement. At the top of the file, add use Acme\Tools\Foo as SomeFooClass:

... lines 1 - 2
require 'Foo.php';
use Acme\Tools\Foo as SomeFooClass;
... lines 6 - 10

This creates a... sort of... "shortcut". Anywhere else in this file, we can now just type SomeClassFoo:

... lines 1 - 2
require 'Foo.php';
use Acme\Tools\Foo as SomeFooClass;
$foo = new SomeFooClass();
... lines 8 - 10

and PHP will know that we're really referring to the long class name: Acme\Tools\Foo.

php some-other-file.php

Or... if you leave off the as part, PHP will assume you want this alias to be Foo. That's usually how code looks:

... lines 1 - 2
require 'Foo.php';
use Acme\Tools\Foo;
$foo = new Foo();
... lines 8 - 10

So, namespaces make class names longer... and use statements allow us to create shortcuts so we can use the "short" name in our code.

Core PHP Classes

In modern PHP code, pretty much all classes you deal with will live in a namespace... except for core PHP classes. Yep, core PHP classes do not live in a namespace... which kinda means that they live at the "root" namespace - like a file at the root of your filesystem:

ls /some-root-file

Let's play with the core DateTime object: $dt = new DateTime() and then echo $dt->getTimestamp() with a line break:

... lines 1 - 8
$foo->doAwesomeThings();
$dt = new DateTime();
echo $dt->getTimestamp()."\n";

When we run the script:

php some-other-file.php

It works perfectly! But... now move that same code into the doAwsomeThings method inside our friend Foo:

15 lines Foo.php
... lines 1 - 2
namespace Acme\Tools;
class Foo
{
public function doAwesomeThings()
{
echo "Hi Foo!\n";
$dt = new DateTime();
echo $dt->getTimestamp()."\n";
}
}

Now try the code:

php some-other-file.php

Ah! It explodes! And check out that error!

Class Acme\Tools\DateTime not found

The real class name should just be DateTime. So, why does PHP think it's Acme\Tools\DateTime? Because namespaces work like directories! Foo lives in Acme\Tools. When we just say DateTime, it's the same as looking for a DateTime file inside of an Acme/Tools directory:

cd /acme/tools
ls DateTime # /acme/tools/DateTime

There are two ways to fix this. The first is to use the "fully qualified" class name. So, \DateTime:

15 lines Foo.php
... lines 1 - 2
namespace Acme\Tools;
class Foo
{
public function doAwesomeThings()
{
... lines 9 - 10
$dt = new \DateTime();
... line 12
}
}

Yep... that works just like a filesystem.

php some-other-file.php

Or... you can use DateTime... then remove the \ below:

17 lines Foo.php
... lines 1 - 2
namespace Acme\Tools;
use DateTime;
class Foo
{
public function doAwesomeThings()
{
... lines 11 - 12
$dt = new DateTime();
... line 14
}
}

That's really the same thing: there's no \ at the beginning of a use statement, but you should pretend there is. This aliases DateTime to \DateTime.

And... we're done! Namespaces make your class names longer, use statements allow you to create "shortcuts" so you can use short names in your code and the whole system works exactly like files inside directories.

Have fun!

Leave a comment!

  • 2020-06-15 Vladimir Sadicov

    Hey Ecludio

    Yeah something like this :)

    Cheers!

  • 2020-06-14 Ecludio

    So it is the equivalent to packages in Java?

  • 2019-07-09 Diego Aguiar

    Ah, sorry I misunderstood you. I'm glad you discovered the answer :)

  • 2019-07-05 Dan Marshall

    Hey, thanks for your reply. However, I meant just the beginning of the file, when you declare to 'use' a class from another, non-global namespace. I found the answer somewhere else, turns out that it doesn't make any difference, but it should be written without the backslash (as a convention). Cheers!

  • 2019-07-04 Diego Aguiar

    Hey Dan Marshall

    If you prepend a backslash when instantiating an object, i.e. $movie = new \Movie() then, PHP will try to find that class from the global scope (The global scope is where built-in classes live, like for example $today = new \DateTime())

    I hope it helps. Cheers!

  • 2019-07-03 Dan Marshall

    Thanks for the tutorial, great! Could you elaborate on the backslashes, though? Should it be 'use \...' or 'use ...' from inside a namespace?

  • 2019-02-10 C Silkey

    Thanks, kept your 120 second promise :)

  • 2018-12-03 Victor Bocharsky

    Hey Yassin,

    Glad you liked this tutorial! And thanks for your feedback :)

    Cheers!

  • 2018-12-02 Yassin Hammou Ouali

    Very clear! Thank you very much for that tutorial! :) <3

  • 2018-06-29 Hicham Zaher

    easy, fast and great !!!!
    Thanks

  • 2017-07-06 Victor Bocharsky

    Hey Jeric,

    We're glad you like it! Honestly, this is my favorite tutorial :p

    Cheers!

  • 2017-07-06 Jeric Realubit

    Sweet As! Thank you!

  • 2017-06-14 Diego Aguiar

    Hey Mr TK

    In this case we are using "require" in a file (some-other-file.php) that doesn't define a namespace, the one who has a namespace is the Foo class, so if you want to create a Foo object in other file, you have two options

    1) In that file, define it's namespace and write a "use" statement that points to the "Foo" class

    2) Don't define a namespace and use "require" or "include" that points for that class

    Cheers!

  • 2017-06-14 Mr TK

    And why do you need to require a file when namespacing? Isn't namespacing intended to do away with requiring?

  • 2017-03-31 彭天晴

    Awesome! Really save my time!

  • 2017-03-07 Mickaël LP

    It think it would actually help !
    I generally have the same 'problem'.
    But not putting sub-titles also makes us focusing more on the screen and the intonation of the voice.

    So having the choice of activating sub-titles would be a benefit (in my opinion).

  • 2017-03-07 Mickaël LP

    Waow ! These 2 minutes were incredibly efficient (in my case).
    Thank you for this course, I feel like I've just discovered my new Bible with knpuniversity :)

  • 2016-12-29 meXa

    Thanks

  • 2016-07-01 Victor Bocharsky

    Hey, thank you!

  • 2016-07-01 BIBIN JOHN

    The best php namespace tutorial.... Great... keep it up...

  • 2016-05-09 Janak

    excellent explanation. Thanks!!!

  • 2016-03-21 Emmanuel Higgins

    Wish documentation was like this.

  • 2016-01-28 TuConciencia

    120 seconds + this explanation and I'm ready to go =)
    Thank you!

  • 2016-01-16 Arturas Lapiskas

    guess i'm not the first, who say that this titorial is great! Thank you!

  • 2015-07-21 weaverryan

    Ha, 120 seconds is definitely a rush! You can't slow down the video yet, but we're adding speed control really soon :)

  • 2015-07-21 Zoe Abe

    Quite helpful, many thanks! I realized it before I know I realized it (does that make sense? :P)
    But do you happen to have a 0.75x speed playback option? 120 seconds sound like a rush to me~~ :-D

  • 2015-03-27 sancoLgates

    great explanation, thanks :)
    i get it now!

  • 2015-03-20 Braxton Overby

    I got myself ready to sit down and read/watch for several minutes on how to properly use namespaces in PHP. I appreciate how easy this tutorial was to follow.

  • 2015-01-24 Sajeepan Yogenthiran

    useful tip :-) Thank you.

  • 2014-12-10 Alberto Maturano

    Yes, It would help :D

  • 2014-12-03 Jimmy James Atauje Hidalgo

    Very nice tutorial

  • 2014-11-13 weaverryan

    Hey R0bertinski!

    I wonder if (English) sub-titles would help? I want to do the most useful thing for our non-native English-speaking friends :).

    Thanks!

  • 2014-11-12 R0bertinski

    I am used to listen videos in english, but is very complicate to understand this videos, because she speak very fast.

  • 2014-10-27 weaverryan

    So nice, thanks Troy :)

  • 2014-10-25 Troy Close

    Brilliant. I just wasted my time reading two different tutorials on namespaces and still didn't understand it. Watched your video and got it immediately. Thanks Leanna and Ryan for uncomplicating this subject.

  • 2014-07-29 Century Media

    Great overview. Only thing I think it could use is to mention that the main use of namespaces is to stop method names conflicting. Aside from that great job!

  • 2014-06-04 weaverryan

    Hi there!

    Actually, namespaces and autoloading are 2 separate things, though in practice, due to PSR-0 autoloaders, they are quite related.

    Namespaces are all about basically making class names really long, and then giving us a "use" statement to help shorten things. On its own, it doesn't help with removing the require/include statements. So you're right, on their own, namespaces actually *add* code and make things longer. Really, namespaces weren't created for you and I, they were created for library authors to avoid name collisions (like you mentioned). For us, they just make things longer :).

    But in practice (and you're totally right about this part), if you use namespaces properly, AND you use a PSR-0/PSR-4 autoloader (like the one provided in Composer), then you'll be able to remove your require/include statements. The autoloader basically leverages namespaces to do this, but namespaces on their own don't allow you to remove those ugly require/include things from your code.

    I hope that clarifies - it's confusing because namespaces *seem* to make include/require statements no longer necessary (because in practice, this is true). But in reality, on their own, they just make class names longer and mean more typing.

    Cheers!

  • 2014-06-04 ENetArch

    So, why wasn't the required_once function removed from your example? If that function is required to import your classes, then there is no purpose in updating code to include namespaces, since there is no benefit in reducing code, instead, you've increase code.

    The purpose of adding a namespace, not only has to reduce class name clashes, but also automate the finding and binding of classes somehow, otherwise there is no use to using namespaces.

  • 2014-02-12 Jerome Covington

    That was awesome. Thanks for this. Namespaces and object-oriented code in PHP are bringing me back.

  • 2014-01-23 weaverryan

    Hi there!

    Namespaces and using the include/require statements don't do the same thing - it's one of the trickiest parts of learning namespaces. You still need to include/require any file before using the class inside of it (unless you use an autoloader, like the one Composer gives you). Namespaces have nothing to do with that part.

    The point of namespaces is, basically, to give you a systematic way to make your class names longer. When you have the `Acme\Tools` namespace, the full class name ends up being `Acme\Tools\Foo`. Why is this useful? Well, on its own, it's not :). It's really so that 2 3rd-party library authors an choose 2 different namespaces so that their class names don't conflict. Namespaces really help to serve that purpose: to avoid conflicts between libraries.

    If you want to see a little bit more on the autoloading side of things (i.e. removing the need for require/include) - check out http://knpuniversity.com/sc.... Again, it's actually unrelated to namespaces.

    Cheers!

  • 2014-01-23 spudgun

    You explained what namespaces do, but you didn't explain why I might need them. You say "This is just like referring to a file by its absolute path.", so ... why don't you just do that?

    include('Acme/Tools/Foo.php');

  • 2013-12-08 JC

    Wow... you really did it in 120 secs :-)