Matthias Pigulla wrote:
>> Von: Gregory Beaver [mailto:[EMAIL PROTECTED]
> 
>> Exactly - which is why you should never put classes, functions or 
>> constants in the __php__ namespace.  The convention I am proposing
>> is to only use __php__ for code that *uses* re-usable components,
>> not *declares* them.
> 
> Let alone __php__. If you just put all of your code into namespace
> Mylib, you're not safe because according to the name resolution
> rules, internal classes come after imported ones but before trying to
> find classes in the current namespace.

Right, but as long as you know this, it is not so bad for two reasons,
see below.  Even if you *don't* know this, the chance of a name
collision is extremely unlikely - the most common collision will be
Exception.

>> 1) library code is always explicitly "use"d 2) name conflicts are
>> impossible
> 
> 1) is the crucial one because that puts your classes ahead of the
> internal ones in the resolution list. That is not only "library code"
> you explicitly use, but also all code from "your" own namespace.
> Having to explicitly enumerate all classes you use in your own
> namespace in every file may be tedious.
> 
> So just to get that straight: Having a namespace statement and no
> "use" (because all you use is from your library) is a discouraged
> practise?

To be clear - this *only* affects users who are relying on autoload.  In
other words, this code works the same way 100% of the time regardless of
load order:

file1.php:
<?php
namespace foo;
class Exception {}
?>

file2.php:
<?php
namespace foo;
include 'file1.php';
$a = new Exception('hi');
echo get_class($a); // foo::Exception
?>

So, if your code explicitly loads external files using include/require,
you need not worry about this issue.

Library authors who are in fact relying upon autoload do need to
explicitly use the classes they import as unqualified names, but this is
far less onerous than it seems on initial thought.

Let's say you're using 10 classes from your own project.  The first
instinct is that you then have to have 10 use lines - what a pain!
However, this is not necessary.  Here's a realistic sample from
PEAR2_Pyrus's package.xml validator class,
PEAR2::Pyrus::PackageFile::v2::Validator.

<?php
namespace PEAR2::Pyrus::PackageFile::v2;
use PEAR2::Pyrus::PackageFile as pf;
use PEAR2::Pyrus::PackageFile::Exception as _ex
use PEAR2::Pyrus as me;
class Validator {...} // details removed for brevity :)
?>

With the above use statements, I can access these classes:

PEAR2::Pyrus::PackageFile::v2
PEAR2::Pyrus::Validate
PEAR2::Pyrus::PackageFile::Exception
PEAR2::Pyrus::ChannelRegistry
PEAR2::Pyrus::Installer::Role
PEAR2::Pyrus::Config
PEAR2::Pyrus::Config::Exception
PEAR2::Pyrus::Task
PEAR2::Pyrus::Log
PEAR2::Pyrus::Package::Tar

with these shortcuts:

pf::v2
me::Validate
_ex
me::ChannelRegistry
me::Installer::Role
me::Config
me::Config::Exception
me::Task
me::Log
me::Package::Tar

Note that it would be possible to shorten the longer names like
me::Config::Exception, but these classnames are only used once in the
file.  The most commonly used classname is
PEAR2::Pyrus::PackageFile::Exception, and so I would choose that as the
shortest name.  When one examines these things from a practical
standpoint, having the 4 extra characters "me::" definitely increases
maintainability, as it makes it obvious that this class is from our
library, and not an internal class.

I do think it would be worth putting future internal classes into the
PHP namespace, and it would be a good idea to reserve that namespace
now.  The reservation can always be dropped later if necessary.

Greg

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to