PHP PSR-0 + several namespaces in one file and autoload
<p>I've been thinking for a while about defining several namespaces in one php file and so, having several classes inside this file.</p>

<p>Suppose, I want to implement something like <code>Doctrine\ORM\Query\Expr</code>:</p>

<pre><code>Expr.php
Expr
|-- Andx.php
|-- Base.php
|-- Comparison.php
|-- Composite.php
|-- From.php
|-- Func.php
|-- GroupBy.php
|-- Join.php
|-- Literal.php
|-- Math.php
|-- OrderBy.php
|-- Orx.php
`-- Select.php
</code></pre>

<p>It would be nice if I had all of this in one file - <code>Expr.php</code>:</p>

<pre><code>namespace Doctrine\ORM\Query;
class Expr {
    // code
}

namespace Doctrine\ORM\Query\Expr;

class Func {
    // code
}

// etc...
</code></pre>

<p>What I'm thinking of is directories naming convention and, unlike <a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md" rel="nofollow"><code>PSR-0</code></a> having several classes and namespaces in one file. It's best explained by the code:</p>

<pre><code>ls Doctrine/orm/query
Expr.php
</code></pre>

<p>that's it - only <code>Expr.php</code></p>

<p>Since <code>Expr.php</code> is somewhat I call a "meta-namespace" for <code>Expr\Func</code>, it make sense to place all the classes inside Expr.php (as shown above).</p>

<p>So, the vendor name is still starts with an uppercased letter (<code>Doctrine</code>) and the other parts of namespace start with lowercased letter. We can write an autoload so it would respect this notion:</p>

<pre><code>function load_class($class) {
    if (class_exists($class)) {
        return true;
    }
    $tokenized_path = explode(array("_", "\\"), DIRECTORY_SEPARATOR, $class);
    // array('Doctrine', 'orm', 'query', 'Expr', 'Func');
    //                                    ^^^^
    // first, we are looking for first uppercased namespace part
    // and if it's not last (not the class name), we use it as a filename 
    // and wiping away the rest to compose a path to a file we need to include
    if (FALSE !== ($meta_class_index = find_meta_class($tokenized_path))) {
        $new_tokenized_path = array_slice($tokenized_path, 0, $meta_class_index);
        $path_to_class = implode(DIRECTORY_SEPARATOR, $new_tokenized_path);
    }
    else { // no meta class found
        $path_to_class = implode(DIRECTORY_SEPARATOR, $tokenized_path);
    }
    if (file_exists($path_to_class.'.php')) {
        require_once $path_to_class.'.php';
    }
    return false;
}
</code></pre>

<p>Another reason to do so is to reduce a number of php files scattered among directories.
Usually you check file existence before you require a file to fail gracefully:</p>

<pre><code>file_exists($path_to_class.'.php');
</code></pre>

<p>If you take a look at actual <a href="https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Query/Expr.php" rel="nofollow"><code>Doctrine\ORM\Query\Expr</code></a> code, you'll see they use all of the "inner-classes", so you actually do:</p>

<pre><code>file_exists("/path/to/Doctrine/ORM/Query/Expr.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/AndX.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Base.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Comparison.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Composite.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/From.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Func.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/GroupBy.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Join.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Literal.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Math.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/OrderBy.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Orx.php");
file_exists("/path/to/Doctrine/ORM/Query/Expr/Select.php");
</code></pre>

<p>in your autoload which causes quite a few I/O reads.
Isn't it too much to check on each user's hit?</p>

<p>I'm just putting this on a discussion.</p>

<p>I want to hear from another PHP programmers what do they think of it.
And, of course, if you have a silver bullet addressing this problems I've designated here, please share.</p>

<p>I also have been thinking if my vogue question fits here and according to <a href="http://programmers.stackexchange.com/faq"><code>the FAQ</code></a> it seems like this question addresses "software architecture" problem <em>slash</em> proposal.</p>

<p>I'm sorry if my scribble may seem a bit clunky :)
Thanks.</p>
