Proposal for "Package Naming Conventions"

» Metadata » Status
  • Status: Draft
» Description
note this is a work in progress that is merely a collection of notes at this point

This RFC calls for a change in the way package names are mapped to namespaces. It will use existing packages within the context of PEAR2 will be used throughout to show how existing code would fix into this.

Using PEAR's Text_Diff class in the Text_Diff package, in PEAR2 the class would become PEAR2::Text_Diff::Diff. Or in PHP code:


namespace PEAR2::Text_Diff;
class Diff
{
....


This package/namespace combination is reached via:


namespace Vendor::Package;


PEAR2 is the Vendor, the package name is Text_Diff. Within the current directory structure, this would map to include_path/PEAR2/Text_Diff/Diff.php.

Background:

PEAR packages currently do not enforce a single-directory, single-package rule. This makes it harder contain packages within a version control system through means such as Subversion's svn:externals or Git's submodules.

This proposal is aimed at making the package name map to a specific directory and that each file within that directory is considered part of its package.

Benefits:


  1. Tracking packages within a version control system is easier as most modern vcs delineate externals along directory lines
  2. Keeps existing package names in tact
  3. Allows classes to be properly named by their use instead of forcing names by their location within a directory hierarchy
  4. Helps explicitly show what is a class and what is a namespace (first two elements are always Vendor and Package Name, everything else is the class)


Drawbacks:


  1. Changes existing, 9 year structure
  2. Changes existing behavior of "_"


Examples:

The examples that follow are meant to be illustrative of how an existing package might fit into this new structure. These are not meant as a discussion of the benefits of one particular implement over another, but only so we are discussing familiar code.

MDB2 Example

<?php
namespace PEAR2::MDB2;
class MDB2 {
...

namespace PEAR2::MDB2_MySQLDriver {
class Driver {
...


The existing MDB2 package presents a unique case with its package and sub-package model. The current PEAR implementation of its drivers requires the naming convention "MDB2_Driver_<SomeDriver>" in order to keep all of the drivers in a central location. With the new autoload capable code, you would check for the existence of a properly named package, the MDB2_MySQLDriver (note that MySQL in this package name modifies the "Driver", and not the other way around).


<?php
// possible snippet for checking for a driver...

$driver_name = $this->getFullyQualifiedDriverName($driver);
if (!class_exists($driver_name, true)) {
throw new UnknownDriverException($driver);
}

// etc., etc.

function getFullyQualifiedDriverName($driver) {
if (strpos('::', $driver) === false) {
$driver = 'PEAR2::MDB2_' . $driver . 'Driver::Driver';
}
return $driver;
}


This also allows for the presence of a namespace token ("::") to signify that you want to use your own driver that's not part of the PEAR2's MDB2 distribution.

Text_Diff and Text_CAPTCHA Example:


<?php
// located in include_path/PEAR2/Text_Diff/Diff.php
namespace PEAR2::Text_Diff;
class Diff {



<?php
// located in include_path/PEAR2/Text_CAPTCHA/CAPTCHA.php
namespace PEAR2::Text_CAPTCHA;
class CAPTCHA {


This demonstrates two classes that could very possibly be used in conjunction. In a normal PEAR style installation, these two files would be located in the same directory. The new method would put both of them in their own directories, allowing external developers to track versions independently.
» Dependencies » Links
» Timeline » Changelog
  • First Draft: 2008-04-06