# [PATCH] Namespace Patch, Beta 1

- Thread: https://externals.io/message/17484
- Original archive: https://news-web.php.net/php.internals/17484
- Started by Jessie Hernandez on 2005-08-02T04:07:03+00:00
- Messages: 15
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #17484 — Jessie Hernandez — 2005-08-02T04:07:03+00:00

URL: https://externals.io/message/17484#17484

Attached is the latest version of the namespace patch! It finally includes
namespace imports and it even includes anonymous namespace support. Also,
the previous bison shift/reduce conflict has been removed. Here is a
summary of its features:

- Simple imports: import ns:class1;
- Import aliases: import ns:class1 as my_alias;
- Namespace imports: import namespace ns;
- Anonymous namespaces:  namespace { class file_class{} }
- Namespace-private classes: namespace ns{ private class prv_class{} }

Two new functions have also been added to support namespace imports (more on
that below):

- get_imported_namespaces([$className])
Returns an array of imported namespaces for the current file. If a class
name is passed, and this class is currently being autoloaded (also meaning
that this function is called inside __autoload), then the list of returned
imported namespaces is based on the file that triggered the __autoload
call.

- autoload_import_class($className, $namespaceName)
Imports a class in a given namespace for the currently executing file (can
ONLY be used inside __autoload!)

Imports
-------
Imports and namespace imports are handled completely by the user with the
use of the __autloload function. This means that there are no restrictions
on class file naming/directory structure. For simple imports, the class
name will be passed with its full name (including the colons, such as
"ns:class1"). For namespace imports, only the class name will be called.
Since the user needs to determine which namespace (or namespaces) a class
belongs to, the "get_imported_namespaces" function is provided to check the
imported namespaces for the currently-executing file. Once the user is
satisfied with a match, he/she needs to perform an "import" for this class,
but this needs to be done on the executing file, not the file where
__autoload is defined. For this reason, the autoload_import_class function
is provided. A sample usage of both these functions is at
tests/classes/namespace_autoload.php.

Namespace-private classes
-------------------------
Classes marked as "private" from within a namespace can only be used by
classes defined in the same namespace.

Anonymous namespaces
--------------------
Classes defined inside anonymous namespaces can only be used within the file
that declared the anonymous namespace.


I believe the attached patch solves the issues that were presented long ago
for namespaces. Referring to the post by Daniel Cogwill at
http://www.zend.com/lists/engine2/200304/msg00164.html, the following are
my answers to the problems he found at the time:

1) import-all silently hides local names.
A: If a global class is defined with the same name as a class in a
namespace, and the namespace class has been imported in the same script,
the global class takes precedence. The namespace class can still be used by
using its full name, i.e. namespace_name:class_name.

2) Interestingly (and I assume this is simply a bug), functions and classes
behave differently wrt to import-all and duplicate definitions.
A: Irrelevant in this patch.

3) There is no way to hide names from import (i.e. make a name
non-exportable). This is a fundamental namespace feature, and there is
already an appropriate keyword (private).
A: Namespace-private classes are supported, using the "private" keyword.

4) The semantic meaning of successive imports depends on their relative
ordering.
A: The engine does not attempt to determine which class is included, the
user decides the most appropriate behavior  inside __autoload.

5) The most egregious issue is that an import in an included file affects
the scope of the including file.
A: Imports in this patch only affect the file they are in.


Since I could not find a way to add the tests/classes/namespace directory
and subdirectories, I zipped them separately, as before.

Let me know if you have any questions on the attached patch.


Best regards,

Jessie Hernandez

---

## #17488 — dz@bitxtender.com — 2005-08-02T09:16:49+00:00

URL: https://externals.io/message/17484#17488 · In reply to: #17484

This sounds awesome. Good job, Jessie. Keep it up!

- David


