ryeguy
ryeguy

Reputation: 66851

Resetting a namespace in PHP?

How can I "reset" a namespace to the global one? Given the following code:

namespace foo;
include 'myfile.php';

myfile.php will now try to load all of its classes in the foo namespace, even though its classes are in the global namespace. Now it wouldn't be a big deal to swap the order of those lines, but how would I deal with myfile.php having an autoloader? It will try to load the classes in namespace foo.

Upvotes: 6

Views: 8574

Answers (4)

raveren
raveren

Reputation: 18533

I'd just like to chime in on this with my findings. Since PHP cannot handle exceptions in __toString methods, the solution is to do it yourself: something along the lines of

public function __toString()
{
    try {
        return $this->draw();
    } catch ( \Exception $e ) {
        die( \error::_getExceptionPage( $e ) );
    }
}

However what becomes really weird, the namespace of the call to error::_getExceptionPage($e) becomes the same as the class in which __toString was defined - and I wasn't able to find a way around that except prefixing everything in my exception handling code with \, i.e. every call to any class in getExceptionPage must become \someClass::staticMethod().

Same goes for included files, everything - all code since the thrown exception becomes embedded in the namespace of the faulty class. Tested with PHP 5.3.17

Upvotes: 0

Josh Davis
Josh Davis

Reputation: 28730

Namespaces work on a per-file basis. If myfile.php doesn't declare any namespace then everything in it will belong to the global namespace, regardless of the namespace in which include was used.

Long story short, namespace declarations only apply to their own file, not includes.

Upvotes: 13

JSBձոգչ
JSBձոգչ

Reputation: 41378

myfile.php should declare the namespace that it wants to be in. If you want to ensure that myfile.php loads in the global namespace, I believe you can put

namespace // empty namespace means global
{
}

around the body of myfile.php. Make sure that you use the braces, or else you'll redefine the rest of the file in which myfile.php is included to also be in the global namespace.

Upvotes: 9

Pascal MARTIN
Pascal MARTIN

Reputation: 400932

Maybe I didn't understand your question well ; in that case, could you provide an example of what you get, and what you'd expect ?


Are you sure it will try to load the functions from myfile.php in the foo namespace ?

Considering I have one file (temp-2.php) that looks like this :

<?php
namespace foo;

function my_function_this_file() {
    var_dump(__FUNCTION__);
}
my_function_this_file();

include 'my_other_file.php';
my_function_the_other_file();

And another one (my_other_file.php) that looks like this :

<?php

function my_function_the_other_file() {
    var_dump(__FUNCTION__);
}

When I call the first one from my browser, I get this output :

string 'foo\my_function_this_file' (length=25)

string 'my_function_the_other_file' (length=26)

This seems to indicate the second function is not inside any namespace, except the global one -- which corresponds to the fact that it's not declared in any namespace.

If I remember correctly, the "namespace" instruction is only valid for the file it is used in, and not for included files.


The Import names cannot conflict with classes defined in the same file page from the namespaces FAQ seems to indicate that too.


Hope this helps, and I understood the question correctly...


EDIT : btw, swapping the order of the to lines, like this :

<?php
include 'my_other_file.php';
namespace foo;

Wouldn't work : the "namespace" instruction must be the first one of the file : you'll get a Fatal Error, if you do that :

Fatal error: Namespace declaration statement has to be the very first statement in the script

Upvotes: 2

Related Questions