Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php namespace vs require

Tags:

php

symfony

quick question, I'm playing with The HttpFoundation Component (Symfony) and something is not clear to me. The tutorial I'm looking at shows this code

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$input = $request->get('name', 'World');

$response = new Response(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));

$response->send();

Now, this works, no problem, but I was trying to make it work without the 'use' keywords, so including (php require) the Request class itself, and then I get a class not found, which is so wierd to me, when I use the use keyword and use the namespace, the class is found, but when I include the classfile itself, I get a class not found..

So to illustrate, this returns a 'Class not found'..

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__.'/vendor/symfony/http-foundation/Request.php';

$request = new Request();

Can anyone clear this up for me please? Thanks in advance!

P.S. I've red the use keyword is not including anything, just declaring the namespace or something? So It's so wierd to me that it works with the use case since its not even including files and when I include the file directly it returns a 'Class not found'...

like image 907
frederikvdbe Avatar asked Feb 29 '16 09:02

frederikvdbe


2 Answers

If you use use, you create something like an file based alias for the fully qualified name(fqn). So if you use Symfony\Component\HttpFoundation\Request, you could write Request instead of the fqn. If you dont want to include the use statement, you have to write everytime the whole class name.

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';

$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();

$input = $request->get('name', 'World');

$response = new \Symfony\Component\HttpFoundation\Response(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));

$response->send();

The use-statement itself has nothing to do with class loading. The class loading stuff is done by the autoloader which resolves the filename of the included php class out of it's class name.

To clear your question code up:

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__.'/vendor/symfony/http-foundation/Request.php';

$request = new Request();

The Class \Symfony\Component\HttpFoundation\Request is included, but you want to create an new object of the class \Request, which is something different.

like image 100
Philipp Avatar answered Oct 04 '22 09:10

Philipp


Namespace is not about loading classes, is about naming.

<?php
$response = new Response();

Here we're telling PHP to use a \Response class. So if a \Response class is not loaded at the moment, you'll get an error.

<?php

use Symfony\Component\HttpFoundation\Response;

$response = new Response();

And here (with new Response() statement) we're telling it to use a Symfony\Component\HttpFoundation\Response class. So if a Symfony\Component\HttpFoundation\Response class is not loaded at the moment, you'll get an error.

Basically use Some\Namespaced\ClassName means use Some\Namespaced\ClassName as ClassName, think of it as aliasing in file context.

Read more at http://php.net/manual/en/language.namespaces.basics.php .

like image 31
ksimka Avatar answered Oct 04 '22 09:10

ksimka