> -----Original Message-----
> From: Jessie Hernandez [mailto:jrhernandez05@gmail.com]
> Sent: Tuesday, August 02, 2005 6:07 AM
> To: internals@lists.php.net
> Subject: [PHP-DEV] [PATCH] Namespace Patch, Beta 1
> 
> Attached is the latest version of the namespace patch! It finally includes
> namespace imports and it even includes anonymous namespace support. Also,
> the previous bison shift/reduce conflict has been removed. Here is a
> summary of its features:
> 
> - Simple imports: import ns:class1;
> - Import aliases: import ns:class1 as my_alias;
> - Namespace imports: import namespace ns;
> - Anonymous namespaces:  namespace { class file_class{} }
> - Namespace-private classes: namespace ns{ private class prv_class{} }
> 
> Two new functions have also been added to support namespace imports (more
> on
> that below):
> 
> - get_imported_namespaces([$className])
> Returns an array of imported namespaces for the current file. If a class
> name is passed, and this class is currently being autoloaded (also meaning
> that this function is called inside __autoload), then the list of returned
> imported namespaces is based on the file that triggered the __autoload
> call.
> 
> - autoload_import_class($className, $namespaceName)
> Imports a class in a given namespace for the currently executing file (can
> ONLY be used inside __autoload!)
> 
> Imports
> -------
> Imports and namespace imports are handled completely by the user with the
> use of the __autloload function. This means that there are no restrictions
> on class file naming/directory structure. For simple imports, the class
> name will be passed with its full name (including the colons, such as
> "ns:class1"). For namespace imports, only the class name will be called.
> Since the user needs to determine which namespace (or namespaces) a class
> belongs to, the "get_imported_namespaces" function is provided to check
> the
> imported namespaces for the currently-executing file. Once the user is
> satisfied with a match, he/she needs to perform an "import" for this
> class,
> but this needs to be done on the executing file, not the file where
> __autoload is defined. For this reason, the autoload_import_class function
> is provided. A sample usage of both these functions is at
> tests/classes/namespace_autoload.php.
> 
> Namespace-private classes
> -------------------------
> Classes marked as "private" from within a namespace can only be used by
> classes defined in the same namespace.
> 
> Anonymous namespaces
> --------------------
> Classes defined inside anonymous namespaces can only be used within the
> file
> that declared the anonymous namespace.
> 
> 
> I believe the attached patch solves the issues that were presented long
> ago
> for namespaces. Referring to the post by Daniel Cogwill at
> http://www.zend.com/lists/engine2/200304/msg00164.html, the following are
> my answers to the problems he found at the time:
> 
> 1) import-all silently hides local names.
> A: If a global class is defined with the same name as a class in a
> namespace, and the namespace class has been imported in the same script,
> the global class takes precedence. The namespace class can still be used
> by
> using its full name, i.e. namespace_name:class_name.
> 
> 2) Interestingly (and I assume this is simply a bug), functions and
> classes
> behave differently wrt to import-all and duplicate definitions.
> A: Irrelevant in this patch.
> 
> 3) There is no way to hide names from import (i.e. make a name
> non-exportable). This is a fundamental namespace feature, and there is
> already an appropriate keyword (private).
> A: Namespace-private classes are supported, using the "private" keyword.
> 
> 4) The semantic meaning of successive imports depends on their relative
> ordering.
> A: The engine does not attempt to determine which class is included, the
> user decides the most appropriate behavior  inside __autoload.
> 
> 5) The most egregious issue is that an import in an included file affects
> the scope of the including file.
> A: Imports in this patch only affect the file they are in.
> 
> 
> Since I could not find a way to add the tests/classes/namespace directory
> and subdirectories, I zipped them separately, as before.
> 
> Let me know if you have any questions on the attached patch.
> 
> 
> Best regards,
> 
> Jessie Hernandez

---

## #17489 — John LeSueur — 2005-08-02T09:27:25+00:00

URL: https://externals.io/message/17484#17489 · In reply to: #17484

Jessie Hernandez wrote:

