second draft: standards vs. best practices
| From: | Greg Beaver | Date: | Fri, 07 Aug 2009 20:51:10 +0000 |
| Subject: | second draft: standards vs. best practices | ||
| Groups: | php.standards | ||
| Request: | Send a blank email to standards-+get-87@lists.php.net to get a copy of this message | ||
Hi,
My daughter is napping, so I have both hands free for a little while.
Here is a revision based on David's suggestions:
=====
Requirements and restrictions:
(1) Each vendor must define its own top-level namespace using
lower-cased alphanumeric characters
(2) All code must be organized into packages, each contained within
their own sub-directory of the vendor directory. For example:
pear2/
Pyrus/
SimpleChannelServer/
Packages are defined exclusively by their sub-directory.
(3) All classes must have names beginning with an upper-cased English
character between A and Z. Class names must reflect the relative path
within their vendor and package For example: the file
pear2/Pyrus/Main.php will contain the class pear2\Pyrus\Main (namespace
pear2\Pyrus, class Main)
(4) All class-based packages must be designed for autoloading, and must
not load dependencies directly using the include, include_once, require,
or require_once statement, or any customized loaders. The work of
loading a dependent file must be done either by an autoloader or by the
consumer of the package.
Options allowed under the standard:
(1) Packages may be distributed in any manner that the vendor would
like, the definition of package shall be how it is installed inside the
vendor directory. For example, the Zend Framework may choose to
distribute all packages at once, whereas PEAR2 may choose to distribute
packages separately, or to split up a package into components and
distribute those separately.
(2) Packages may have sub-namespaces. For example, the vendor "pear2"
package "Pyrus" may choose to have a class named
"pear2\Pyrus\Developer\CoverageAnalyzer\Sqlite" instead of
"pear2\Pyrus\DeveloperCoverageAnalyzerSqlite" or
"pear2\Pyrus\Developer_Coverage_Analyzer_Sqlite"
Recommendations under the standard:
(1) It is recommended that all vendors distributing packages using a
PEAR Channel should distribute each top-level package as a separate PEAR
package.
=====
The draft best practices could look like:
=====
(1) Every package that throws exceptions should provide a base exception
class. This may be an interface that other exceptions within the
package implement. For small vendors, this base class may also be the
same as a base vendor exception package, for instance class
"pear2\Basic\Exception"
(2) Abstract classes should have the suffix "Abstract." For example, an
abstract class for "Registry" from vendor "pear2" in the package
"Pyrus"
would be named "pear2\Pyrus\RegistryAbstract"
(3) All interfaces should have the suffix "Interface." For example, an
interface for "Registry" from vendor "pear2" in the package "Pyrus"
would be named "pear2\Pyrus\RegistryInterface"
(4) Underscores are not recommended for use inside a package name, but
may be used. If present, underscores will be translated to path
separators. For example, the class name "pear2\Pyrus_Developer\Thing"
will translate to file "pear2/Pyrus/Developer/Thing.php"
(5) packages that use functions should name their functions as
vendor\package\function <-- functional people, speak now, and make a
recommendation if this ain't good
=====
I'm not so sure about "pear2\Basic\Exception" but it is one of the only
ways to get a base vendor exception that satisfies requirement (2). I
really hate "the namespace stutter" "pear2\Exception\Exception" it is
positively vile :).
Greg