Title:           Zend 2.0 Namespaces
Version:         $Id: aaef2827c11ef1b0f4c4e4e2916c1ebfd47f0509 $
Status:          declined
Maintainer:      Stig S. Bakken <ssb@php.net>
Created:         2001-09-08
Modified:        2001-09-08


1. Background/Need
==================

PHP and Zend 1.0 have come to a point where a lot of reusable code is
being written; from simple functions and classes to entire application
frameworks.  It is becoming increasingly difficult to avoid symbol
name collisions with the current scoping methods.

The symbol scopes available in Zend 1.0 are the global scope, the
class scope and the function scope.  All scopes but classes may
contain variables, only the class and global scopes may contain
functions, while only the global scope may contain constants and
classes.  This means that all of Zend 1.0's scoping methods are
inherently limited for solving symbol name collision problems.


2. Overview
===========

Namespaces in Zend 2.0 provide a way to manage the symbol collision
problem by making it possible to define multiple symbol tables able to
contain all types of symbols.  Zend will get the notion of a current
namespace, defaulting to the current global one.  The current name
space may be changed on a file-by-file basis.  Symbols in other name
spaces than the current one may be referenced using a new namespace
operator.  It will be possible to "import" symbols from one namespace
into another.


3. Functionality
================

3.1. Namespace Syntax
=====================

The namespace operator ":" is used to refer to symbols in other
namespaces than the current one:

Class:          Namespace:class
Function:       Namespace:function
Static method:  Namespace:class::method
Variable:       $Namespace:variable
Constant:       Namespace:CONSTANT
Class variable: $Namespace:class::variable

To refer to symbols in the global namespace, symbols are prefixed with
only the namespace operator:

Class:          :class
Function:       :function
Static method:  :class::method
Variable:       $:variable
Constant:       :CONSTANT
Class variable: $:class::variable

Note: $:variable will effectively be just another syntax for
$GLOBALS['variable'].

A namespace may have a name containing a ":", it is always the last
":" character in the symbol qualifier that is the actual namespace
operator:

Class:          Name:Space:class
Function:       Name:Space:function
Static method:  Name:Space:class::method
Variable:       $Name:Space:variable
Constant:       Name:Space:CONSTANT
Class variable: $Name:Space:class::variable

(Here, the ":" between "Name" and "Space" is part of the name, it is
the one after "Space" that is the namespace operator.)


3.2. Defining Namespaces
========================

Individual files may define a namespace that will apply to the entire
file.  If no "namespace" operator occurs in the file, it will be in
the global namespace:

 1 namespace HTML;
 2
 3 class Form {
 4     function Form() {
 5         // constructor
 6     }
 7     // ...
 8 }

Or with the "nested" name syntax:

 1 namespace HTML:Form;
 2
 3 class Image {
 4     var $src;
 5     function Image($src) {
 6         $this->src = $src;
 7     }
 8     // ...
 9 }

Code executed within the "HTML" namespace may refer to the Form class
as just "Form".  Code executed from within other namespaces has to
refer to it as "HTML:Form".  The "namespace" statement must occur
before any other statements in the file.

# [ssb 2001-09-08]:
# Should it be possible to "add" symbols to a namespace by including a
# second file with the same namespace statement?


3.3. Importing Symbols
======================

It is possible to import symbols from another namespace into the
current one with the "import" statement:

  import * from HTML;          // all symbols

  import Form from HTML;       // single symbols

  import Form,Table from HTML; // multiple symbols

There is a potential for name clashes between symols of different
types that have the same qualifier syntax.  These are resolved in this
order: class, function, constant.

Optionally, the symbol type may be explicitly given to import (as
"class", "function", "variable" or "constant"):

  import class Form from HTML;

And finally, you may import all symbols of a given type:

  import constant * from HTML:Table;

The namespace with its symbols must already be defined before using
"import".


4. Compatibility Notes
======================

Old code that does not take advantage of namespaces will run without
modifications.


5. Dependencies
===============

The class variable syntax depends on this class variables being
implemented in the new ZE2 object model.


6. Acknowledgements
===================

Andi Gutmans <andi@zend.com> and Zeev Suraski <zeev@zend.com> for
initial ZE2 namespaces proposal

Dean Hall <php@apt7.com> for the initial symbol qualification syntax