>Attached is the latest version of the namespace patch! It finally includes
>namespace imports and it even includes anonymous namespace support. Also,
>the previous bison shift/reduce conflict has been removed. Here is a
>summary of its features:
>
>- Simple imports: import ns:class1;
>- Import aliases: import ns:class1 as my_alias;
>- Namespace imports: import namespace ns;
>- Anonymous namespaces:  namespace { class file_class{} }
>- Namespace-private classes: namespace ns{ private class prv_class{} }
>
>Two new functions have also been added to support namespace imports (more on
>that below):
>
>- get_imported_namespaces([$className])
>Returns an array of imported namespaces for the current file. If a class
>name is passed, and this class is currently being autoloaded (also meaning
>that this function is called inside __autoload), then the list of returned
>imported namespaces is based on the file that triggered the __autoload
>call.
>
>  
>
so, if I understand correctly, if your __autoload is defined in a 
different file(file1) from where the import was
called(file2), then get_imported_namespaces() returns the namespace 
imports for file1.
get_imported_namespaces($className) would return for file2, and outside 
of the __autoload function,
get_imported_namespaces($className) would return the namespaces for 
file1. That seems like
complicated semantics. Is there some way this could be simplified? Maybe 
there should be two functions,
one that returns namespaces for file2 and is incorrect(throws an error) 
to call from anywhere other than
__autoload(), and one that returns namespaces for file2.

>- autoload_import_class($className, $namespaceName)
>Imports a class in a given namespace for the currently executing file (can
>ONLY be used inside __autoload!)
>
>Imports
>-------
>Imports and namespace imports are handled completely by the user with the
>use of the __autloload function. This means that there are no restrictions
>on class file naming/directory structure. For simple imports, the class
>name will be passed with its full name (including the colons, such as
>"ns:class1"). For namespace imports, only the class name will be called.
>Since the user needs to determine which namespace (or namespaces) a class
>belongs to, the "get_imported_namespaces" function is provided to check the
>imported namespaces for the currently-executing file. Once the user is
>satisfied with a match, he/she needs to perform an "import" for this class,
>  
>
This seems like it would be slow, as the user might have many 
namespaces(directories) to search for matching
files. This would of course be up to the user. And it doesn't bother me 
that a full namespace import
may not be as fast as a more specific import. In development it might be 
convenient, but at some point, it's not
that big a deal to specify the classes you use.

>but this needs to be done on the executing file, not the file where
>__autoload is defined. For this reason, the autoload_import_class function
>is provided. A sample usage of both these functions is at
>tests/classes/namespace_autoload.php.
>  
>
I like the option of having namespaces, and from the description this 
seems to be a light method of doing it. It does
require some effort from the user. It seems that for most cases 
__autoload will be the same every time, maybe with
different paths or file naming conventions.

John

---

## #17496 — Jessie Hernandez — 2005-08-02T15:00:57+00:00

URL: https://externals.io/message/17484#17496 · In reply to: #17489

"John LeSueur" <john@supernerd.com> wrote in message
news:42EF3C7D.9000105@supernerd.com...
> > […]
> so, if I understand correctly, if your __autoload is defined in a
> different file(file1) from where the import was
> called(file2), then get_imported_namespaces() returns the namespace
> imports for file1.
> get_imported_namespaces($className) would return for file2, and outside
> of the __autoload function,
> get_imported_namespaces($className) would return the namespaces for
> file1. That seems like
> complicated semantics. Is there some way this could be simplified? Maybe
> there should be two functions,
> one that returns namespaces for file2 and is incorrect(throws an error)
> to call from anywhere other than
> __autoload(), and one that returns namespaces for file2.
>

To clarify the usage of this function (using your same example of file1 and
file2):

- get_imported_namespaces() can be called in any file. It will return the
namespace imports for the currently-executing file (whether it's file1 or
file2).
- When inside __autoload, get_imported_namespaces($className) will return
the namespace imports for the file that triggered the __autoload call (in
this case, file2).
- When not inside __autoload, get_imported_namespaces($className) will
return an empty array.

I don't think the above usage is complicated. The only thing that can be
changed is the behavior of get_imported_namespaces($className) when not
inside __autoload. Right now it's returning an empty array. Will it be
better to return false and/or generate an error?


> > […]
restrictions
> > […]
the
> > […]
class,
> > […]
> This seems like it would be slow, as the user might have many
> namespaces(directories) to search for matching
> files. This would of course be up to the user. And it doesn't bother me
> that a full namespace import
> may not be as fast as a more specific import. In development it might be
> convenient, but at some point, it's not
> that big a deal to specify the classes you use.
>

