[VOTE] Package-Oriented Autoloader

705 views
Skip to first unread message

Paul Jones

unread,
May 10, 2013, 11:31:03 AM5/10/13
to php...@googlegroups.com
Hi everyone,

I hereby call for votes on the Package-Oriented Autoloader:

<https://github.com/php-fig/fig-standards/blob/master/proposed/package-oriented-autoloader.md>

The member count at the start of the vote is 27. The quorum requirement is 9 votes. A simple majority of +1 over -1 is required for the measure to pass. The vote started on Fri 10 May 2013 at about 1030am CDT, and closes on Fri 24 May 2013 at about the same time.

Please restrict this thread to votes only; discussion may proceed on other threads.

The text of the measure is attached below for posterity.

* * *

PSR-X: Package-Oriented Autoloader
==================================

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in [RFC 2119](http://tools.ietf.org/html/rfc2119).


1. Overview
-----------

This PSR specifies the rules for an interoperable autoloader. It is intended
as a co-existing alternative to, not a replacement for,
[PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
It removes some legacy compatibility features that were built into PSR-0, in
particular the handling of underscores in class names, and it allows for
classes to map to shallower directory structures.


2. Definitions
--------------

- `class`: The term "class" refers to PHP classes, interfaces, and traits.

- `absolute class name`: A fully-qualified namespace and class name.

- `namespace`: Given an `absolute class name` of `Foo\Bar\Dib\Zim`, the
`namespace` is `Foo\Bar\Dib`.

- `namespace name`: Given an `absolute class name` of `Foo\Bar\Dib\Zim`, the
`namespace names` are `Foo`, `Bar`, and `Dib`.

- `namespace prefix`: One or more contiguous `namespace names` at the start of
the `namespace`. Given an `absolute class name` of `Foo\Bar\Dib\Zim`, the
`namespace prefix` may be `Foo`, `Foo\Bar`, or `Foo\Bar\Dib`.

- `relative class name`: The parts of the `absolute class name` that appear
after the `namespace prefix`. Given an `absolute class name` of
`Foo\Bar\Dib\Zim` and a `namespace prefix` of `Foo\Bar`, the `relative class
name` is `Dib\Zim`.

- `base directory`: The absolute directory path on disk where the files for
`relative class names` have their root.


3. Specification
----------------

- A class file MUST contain only one class definition.

- An absolute class name MUST begin with a top-level namespace name, which
MUST be followed by zero or more sub-namespace names, and MUST end in a
class name.

- The namespace prefix of an absolute class name MUST be mapped to a base
directory; that namespace prefix MAY be mapped to more than one base
directory.

- The relative class name MUST be mapped to a sub-path by replacing namespace
separators with directory separators, and the result MUST be suffixed with
`.php`.


4. Example Implementations
--------------------------

The example implementations MUST NOT be regarded as part of the specification;
they are examples only. Class loaders MAY contain additional features and MAY
differ in how they are implemented. As long as a class loader adheres to the
rules set forth in the specification they MUST be considered compatible
with this PSR.


### Example: Project-Specific Implementation

The following is one possible project-specific implementation of the
specification.

```php
<?php
// if this closure is registered in a file at /path/to/project/autoload.php ...
spl_autoload_register(function ($absoluteClass) {
$namespacePrefix = 'Foo\Bar';
$baseDirectory = __DIR__ . '/src/';
if (0 === strncmp($namespacePrefix, $absoluteClass, strlen($namespacePrefix))) {
$relativeClass = substr($absoluteClass, strlen($namespacePrefix));
$relativeFile = str_replace('\\', '/', $relativeClass) . '.php';
$path = $baseDirectory . $relativeFile;
if (is_readable($path)) {
require $path;
return true;
}
}
return false;
});

// ... then the following line would cause the autoloader to attempt to load
// the \Foo\Bar\Dib\Zim class from /path/to/project/src/Dib/Zim.php
new \Foo\Bar\Dib\Zim;
```


### Example: General-Purpose Implementation

The following is one possible general-purpose implementation of the
specification.

```php
<?php
namespace Example;

/**
*
* An example implementation for a package-oriented autoloader. Note that this
* is only an example, and is not a specification in itself.
*
*/
class PackageOrientedAutoloader
{
/**
*
* An array where the key is a namespace prefix, and the value is a
* a base directory for classes in that namespace.
*
* @var array
*
*/
protected $prefix_base = array();

/**
*
* Sets the directory for a namespace prefix.
*
* @param string $prefix The namespace prefix.
*
* @param string $dir The directory containing classes in that
* namespace.
*
* @return void
*
*/
public function setNamespacePrefixBase($prefix, $base)
{
$base = rtrim($base, DIRECTORY_SEPARATOR);
$this->prefix_base[$prefix] = $base;
}

/**
*
* Loads the class file for an absolute class name.
*
* @param string $absolute The absolute class name.
*
*/
public function load($absolute)
{
// a partial relative file name
$relative = '';

// go through the individual names in the absolute class name
$names = explode('\\', $absolute);
while ($names) {

// take the last element off the absolute class name,
// and add it to the partial relative file name
$relative .= DIRECTORY_SEPARATOR . array_pop($names);

// the remaining elements indicate the namespace prefix
$prefix = implode('\\', $names);

// is there a base for this namespace prefix?
if (isset($this->prefix_base[$prefix])) {

// yes. create a complete file name from the namespace dir
// and partial name
$file = $this->prefix_base[$prefix] . $relative . '.php';

// can we read the file from the filesystem?
if ($this->readFile($file)) {
// done!
return true;
}
}
}

// never found a file for the class
return false;
}

/**
*
* Uses `require` to read a file from the filesystem.
*
* @param string $file
*
* @return bool True if the file gets read; false if it does not.
*
*/
protected function readFile($file)
{
if (! is_readable($file)) {
return false;
}

require $file;
return true;
}
}
```

Given the example general-purpose implementation, and a `foo-bar` package of
classes on disk at the following paths ...

/path/to/packages/foo-bar/
src/
Baz.php # Foo\Bar\Baz
Dib/
Zim.php # Foo\Bar\Dib\Zim

... one would register the path to the class files for the `Foo\Bar` namespace
prefix like so:

```php
<?php
// instantiate the loader
$loader = new \Example\PackageOrientedLoader;

// register the base directory for the namespace prefix
$loader->setNamespacePrefixBase(
'Foo\Bar',
'/path/to/packages/foo-bar/src'
);

// register the autoloader
spl_autoload_register(array($loader, 'load'));

// the following line would cause the autoloader to attempt to load
// the \Foo\Bar\Dib\Zim class from /path/to/packages/foo-bar/src/Dib/Zim.php
new \Foo\Bar\Dib\Zim;
```

* * *


-- pmj



pmjones

unread,
May 10, 2013, 11:32:03 AM5/10/13
to php...@googlegroups.com
+1.  Kneel before Zim!

-- pmj

Brett Bieber

unread,
May 10, 2013, 11:38:31 AM5/10/13
to php...@googlegroups.com
+1


On Fri, May 10, 2013 at 10:32 AM, pmjones <pmjo...@gmail.com> wrote:
+1.  Kneel before Zim!

-- pmj



--
Brett Bieber

Phil Sturgeon

unread,
May 10, 2013, 12:36:00 PM5/10/13
to php...@googlegroups.com
+1 from PyroCMS

Obviously.

Pádraic Brady

unread,
May 10, 2013, 1:35:38 PM5/10/13
to php...@googlegroups.com
Zend Framework votes +1

Paddy

--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com
Zend Framework Community Review Team
Zend Framework PHP-FIG Representative

Drak

unread,
May 10, 2013, 1:44:55 PM5/10/13
to php...@googlegroups.com
Sorry it's -1 from me.

Drak





--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Cal Evans

unread,
May 10, 2013, 2:06:49 PM5/10/13
to php...@googlegroups.com
+1

=C=


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
Read this book before you hire a 
developer to build your website.

Jordi Boggiano

unread,
May 11, 2013, 6:53:35 AM5/11/13
to php...@googlegroups.com
+1 



Paul Dragoonis

unread,
May 11, 2013, 11:08:33 AM5/11/13
to php...@googlegroups.com
+1 from PPI Framework


On Sat, May 11, 2013 at 11:53 AM, Jordi Boggiano <j.bog...@seld.be> wrote:
+1 




--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/sj3SQAJlxkEJ.

Larry Garfield

unread,
May 12, 2013, 1:00:08 AM5/12/13
to php...@googlegroups.com
With a more vocal backing from the rest of the Drupal community than
we've had for any other PSR to date, Drupal votes +1. :-)

--Larry Garfield, Drupal

André R.

unread,
May 13, 2013, 3:13:03 AM5/13/13
to php...@googlegroups.com
+1 from eZ.

André R.

unread,
May 13, 2013, 6:22:33 AM5/13/13
to php...@googlegroups.com
Actually, strike that vote, I notice now that this proposal will allow several matching namspaces to exists for a given file, resulting in people writing poorly namespace prefixes that just works because of this:

        if (is_readable($path)) { 
            require $path; 
            return true; 
        } 

But it will work slowly as php does not cache stat calls for non existing files (and neither should it).
I'll bring this up on the discussion thread, please do not reply to this mail.

André R.

unread,
May 13, 2013, 12:11:51 PM5/13/13
to php...@googlegroups.com
So -1 from eZ (don't see a need for a competing autoload spec, a spec that updates and obsoletes Psr0 would be better)


IMO: If this is in the end accepted, we should consider straight away getting started on a PSR that merges, updates and obsoletes both.

Donald Gilbert

unread,
May 14, 2013, 11:14:22 AM5/14/13
to php...@googlegroups.com
+1 from the Joomla project.

This is a feature we lost when switching to PSR-0 when creating all our packages.

Larry Garfield

unread,
May 16, 2013, 10:13:49 PM5/16/13
to php...@googlegroups.com
As the proposal that was put to a vote has been retracted and replaced
with a modified one, I am forced to change my vote to -1. Changing a
proposal mid-vote is absolutely not a precedent we should be setting,
and I encourage all other voting representatives to reject that
precedent outright, as it has been rejected in other organizations.

--Larry Garfield, Drupal

Paul Jones

unread,
May 17, 2013, 1:28:20 AM5/17/13
to php...@googlegroups.com

On May 16, 2013, at 9:13 PM, Larry Garfield wrote:

> As the proposal that was put to a vote has been retracted and replaced with a modified one, I am forced to change my vote to -1. Changing a proposal mid-vote is absolutely not a precedent we should be setting, and I encourage all other voting representatives to reject that precedent outright, as it has been rejected in other organizations.

As I noted elsewhere, I concur, and I apologize for even suggesting that it might be permissible. Although the merging of the change was outside my purview, it did in fact occur, and I agree that it renders the vote invalid.

As such, I hereby withdraw the proposal. I will re-submit it for a vote at a later time.

Again, my apologies.


-- pmj

Larry Garfield

unread,
May 17, 2013, 1:39:52 AM5/17/13
to php...@googlegroups.com
Thank you, Paul. We should probably take a few days (a very few) to
make sure there's no other t's that need dotting or i's that need
crossing and then resubmit with these last tweaks so that we can get it
approved.

--Larry Garfield

Drak

unread,
May 17, 2013, 1:42:24 AM5/17/13
to php...@googlegroups.com
I am glad about this because maybe we can now address the point of not somehow competing with PSR-0 but improving upon it. This is a good thing. Sorry you had to be the fall guy, but you have done a good thing anyway, the proposal needs work (or a bullet).

Drak 

Larry Garfield

unread,
May 17, 2013, 2:12:41 AM5/17/13
to php...@googlegroups.com
As written, it's impossible for PSR-X to be a superset or subset of PSR-0.  The overlap between the two would be classes that follow the name => directory mapping, with a prefix a la PSR-X, but the classes just so happen to not have underscores.  That's the majority of classes that use PHP 5.3, but not 100%.

So the only way to make PSR-X be 100% BC with PSR-0 would be to limit it to JUST "oh yeah, and you can specify a root prefix", with the degenerate case being no prefix, aka what PSR-0 does today.

And the advantage of that would be...  What?  So you can have One Autoloader To Rule Them All?  Why?  PHP is designed to support multiple autloaders at the same time.  There's nothing wrong with that, as long as you don't go overboard with it.  I really don't get why people are allergic to multiple autoloaders being registered.  And even then, there's nothing stopping a single implementation from supporting both.  It's totally doable.

And if you're using Composer, I'd expect it would just compile everything together somehow anyway and you're still back to a single autoloader class actually running.

So really, I don't see what the big deal is.

--Larry Garfield

Nathan Haug

unread,
May 17, 2013, 2:33:04 AM5/17/13
to php...@googlegroups.com
Although the language of package-based autoloader makes it clear that it's merely an *alternative* to PSR-0, and several people have re-iterated that on this list, I think that referring to it as an alternative instead of replacement downplays the real-world migration that would result from a new standard. The package autoloader proposal is a less-confusing (no special underscore handling) and more-flexible (arbitrary directory-to-namespace prefixing) than PSR-0. For most projects, that's two upsides and no downsides. I would predict that every project currently basing its loading or directory structure on PSR-0 would quickly convert to PSR-X at the first opportunity. In practice there would be little reason to keep using PSR-0. In that sense, PSR-X is deprecating PSR-0.

TL;DR: PSR-X really is a replacement for PSR-0.

--
Nathan Haug
Sent with Sparrow (http://bit.ly/sigsprw)


On Thursday, May 16, 2013 at 11:12 PM, Larry Garfield wrote:

> On 05/17/2013 12:42 AM, Drak wrote:
> --
> You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com (mailto:php-fig+u...@googlegroups.com).
> To post to this group, send email to php...@googlegroups.com (mailto:php...@googlegroups.com).

Phil Sturgeon

unread,
May 17, 2013, 12:06:29 PM5/17/13
to php...@googlegroups.com

TL;DR: PSR-X really is a replacement for PSR-0.
  
I've been wondering recently if this would be such a bad thing. I can understand the need for us to not scare folks that have implemented PSR-0 for their code, so we cant call it dead, but if we say "A new autoloader has been defined which drops the _ stuff and adds some flexibility on where the prefix maps to" then thats not so hard for people to understand.

PSR-X is like PSR-0, but better.

Zachary King

unread,
May 17, 2013, 12:19:04 PM5/17/13
to php...@googlegroups.com
Personally I would prefer that there be *one* standard, but it does not matter to me that much, and I am not an experience developer. So... just my 2 cents worth.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Donald Gilbert

unread,
May 17, 2013, 12:40:57 PM5/17/13
to php...@googlegroups.com
As Larry said, since the proposal was altered, I'm changing my vote to -1 on principle.

There is no voting-protocol for retracting a vote, so it could be confusing as to how those who have already voted should proceed. We should amend the voting protocol bylaw to the effect of:

0) A proposal MUST NOT be altered during the voting process.
0a) If a proposal is altered during the voting process, voting SHALL immediately cease and all votes already cast are invalidated.

1a) Only the member who called for the vote on a proposal may withdraw the call. If the call for votes is withdrawn, voting SHALL immediately cease and all votes already cast are invalidated.

Drak

unread,
May 17, 2013, 12:42:55 PM5/17/13
to php...@googlegroups.com
I believe the vote proposal has now been withdrawn anyway, so this current vote is dead. Correct me if I'm wrong.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Donald Gilbert

unread,
May 17, 2013, 12:52:16 PM5/17/13
to php...@googlegroups.com
Even still, there's no voting protocol stating that a proposal CAN be withdrawn from vote, is there? Sure, this is the first time we have to deal with it, but let's deal with it and modify our bylaws to dictate how this should be done in the future.

That's the main reason for me posting.

Paul Jones

unread,
May 17, 2013, 1:22:23 PM5/17/13
to php...@googlegroups.com

On May 17, 2013, at 11:52 AM, Donald Gilbert wrote:

> Even still, there's no voting protocol stating that a proposal CAN be withdrawn from vote, is there? Sure, this is the first time we have to deal with it, but let's deal with it and modify our bylaws to dictate how this should be done in the future.
>
> That's the main reason for me posting.

Yup, I get you. I don't want to call another vote on it for at least a week anyway, to make sure it times out properly. You're right, we do need rules for invalidation and withdrawal.

Meanwhile, I have withdrawn the proposal from vote, so if we can go on a "gentlemen's agreement" here that the vote is done, that would be appreciated.


-- pmj

Paul Dragoonis

unread,
May 18, 2013, 8:05:16 AM5/18/13
to php...@googlegroups.com
It's all good Paul. Lets start another thread if necessary to discuss anything needing refined and then re-call the vote :)


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Paul Jones

unread,
May 24, 2013, 4:08:39 PM5/24/13
to php...@googlegroups.com

On May 17, 2013, at 1:33 AM, Nathan Haug wrote:

> Although the language of package-based autoloader makes it clear that it's merely an *alternative* to PSR-0, and several people have re-iterated that on this list, I think that referring to it as an alternative instead of replacement downplays the real-world migration that would result from a new standard. The package autoloader proposal is a less-confusing (no special underscore handling) and more-flexible (arbitrary directory-to-namespace prefixing) than PSR-0. For most projects, that's two upsides and no downsides. I would predict that every project currently basing its loading or directory structure on PSR-0 would quickly convert to PSR-X at the first opportunity. In practice there would be little reason to keep using PSR-0. In that sense, PSR-X is deprecating PSR-0.
>
> TL;DR: PSR-X really is a replacement for PSR-0.

This is an interesting analysis. It might indeed become more prevalent than PSR-0. I would that that *only at that time* should PSR-0 be deprecated; that is, only as adherence dwindles.


-- pmj

Reply all
Reply to author
Forward
0 new messages