Modifying the include mechanism (include, require, include_once, require_once)

I submitted a feature request to the PHP team today to fix a minor problem I’m having with templates then realized the full scope of what it would affect.

http://bugs.php.net/bug.php?id=52995

Basically, allow namespaces to be specified at include time. Consider

Page.php


class Page extends Controller {
}

Controller.php


class Controller {}

elsewhere in the code…


namespace MyNamespace;

new Page();

The autoloader looks for Page and includes it. Currently — CRASH. Why? Since the two class files don’t specify namespaces they attach to the global space. However - if what if we could attach them?

require('Page.php', '\\MyNamespace');

This would work. But it gets better. Say we give the autoloader a choice of Page php files, one default framework Page class and one in the Project. Again, we get a request for Page and we serve up the Project file - but wait… It starts like this

class Page extends \\Framework\\Page

The autoloader puts this into MyNamespace and then gets the request for this new class belonging to MyNamespace\Framework\Page (remember, the code is executing in a namespace set by the require statement). So it goes and gets the Framework page and puts it there.

The effects of this change can be tested in current PHP through a rotten trick with eval


eval('namespace '.$targetNamespace.'; '.file_get_contents('file.php'));

Due to the enormous performance hit I wouldn’t advise putting this into production, but it is a way to experiment with this concept.

I think this would open up a LOT of doors for code reuse. Course it could be the world’s worst idea. Comments?

Hmm… Close, but using class_exists would still leave the class being written to a namespace that the autoloader can’t control. And debugging as you point out could be an issue. It might work but I’ll deal with it later.

Yep, being able to move classes between namespaces at runtime (or just on load) would be really useful for a number of things.

When dealing with 3rd party code it would be nice to be able to load it all into a single namespace.

I don’t ‘get’ the implmenation of namespaces in php, they go against every other design decision the php developers took.

For anything else, including a file includes it into the current scope yet an include inside a namespace loses scope of the namspace.

Is there a reason to not instantiate Page like this?


<?php

namespace MyNamespace;

new \\Page(); 


That assigns the class to MyNamespace statically - the only way to change it is to edit the code. What I’m looking for is a way to assign the class to the namespace dynamically. The advantage of a dynamic assignment is I can more easily deal with namespace collisions.

PHP’s current namespace schema solves nothing the moment two people release products with matching namespaces - they’ll collide. That’s the penalty of static namespacing. In order to be truly useful the system must be able to handle dynamic namespace assignments.


<?php

namespace A
{
	class Foo
	{
	}
}

namespace B
{
	class_alias('A\\Foo', 'B\\Bar');
}

namespace
{
	$bar = new B\\Bar();

	var_dump($bar);
}

But its seriously wtf type code, and wouldn’t recommend it.