This same search would have to be done by the engine, and although a bit
faster, this could also be slow depending on the number of imported
namespaces. Also, if the search is done by the engine, then a file
structure/naming convention would have to be enforced (that's why I had the
class_path .ini variable before), and some already mentioned that they have
different conventions, hence we need to provide flexibility to the user.

I agree with you that it's not a big deal to be explicit in specifying which
classes will be imported (in fact, when I have to write a Java class at
work, I always specify each class one-by-one, regardless of how many imports
I have to do, as it also makes the code clearer).


> > […]
function
> > […]
> I like the option of having namespaces, and from the description this
> seems to be a light method of doing it. It does
> require some effort from the user. It seems that for most cases
> __autoload will be the same every time, maybe with
> different paths or file naming conventions.
>

You are correct, this is a very lightweight implementation. Very few (from
2-4 IIRC, depending on the type of import) hashtables are searched (this is
including class_table), and this number does not increase with the number of
class imports nor with the number of namespace imports.

Right now, it requires some initial effort from the user to implement the
imports, but as you said, this would only need to be done once (once the
__autoload function is defined, this can be included from all other
scripts).

--
Jessie

---

## #17497 — Jessie Hernandez — 2005-08-02T15:17:45+00:00

URL: https://externals.io/message/17484#17497 · In reply to: #17489

Forgot to mention, since I expect the majority of users to follow the PEAR
convention for their classes (basically one class per file, file is named
like class, with "namespace" directories), then maybe a default
implementation can be provided in SPL's autoload. That way, namespace
imports can be used "out of the box".

Marcus, what do you think?


Regards,

Jessie Hernandez

---

## #17498 — Michael Wallner — 2005-08-02T16:01:18+00:00

URL: https://externals.io/message/17484#17498 · In reply to: #17497

Hi Jessie Hernandez, you wrote:

> Forgot to mention, since I expect the majority of users to follow the PEAR
> convention for their classes (basically one class per file, file is named
> like class, with "namespace" directories)

With the minor but essential logical difference:
	$file = strtr($class, '_', '/')
I don't know if you took that into account though...

Regards,
--
Michael - < mike(@)php.net

---

## #17499 — Jessie Hernandez — 2005-08-02T16:11:49+00:00

URL: https://externals.io/message/17484#17499 · In reply to: #17498

Hi Michael,

Yes, I am aware of this. Underscores were used due to the lack of
namespaces. For user classes which use namespaces (and in the case where
some PEAR classes get modified to be under namespaces), the colon would be
used as the separator, and this would get replaced by the slash to form the
file path.


--
Jessie

---

## #17502 — Andi Gutmans — 2005-08-02T16:51:32+00:00

URL: https://externals.io/message/17484#17502 · In reply to: #17484

FYI, I haven't had a chance to look at this patch yet (nor a lot of the 
emails on the subject). After PHP 5.1 goes RC and we start our Unicode 
work, I should have time to look into it. Interesting to see if it 
addresses the issues we had in the past. I think some of them weren't 
solvable although if this only addresses classes it might have. One note, 
we need to make sure we don't complicate the language too much... But 
anyway, hopefully next week or so I'll have more constructive feedback.


