Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialTunde Adegoroye
20,597 PointsA question about namespaces and use keyword
Trying to get my head around this but to clear things up like in the php file Logger with have
namespace Monolog;
use Monolog\Handler\HandlerInterface;
use Monolog\Handler\StreamHandler;
use Psr\Log\LoggerInterface;
use Psr\Log\InvalidArgumentException;
Does the namespace Monolog define the class of this file the same way you would by writing something like this ?
class Monolog {
public function __construct(){}
}
Also when using the use is this just the same way as using include or require so rather than loading in all of these classes we're just adding a reference to them by defining and using the shorthand at the end so we can just easily access methods, properties within them etc
And finally just to clear this up in our index.php where we have said
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('name');
$log->pushHandler(new StreamHandler('app.txt ', Logger::WARNING));
$log->addWarning('No my god');
echo "Hello World!";
With the first 2 use statements are we just saying we want to access the Logger file in the folder monolog & StreamHandler which is nested in the Handler folder with then allows us later to use these methods within these files since we have reference them above.
That was a mouthful hopefully i'm on the right track :D
3 Answers
thomascawthorn
22,986 PointsIt sounds like you're almost there.
When you add a namespace to a file that contains a class, it's similar to writing out the file path that your class is sitting in. Let's say that Treehouse project has a directory of models, and inside the directory you have a php User class:
your filepath would be Treehouse/Models/User.php
and the psr-4 convention says your namespace should be Treehouse\Models;
e.g.
<?php
namespace Treehouse\Models;
class User {
//
}
If you were import (or 'use') this class in another file, you'd say:
<?php
use Treehouse\Models\User;
psr-4 convention is handy - you can guess where everything is sitting because it closely resembles the folder structure.
To answer your questions:
does the namespace Monolog define the class of this file the same way you would by writing something like this ?
No, think of the namespace as a declaration of the location of your class, not the name. It's like saying this Muse track sits within this Muse album. The album might have the same name as one of the songs (and that's fine) but the song name isn't dictated by the album.
Also when using the use is this just the same way as using include or require so rather than loading in all of these classes we're just adding a reference to them by defining and using the shorthand at the end so we can just easily access methods, properties within them etc
Yes, pretty much. It's an additional way to pull in classes from your application. I might be misinformed here (and please correct me if I'm wrong!) - you can include a file of functions and use those functions in the current file. You can also include a file of a class and have the same result. However, you won't be able to 'use' a file of functions because the autoloader is looking for a CLASS.
With the first 2 use statements are we just saying we want to access the Logger file in the folder monolog & StreamHandler which is nested in the Handler folder with then allows us later to use these methods within these files since we have reference them above.
Hmmm, so psr-4 is a convention that means namespacing closely resembles file structure. You can, however, set any namespace you want to. It doesn't automatically mean that you're looking in a specific directory, but if you're being awesome and following conventions, then that's great!
In this directory: Something/Totally/Random.php you could set a namespace:
e.g.
<?php
namespace Bad\Practice
class Namespace {
//
}
and import that class using
<?php
use Bad\Practice\Namespace;
even thought it's sitting in a different directory.
If you want to check this out, click through the composer files in the vendor directory. You'll be able to see how it assocaites your classes with file paths (/vendor/composer).
Hope this helps
Andrew Shook
31,709 PointsTunde, You are kinda on the right track. The use statement doesn't include or require other files, it simply tells php that you want to use a specific class. So in the case of the Logger class from Monolog you mentioned, the use statement is telling php that when you create a new Logger object that Logger object should be from the Monolog Logger class not another class called Logger.
Now, as you noticed that fully qualified class name, Monolog\Logger, does match the folder structure of the Monolog package. This isn't because php doesn't automatically loads the files for you, but because composer autoloads the file for you. Composer can do this form you because it knows to takes the fully qualified class name, replace the "\" with "/", and knows roughly where to find the file. So Monolog\Logger is probably found inside the package at PACKAGEROOT/scr/Monolog/Logger.php (PSR-0), or at PACKAGEROOT/scr/Logger.php (PSR-4).
The namespace keyword was added to php so that people, and php itself, could distinguish one class from another. Back before php 5, you couldn't have two packages with a class called Logger because there would be a name collision. In other words php wouldn't know which Logger class you meant. So the namespace key word lets php distinguish two classes with the same name. So it will know that AndrewShook\Logger is different then Monolog\Logger. So by using the namespace keyword you are telling PHP that all the classes under that namespace are different then other classes with the same name.
<?php
use Monolog\Logger;
use AndrewShook\Logger;
$log = new Logger('name');
//this will fail because php doesn't know which logger to use.
?>
<?php
namespace SOMENAMESPACE;
$log = new Monolog\Logger('name');
//this will fail because php will look for SOMENAMESPACE\Monolog\Logger.
$log = new \Monolog\Logger('name');
//will work because the "\" at the beginning tell php that the class from another namespace
?>
<?php
use Monolog\Logger;
use AndrewShook\Logger;
$log = new Monolog\Logger('name');
//this will work since php knows that logger means the Logger class form the AndrewShook namespace
$log = new AndrewShook\Logger('name');
//this will work since php knows that logger means the Logger class form the Monolog namespace
?>
<?php
use Monolog\Logger as Monologger;
use AndrewShook\Logger;
$log = new Logger('name');
//this will work since php knows that logger means the Logger class form the AndrewShook namespace
$log = new Monologger('name');
//this will work since php knows that logger means the Logger class form the Monolog namespace
?>
Tunde Adegoroye
20,597 PointsReally wish i could vote both of them as best answers very clear and helpful thanks guy i understand now :D
Andrew Shook
31,709 PointsNo worries, just here to help.
Jaime Rios
Courses Plus Student 21,100 PointsJaime Rios
Courses Plus Student 21,100 PointsThanks, Tom! You made it clearer for me.