At 12:07 AM 8/2/2005 -0400, Jessie Hernandez wrote:
>Attached is the latest version of the namespace patch! It finally includes
>namespace imports and it even includes anonymous namespace support. Also,
>the previous bison shift/reduce conflict has been removed. Here is a
>summary of its features:
>
>- Simple imports: import ns:class1;
>- Import aliases: import ns:class1 as my_alias;
>- Namespace imports: import namespace ns;
>- Anonymous namespaces:  namespace { class file_class{} }
>- Namespace-private classes: namespace ns{ private class prv_class{} }
>
>Two new functions have also been added to support namespace imports (more on
>that below):
>
>- get_imported_namespaces([$className])
>Returns an array of imported namespaces for the current file. If a class
>name is passed, and this class is currently being autoloaded (also meaning
>that this function is called inside __autoload), then the list of returned
>imported namespaces is based on the file that triggered the __autoload
>call.
>
>- autoload_import_class($className, $namespaceName)
>Imports a class in a given namespace for the currently executing file (can
>ONLY be used inside __autoload!)
>
>Imports
>-------
>Imports and namespace imports are handled completely by the user with the
>use of the __autloload function. This means that there are no restrictions
>on class file naming/directory structure. For simple imports, the class
>name will be passed with its full name (including the colons, such as
>"ns:class1"). For namespace imports, only the class name will be called.
>Since the user needs to determine which namespace (or namespaces) a class
>belongs to, the "get_imported_namespaces" function is provided to check the
>imported namespaces for the currently-executing file. Once the user is
>satisfied with a match, he/she needs to perform an "import" for this class,
>but this needs to be done on the executing file, not the file where
>__autoload is defined. For this reason, the autoload_import_class function
>is provided. A sample usage of both these functions is at
>tests/classes/namespace_autoload.php.
>
>Namespace-private classes
>-------------------------
>Classes marked as "private" from within a namespace can only be used by
>classes defined in the same namespace.
>
>Anonymous namespaces
>--------------------
>Classes defined inside anonymous namespaces can only be used within the file
>that declared the anonymous namespace.
>
>
>I believe the attached patch solves the issues that were presented long ago
>for namespaces. Referring to the post by Daniel Cogwill at
>http://www.zend.com/lists/engine2/200304/msg00164.html, the following are
>my answers to the problems he found at the time:
>
>1) import-all silently hides local names.
>A: If a global class is defined with the same name as a class in a
>namespace, and the namespace class has been imported in the same script,
>the global class takes precedence. The namespace class can still be used by
>using its full name, i.e. namespace_name:class_name.
>
>2) Interestingly (and I assume this is simply a bug), functions and classes
>behave differently wrt to import-all and duplicate definitions.
>A: Irrelevant in this patch.
>
>3) There is no way to hide names from import (i.e. make a name
>non-exportable). This is a fundamental namespace feature, and there is
>already an appropriate keyword (private).
>A: Namespace-private classes are supported, using the "private" keyword.
>
>4) The semantic meaning of successive imports depends on their relative
>ordering.
>A: The engine does not attempt to determine which class is included, the
>user decides the most appropriate behavior  inside __autoload.
>
>5) The most egregious issue is that an import in an included file affects
>the scope of the including file.
>A: Imports in this patch only affect the file they are in.
>
>
>Since I could not find a way to add the tests/classes/namespace directory
>and subdirectories, I zipped them separately, as before.
>
>Let me know if you have any questions on the attached patch.
>
>
>Best regards,
>
>Jessie Hernandez

---

## #17512 — Marcus Boerger — 2005-08-03T17:08:50+00:00

URL: https://externals.io/message/17484#17512 · In reply to: #17497

Hello Jessie,

  what ever you want auto-of-the-box is good. I suggest the simplest
possible way as default which is we simply stay like we are doing now and
only include a replacement from ':' to the current directory separator.
That we would be searching for '.inc' and '.inc.php' per default in the
include_path directories.

marcus

Tuesday, August 2, 2005, 5:17:45 PM, you wrote:

> Forgot to mention, since I expect the majority of users to follow the PEAR
> convention for their classes (basically one class per file, file is named
> like class, with "namespace" directories), then maybe a default
> implementation can be provided in SPL's autoload. That way, namespace
> imports can be used "out of the box".

> Marcus, what do you think?


> Regards,

> Jessie Hernandez




Best regards,
 Marcus

---

## #17513 — Marcus Boerger — 2005-08-03T17:08:57+00:00

URL: https://externals.io/message/17484#17513 · In reply to: #17498

Hello Michael,

  i suffest that pear finally takes a better approach with the arrival of
namespaces then the ugly workaround of '_'. If pear doesn#t want to i
suggest pear simply writes it's own __autoload().

marcus
  

Tuesday, August 2, 2005, 6:01:18 PM, you wrote:

> Hi Jessie Hernandez, you wrote:

> > […]

> With the minor but essential logical difference:
>         $file = strtr($class, '_', '/')
> I don't know if you took that into account though...

> Regards,
> --
> Michael - < mike(@)php.net >



Best regards,
 Marcus

---

## #17514 — Michael Wallner — 2005-08-03T17:11:20+00:00

URL: https://externals.io/message/17484#17514 · In reply to: #17513

Hi Marcus Boerger, you wrote:

> Hello Michael,
>
>   i suffest that pear finally takes a better approach with the arrival of
> namespaces then the ugly workaround of '_'.

Of course -- PEAR would benefit a lot of namespaces!

--
Michael - < mike(@)php.net

---

## #17516 — Jessie Hernandez — 2005-08-03T20:40:08+00:00

URL: https://externals.io/message/17484#17516 · In reply to: #17512

Hello Marcus,

This simple change will make class imports work out of the box, which is
pretty good. What won't work out of the box are namespace imports. I think
we should provide this also (using the same logic as I'm using in
namespace_autoload.php). Even though this will complicate the default
spl_autoload function, namespace imports would work by default and will be
faster than the userland code. I'll try to add the spl_autoload changes in
my patch in the next few days.

Also, I just looked at the php_spl.c code, is there any reason why .php is
not in the list of default extensions? It'd be nice if the default
extensions were .php, .inc, and .inc.php.


Best regards,

Jessie



"Marcus Boerger" <helly@php.net> wrote in message
news:13210444107.20050803190850@marcus-boerger.de...
> Hello Jessie,
>
>   what ever you want auto-of-the-box is good. I suggest the simplest
> possible way as default which is we simply stay like we are doing now and
> only include a replacement from ':' to the current directory separator.
> That we would be searching for '.inc' and '.inc.php' per default in the
> include_path directories.
>
> marcus
>
> Tuesday, August 2, 2005, 5:17:45 PM, you wrote:
>
> > […]
PEAR
> > […]
named
> > […]
>
> > […]
>
>
> > […]
>
> > […]
>
>
>
>
> Best regards,
>  Marcus

---

## #17517 — James Crumpton — 2005-08-03T21:28:11+00:00

URL: https://externals.io/message/17484#17517 · In reply to: #17516

Maybe I'm alone on this, but all my class files are named as 
Classname.class.php... (hint, hint) :)

...

On second thought, maybe it would be interesting/useful to have some mechanism 
to allow a formatted string like "%s.foo.php" or "foo.%s.php" to be used by 
spl's autoload? Not really sure how it would be implemented... A php.ini setting 
    ;), or from a constant or something. *shrug* dunno, just thinking out loud.


Jessie Hernandez wrote:
> Also, I just looked at the php_spl.c code, is there any reason why .php is
> not in the list of default extensions? It'd be nice if the default
> extensions were .php, .inc, and .inc.php.

---

## #17518 — l0t3k — 2005-08-03T21:37:33+00:00

URL: https://externals.io/message/17484#17518 · In reply to: #17484

Jesse,
  another thing to consider (if you havent already) is extension support. 
IOW, how do i place my extension-created class into a namespace. Is this as 
simple as declaring the class name as Ns:Class ?

l0t3k

---

## #17519 — Jessie Hernandez — 2005-08-03T21:49:46+00:00

URL: https://externals.io/message/17484#17519 · In reply to: #17518

Yep, it's that simple! You can even import it and it'll work! In
zend_lookup_class, the standard class_table search is done first, but on
failure, before it calls __autoload, the class name will try to be
"resolved" using the import table for the executing file. If a matching
entry in the import table is found, then it'll again try to search in
class_table using the full name. Since this class has been defined in the
extension, the search would be successful and __autoload will not be called.


--
Jessie


""l0t3k"" <cshmoove@hotmail.com> wrote in message
news:FC.7B.04646.FC831F24@pb1.pair.com...
> Jesse,
>   another thing to consider (if you havent already) is extension support.
> IOW, how do i place my extension-created class into a namespace. Is this
as
> simple as declaring the class name as Ns:Class ?
>
> l0t3k
