# [PATCH] Namespace Patch, Alpha 3

- Thread: https://externals.io/message/17332
- Original archive: https://news-web.php.net/php.internals/17332
- Started by Jessie Hernandez on 2005-07-20T04:05:30+00:00
- Messages: 28
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/17332.md?page=2
- 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

---

## #17332 — Jessie Hernandez — 2005-07-20T04:05:30+00:00

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

Private class support has been completed in the attached patch! Again, to
reiterate from my last post, the attached patch is a CVS patch, as some
requested me to do. I could not add the test files to the patch because
"cvs add" failed with a "cvs add requires write access to the repository"
error (any way to fix this?).

Also, import statements now include the class files, using a new .ini
variable, "class_path". Files under the directories in the class_path have
the namespace names as directories and the class names named exactly as the
file that declares it (like Java), e.g. my_ns:class1 is declared in
$class_path/my_ns/class1.php.

Again, the only missing feature I know of is "namespace imports". I've been
thinking about it, and I think the best approach is actually very simple.
Right now, when an undefined class is found, the __autoload function is
called from zend_lookup_class to attempt to declare the class at that
point. What I propose is to modify zend_lookup_class to do an additional
lookup, either before/after the __autoload function, for namespace imported
classes. Here's an example:

<?php
import namespace my_namespace1;
// my_namespace1 is added to a runtime hashtable
import namespace my_namespace2;
// my_namespace2 is added to a runtime hashtable

$a = new class1();
?>

At compile-time, the "my_namespace1" and "my_namespace2" strings are saved
in a runtime hashtable. At runtime, zend_lookup_class will be called on
"class1", as usual. Before/after __autoload, this hashtable will be
traversed for the file "class1.php". So in the above example, an attempt to
include "$class_path/my_namespace1/class1.php" will be done. If that fails,
then my_namespace2 is tried, and so forth. If one of these attempts
succeed, then the import alias is also added to the import hashtable for
the currently-executed file, as if the user had added "import
my_namespace1:class1" to the script.

(BTW, is there a way to construct an opcode at runtime and execute it
immediately? If not, I'll have to duplicate the code I have for
ZEND_IMPORT_CLASS in another function).

I think this approach is the easiest and most sensible for namespace import
support. It is no more than a specialized "__autoload". If there are no
objections, I'll start working on it next week. As always,
comments/suggestions are most appreciated.


Regards,

Jessie Hernandez

---

## #17333 — Marcus Boerger — 2005-07-20T06:36:43+00:00

URL: https://externals.io/message/17332#17333 · In reply to: #17332

Hello Jessie,

Wednesday, July 20, 2005, 6:05:30 AM, you wrote:

> Private class support has been completed in the attached patch! Again, to
> reiterate from my last post, the attached patch is a CVS patch, as some
> requested me to do. I could not add the test files to the patch because
> "cvs add" failed with a "cvs add requires write access to the repository"
> error (any way to fix this?).

You can add the line yourself:
marcus@zaphod /usr/src/php5 $ cvs add 061.csv
cvs add: use 'cvs commit' to add this file permanently
marcus@zaphod /usr/src/php5 $ cat CVS/Entries
[...]
/061.csv/0/dummy timestamp//

> Also, import statements now include the class files, using a new .ini
> variable, "class_path". Files under the directories in the class_path have
> the namespace names as directories and the class names named exactly as the
> file that declares it (like Java), e.g. my_ns:class1 is declared in
> $class_path/my_ns/class1.php.

Please don't add new ini settings here, living with include_path should be
enough, wouldn't it?

> Again, the only missing feature I know of is "namespace imports". I've been
> thinking about it, and I think the best approach is actually very simple.
> Right now, when an undefined class is found, the __autoload function is
> called from zend_lookup_class to attempt to declare the class at that
> point. What I propose is to modify zend_lookup_class to do an additional
> lookup, either before/after the __autoload function, for namespace imported
> classes. Here's an example:

> <?php
> import namespace my_namespace1;
> // my_namespace1 is added to a runtime hashtable
> import namespace my_namespace2;
> // my_namespace2 is added to a runtime hashtable

> $a = new class1();
?>>

Why can't __autoload decide itself? I mean either it knows it received a
namespace class since the string contains a ':' or the function writer
has to find out himself.

> At compile-time, the "my_namespace1" and "my_namespace2" strings are saved
> in a runtime hashtable. At runtime, zend_lookup_class will be called on
> "class1", as usual. Before/after __autoload, this hashtable will be
> traversed for the file "class1.php". So in the above example, an attempt to
> include "$class_path/my_namespace1/class1.php" will be done. If that fails,
> then my_namespace2 is tried, and so forth. If one of these attempts
> succeed, then the import alias is also added to the import hashtable for
> the currently-executed file, as if the user had added "import
> my_namespace1:class1" to the script.

> (BTW, is there a way to construct an opcode at runtime and execute it
> immediately? If not, I'll have to duplicate the code I have for
> ZEND_IMPORT_CLASS in another function).

In that case you should provide a function apart the import opcode handler.
Since zend_vm_gen.h might create multiple handlers out of it this is anyway
perhaps a good idea. This function can be used of course from both handlers
and you other function.

> I think this approach is the easiest and most sensible for namespace import
> support. It is no more than a specialized "__autoload". If there are no
> objections, I'll start working on it next week. As always,
> comments/suggestions are most appreciated.


> Regards,

> Jessie Hernandez



-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #17348 — Jessie Hernandez — 2005-07-20T18:35:26+00:00

URL: https://externals.io/message/17332#17348 · In reply to: #17333

"Marcus Boerger" <mail@marcus-boerger.de> wrote in message
news:681697173.20050720083643@marcus-boerger.de...
> Please don't add new ini settings here, living with include_path should be
> enough, wouldn't it?
>

Do we want the import behavior to apply to the existing include path? To me,
it seems nice to have the include_path and class_path separate. The
class_path will only be used for classes, and include_path for everything
else (header/footer code, etc.). Of course, this is just my opinion. What
does everyone else think?


> Why can't __autoload decide itself? I mean either it knows it received a
> namespace class since the string contains a ':' or the function writer
> has to find out himself.
>

Well, when a full namespace import is done, the string will not contain a
':'. __autoload would only receive a class name, and there is no easy way
for __autoload to know which namespace contains that class. That's why a
separate mechanism is needed from __autoload, that will look into the
class_path directories (appending the directories for the namespace name)
for the class file, and if/when found, include that. This is one other
reason why a separate class_path variable would be useful: the include_path
might have several directories, and all these would need to be searched,
even though these directories might not have classes at all. In contrast,
the directories in class_path are specifically for class files, so the
searches are faster.


--
Jessie

---

## #17351 — Jessie Hernandez — 2005-07-21T02:44:27+00:00

URL: https://externals.io/message/17332#17351 · In reply to: #17333

Hello Marcus! Thanks for the cvs add "hack", worked like a charm! I'll post
an updated patch in a few days.


--
Jessie


Marcus Boerger wrote:

> Hello Jessie,
> 
> Wednesday, July 20, 2005, 6:05:30 AM, you wrote:
> 
> > […]
> 
> You can add the line yourself:
> marcus@zaphod /usr/src/php5 $ cvs add 061.csv
> cvs add: use 'cvs commit' to add this file permanently
> marcus@zaphod /usr/src/php5 $ cat CVS/Entries
> [...]
> /061.csv/0/dummy timestamp//
> 
> > […]
> 
> Please don't add new ini settings here, living with include_path should be
> enough, wouldn't it?
> 
> > […]
> 
> > […]
> 
> > […]
> ?>>
> 
> Why can't __autoload decide itself? I mean either it knows it received a
> namespace class since the string contains a ':' or the function writer
> has to find out himself.
> 
> > […]
> 
> > […]
> 
> In that case you should provide a function apart the import opcode
> handler. Since zend_vm_gen.h might create multiple handlers out of it this
> is anyway perhaps a good idea. This function can be used of course from
> both handlers and you other function.
> 
> > […]
> 
> 
> > […]
> 
> > […]

---

## #17353 — Marcus Boerger — 2005-07-21T10:00:06+00:00

URL: https://externals.io/message/17332#17353 · In reply to: #17348

Hello Jessie,

Wednesday, July 20, 2005, 8:35:26 PM, you wrote:

> "Marcus Boerger" <mail@marcus-boerger.de> wrote in message
> news:681697173.20050720083643@marcus-boerger.de...
> > […]

> Do we want the import behavior to apply to the existing include path? To me,
> it seems nice to have the include_path and class_path separate. The
> class_path will only be used for classes, and include_path for everything
> else (header/footer code, etc.). Of course, this is just my opinion. What
> does everyone else think?


> > […]

> Well, when a full namespace import is done, the string will not contain a
> ':'. __autoload would only receive a class name, and there is no easy way
> for __autoload to know which namespace contains that class. That's why a
> separate mechanism is needed from __autoload, that will look into the
> class_path directories (appending the directories for the namespace name)
> for the class file, and if/when found, include that. This is one other
> reason why a separate class_path variable would be useful: the include_path
> might have several directories, and all these would need to be searched,
> even though these directories might not have classes at all. In contrast,
> the directories in class_path are specifically for class files, so the
> searches are faster.


might, might, might only assumptions with the big drawback of adding another
ini setting. My assumption is that i only need one or two include/class
patchs and that they are of course the same since i want to keep my
application files together - for working maintanance for one reason.
Also if __autoload cannot easily get the requested namespace name than a
compilcated solution has to be worked out since otherwise you end up in
nightmare of naming conflicts - how should you know in a situation where
a classname exists in multiple namespaces from which directory to load?
By order of directory? In the end nothing here would really work around the
problem thus we need the full name.

Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #17354 — Weyert de Boer — 2005-07-21T10:36:39+00:00

URL: https://externals.io/message/17332#17354 · In reply to: #17353

Hello,

Well, I wouldn't use the include_path parameter of PHP for the new 
namespaces lookup code, neither __autoload(). I see it as a major 
language change -- the support of namespaces, where you should consider 
to make all need. I suppose you want to support namespace spread over 
multiple files, this shouldn't be a problem. I would only drop the 
support of one class spread over multiple files for only one namespace, 
nice time to raise a Fatal Error/compiler error.

You could support nameless namespaces (i.e. namespace {}) and for 
backward compatibility sake dump all "float" methods in this nameless 
namespace, won't cause problem. And all "new code" should just 
namespaces by default, if not it will be jumped into the nameless 
namespace. For example when you call a function like myNameRocks() it 
should just look for the function in the nameless namespace and go with 
it. Not existing? Bang! Function doesn't exist.

Enough dreaming for now, time to work again :-)

-- 
Yours,

Weyert de Boer (wdb@innerfuse.biz)
innerfuse*

http://www.innerfuse.biz/

---

## #17365 — Jessie Hernandez — 2005-07-21T18:06:49+00:00

URL: https://externals.io/message/17332#17365 · In reply to: #17353

Hello Marcus,

In my case at work, my include_path only has three directories: . (current
directory), the PEAR path, and the directory where my company's classes are
stored. In this case, the namespace import will only have to search in
three directories, which is not bad. The class_path would only save me one
directory lookup (.), so the class_path really is not needed here. Looking
again, the need for class_path really depends on whether many PHP users
have large include_paths or not. If the majority have small include_paths
(like in our cases), then I can just use include_path (my patch would be
simplified, also). Still, I'd like to gather more opinions from others.

Regarding __autoload, there is no way for __autoload to receive the full
class name without having to first scan the directories either at compile
or runtime, and of course, when I determine the full class name and path,
why call __autoload? I already know the path of the file I need to include,
so passing the class name to __autoload seems unnecessary. 

For the lookup, I was thinking of searching all the directories in the
class/include_path, even if I get a match in the first directory. In the
case where there are two identically-named classes in two namespaces that
have been imported, then I will generate an error saying that the class
requested is ambiguous. The way the user would disambiguate the class name
is by entering the full class name, e.g. my_ns:class1, for that particular
class. 


--
Jessie


Marcus Boerger wrote:

> might, might, might only assumptions with the big drawback of adding
> another ini setting. My assumption is that i only need one or two
> include/class patchs and that they are of course the same since i want to
> keep my application files together - for working maintanance for one
> reason. Also if __autoload cannot easily get the requested namespace name
> than a compilcated solution has to be worked out since otherwise you end
> up in nightmare of naming conflicts - how should you know in a situation
> where a classname exists in multiple namespaces from which directory to
> load? By order of directory? In the end nothing here would really work
> around the problem thus we need the full name.
> 
> Best regards,
>  Marcus                            mailto:mail@marcus-boerger.de

---

## #17367 — Weyert de Boer — 2005-07-21T18:26:03+00:00

URL: https://externals.io/message/17332#17367 · In reply to: #17365

My include path is huge... of course it includes the basic ones, but 
also my classes path /classes/System/* , /class/System/Exceptions/* etc. 
Beside of that why clutter the include_path with namespaces? In my 
opinion it's something different then the rest.

p.s. you will support nameless namespaces right :+

-- 
Yours,

Weyert de Boer (wdb@innerfuse.biz)
innerfuse*

http://www.innerfuse.biz/

---

## #17397 — Alex Kiesel — 2005-07-25T21:48:33+00:00

URL: https://externals.io/message/17332#17397 · In reply to: #17332

Hi Jessie,

first, while your patch applied cleanly (except zend_vm_opcodes.h, which
is generated) the build broke with:
bison -y -p zend -v -d /mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y -o Zend/zend_language_parser.c
conflicts:  5 shift/reduce
/mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y: expected 4 shift/reduce conflicts
*** Error code 1

I had to increase the expected shift/reduce conflict count to 5 to
continue the build, which then completed successfully.


> Also, import statements now include the class files, using a new .ini
> variable, "class_path". Files under the directories in the class_path have
> the namespace names as directories and the class names named exactly as the
> file that declares it (like Java), e.g. my_ns:class1 is declared in
> $class_path/my_ns/class1.php.

I don't like this idea; it restricts the developer to this Java-like
class / directory layout. It also restricts him to name his files after
the scheme you defined (which is <classname>.php) - many use other
schemes. Shouldn't PHP let you be free in this kind of decision? I think
yes, especially, as this could also be implemented with the __autoload
function in user-space.

> Again, the only missing feature I know of is "namespace imports". I've been
> thinking about it, and I think the best approach is actually very simple.

Here's another one: the script

<?php
  $foo= 'Foo:Bar';
  import $foo;
?>

gives me

alex@boost:~/cvs/php-namespaces# sapi/cli/php ~/tests/classes/dynamic_import.php 

Parse error: parse error, unexpected T_VARIABLE, expecting T_NAMESPACE_NAME or `T_NAMESPACE` in /mnt/home/alex/tests/classes/dynamic_import.php on line 3

(IIRC Stanislav Malyshev already mentioned this in the YANP-thread
already.)

Regards,
-Alex

---

## #17398 — Marcus Boerger — 2005-07-25T21:59:18+00:00

URL: https://externals.io/message/17332#17398 · In reply to: #17397

Hello Alex,

Monday, July 25, 2005, 11:48:33 PM, you wrote:

> Hi Jessie,

> first, while your patch applied cleanly (except zend_vm_opcodes.h, which
> is generated) the build broke with:
> bison -y -p zend -v -d
> /mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y -o
> Zend/zend_language_parser.c
> conflicts:  5 shift/reduce
> /mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y: expected 4 shift/reduce conflicts
> *** Error code 1

> I had to increase the expected shift/reduce conflict count to 5 to
> continue the build, which then completed successfully.

> 
> > […]

> I don't like this idea; it restricts the developer to this Java-like
> class / directory layout. It also restricts him to name his files after
> the scheme you defined (which is <classname>.php) - many use other
> schemes. Shouldn't PHP let you be free in this kind of decision? I think
> yes, especially, as this could also be implemented with the __autoload
> function in user-space.

You already have the ability to overload __autoload or provide several
userspace __autoload functions that would be called one after another
until the first succeeds. What else do you want? Besides the fact that
i am still convinced that we should find a way to pass the full namespaced
name to __autoload instead of just the classname. If you ask me not doing
so is simply an error.

> > […]

> Here's another one: the script

> <?php
>   $foo= 'Foo:Bar';
>   import $foo;
?>>

> gives me

> alex@boost:~/cvs/php-namespaces# sapi/cli/php ~/tests/classes/dynamic_import.php

> Parse error: parse error, unexpected T_VARIABLE, expecting
> T_NAMESPACE_NAME or `T_NAMESPACE` in
> /mnt/home/alex/tests/classes/dynamic_import.php on line 3

> (IIRC Stanislav Malyshev already mentioned this in the YANP-thread
> already.)

I don't see any reason to allow this. PHP is already far to dynamic (which
already prevents some speed improvements to the engine). Namespaces are a
means for working with several frameworks/libraries at a time and for
spreading/controlling responsibilities. In all those cases you definitively
won't need the above and its presents would circumvent what we'd achieve
here.

Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #17399 — Jessie Hernandez — 2005-07-26T00:02:56+00:00

URL: https://externals.io/message/17332#17399 · In reply to: #17397

Alex Kiesel wrote:

> Hi Jessie,
> 
> first, while your patch applied cleanly (except zend_vm_opcodes.h, which
> is generated) the build broke with:
> bison -y -p zend -v -d
> /mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y -o
> Zend/zend_language_parser.c
> conflicts:  5 shift/reduce
> /mnt/home/alex/cvs/php-namespaces/Zend/zend_language_parser.y: expected 4
> shift/reduce conflicts *** Error code 1
> 
> I had to increase the expected shift/reduce conflict count to 5 to
> continue the build, which then completed successfully.
> 

I am no expert in bison or yacc, so could someone look at the patch and tell
me what, if anything, is wrong, and how to fix it?


> I don't like this idea; it restricts the developer to this Java-like
> class / directory layout. It also restricts him to name his files after
> the scheme you defined (which is <classname>.php) - many use other
> schemes. Shouldn't PHP let you be free in this kind of decision? I think
> yes, especially, as this could also be implemented with the __autoload
> function in user-space.
> 

The scheme is needed in order to locate class files for the classes that
have been imported in a full namespace import. With no convention, we're
forced to call __autoload, and since the only thing that will be passed is
the class name, __autoload will have no way of knowing to what namespace
that class belongs to. With the convention, each imported namespace's
directory can be checked to see which one contains the class file.


> Here's another one: the script
> 
> <?php
>   $foo= 'Foo:Bar';
>   import $foo;
> ?>
> 
> gives me
> 
> alex@boost:~/cvs/php-namespaces# sapi/cli/php
> ~/tests/classes/dynamic_import.php
> 
> Parse error: parse error, unexpected T_VARIABLE, expecting
> T_NAMESPACE_NAME or `T_NAMESPACE` in
> /mnt/home/alex/tests/classes/dynamic_import.php on line 3
> 
> (IIRC Stanislav Malyshev already mentioned this in the YANP-thread
> already.)
> 

What Stanislav and I were discussing was not this, it was the following
(variable class names), which is fully supported in the patch:

<?php
import Foo:Bar;
$name = 'Bar';
$obj = new $name();
?>


Anyways, thanks for taking the time to try out the patch! Let me know if you
have any other ideas/suggestions. 

--
Jessie

---

## #17400 — Jessie Hernandez — 2005-07-26T03:24:02+00:00

URL: https://externals.io/message/17332#17400 · In reply to: #17398

Marcus Boerger wrote:

> 
> You already have the ability to overload __autoload or provide several
> userspace __autoload functions that would be called one after another
> until the first succeeds. What else do you want? Besides the fact that
> i am still convinced that we should find a way to pass the full namespaced
> name to __autoload instead of just the classname. If you ask me not doing
> so is simply an error.
> 

I still think that the namespace importing logic/file-naming convention is
the cleanest, but if __autoload is to be used, then I currently see three
approaches to this:

1) Search in each directory in the class_path (or include_path) for
"namespace-name/class-name.php". When the first file is found, then the
full class name will be generated from that and passed on to __autoload,
e.g. if you import the my_ns namespace and use class1, then
my_ns/class1.php will be searched in the path and then __autoload will be
called with "my_ns:class1".

Requirements
------------
- Namespace/class naming convention

Pros
----
- Full class name is passed to __autoload

Cons
----
- Performance loss (when the directories are searched, the path to the class
file is already known before __autoload is called, so generating the full
class name from the path, calling __autoload, only to then str_replace
colons with slashes and including that seems unnecessary).
- When a class name exists in more than one imported namespace, the first
one found will be passed to __autoload (no way to disambiguate).

2) Like (1), but search all the directories and pass an extra argument (or
pass an array or object as the first argument) to __autoload indicating the
directories where the class name was found. The first argument would be the
class name, the second argument (or an additional key in the array) would
contain the paths (or namespace names, whichever). The user would be
responsible for disambiguation in case a class exists in multiple imported
namespaces.

Requirements
------------ 
- Namespace/class naming convention

Pros
----
- No ambiguity
- The include behavior is handled completely by the user

Cons
----
- In the majority of cases, a class name will not appear in more than one
namespace, so there will be a performance loss by having to search all the
directories in the class/include_path, even though there was a match on the
first directory.

3) Simply pass an extra argument (or pass an array or object as the first
argument) to __autoload containing the names of the imported namespaces of
the calling file. __autoload can then use this array against the class name
and perform its own lookup.

Requirements
------------
- None

Pros
----
- A namespace/class naming convention is not forced
- The include behavior/lookup is handled completely by the user
- No performance loss (all that's passed to __autoload is the class name and
an array of imported namespaces, and this is done immediately).

Cons
----
- IMHO, I think most users would maintain a naming convention similar to
Java's, so the user would have to add code for something which the language
should handle for them. This can be minimized, though, if a function is
added to handle this common behavior. The function can be called by the
user in __autoload and will look something like the following (of course,
the code would be in C):

<?php
function namespace_include($className, $importNamespaces)
{
    $paths = explode( PATH_SEPARATOR, `get_include_path()` );
 
    foreach( $paths as $path )
    {
        foreach( $importNamespaces as $ns )
        {
            $fullPath = $path . `DIRECTORY_SEPARATOR` . str_replace( ':',
DIRECTORY_SEPARATOR, $ns ) . `DIRECTORY_SEPARATOR` . $className . '.php';
 
            if( file_exists( $fullPath ) )
            {
                require_once( $fullPath );
                return true;
            }
        }
    }

    return false;
}
?>


I still think the namespace import behavior should be separate from the
__autoload function. Of course, this is just me. What does everyone else
think? I'd like to gather opinions on which is preferred. I will also like
to know if a separate class_path is preferred (as I have in my last patch)
or if just leaving include_path is what most prefer.


--
Jessie

---

## #17402 — Marcus Boerger — 2005-07-26T07:26:03+00:00

URL: https://externals.io/message/17332#17402 · In reply to: #17399

Hello Jessie,

  i am quite sure it tells you that you have a conflict with the ternary
operator. Look up the archives on the issue. There should also be an
example on the matter.

marcus

Tuesday, July 26, 2005, 2:02:56 AM, you wrote:

> Alex Kiesel wrote:

> > […]

> I am no expert in bison or yacc, so could someone look at the patch and tell
> me what, if anything, is wrong, and how to fix it?


> > […]

> The scheme is needed in order to locate class files for the classes that
> have been imported in a full namespace import. With no convention, we're
> forced to call __autoload, and since the only thing that will be passed is
> the class name, __autoload will have no way of knowing to what namespace
> that class belongs to. With the convention, each imported namespace's
> directory can be checked to see which one contains the class file.


> > […]

> What Stanislav and I were discussing was not this, it was the following
> (variable class names), which is fully supported in the patch:

> <?php
> import Foo:Bar;
> $name = 'Bar';
> $obj = new $name();
?>>


> Anyways, thanks for taking the time to try out the patch! Let me know if you
> have any other ideas/suggestions. 

> --
> Jessie




-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #17404 — Weyert de Boer — 2005-07-26T08:04:28+00:00

URL: https://externals.io/message/17332#17404 · In reply to: #17402

Hello,

How can I use the namespaces support, in such way that I can use with my 
coding guideline?

interfaces -> interface.NAME.inc.php
classes -> class.NAME.inc.php

It doesn't seem it's possible now, because it's hard coded against 
NAME.php. Oh well, I might will have
a look at it, and try to come with some workable, with support for 
nameless namespaces, etc.


-- 
Yours,

Weyert de Boer (wdb@innerfuse.biz)
innerfuse*

http://www.innerfuse.biz/

---

## #17405 — Marcus Boerger — 2005-07-26T08:10:45+00:00

URL: https://externals.io/message/17332#17405 · In reply to: #17400

Hello Jessie,

Tuesday, July 26, 2005, 5:24:02 AM, you wrote:

> Marcus Boerger wrote:

> > […]

> I still think that the namespace importing logic/file-naming convention is
> the cleanest, but if __autoload is to be used, then I currently see three
> approaches to this:

> 1) Search in each directory in the class_path (or include_path) for
> "namespace-name/class-name.php". When the first file is found, then the
> full class name will be generated from that and passed on to __autoload,
> e.g. if you import the my_ns namespace and use class1, then
> my_ns/class1.php will be searched in the path and then __autoload will be
> called with "my_ns:class1".

> Requirements
> ------------
> - Namespace/class naming convention

> Pros
> ----
> - Full class name is passed to __autoload

> Cons
> ----
> - Performance loss (when the directories are searched, the path to the class
> file is already known before __autoload is called, so generating the full
> class name from the path, calling __autoload, only to then str_replace
> colons with slashes and including that seems unnecessary).
> - When a class name exists in more than one imported namespace, the first
> one found will be passed to __autoload (no way to disambiguate).

> 2) Like (1), but search all the directories and pass an extra argument (or
> pass an array or object as the first argument) to __autoload indicating the
> directories where the class name was found. The first argument would be the
> class name, the second argument (or an additional key in the array) would
> contain the paths (or namespace names, whichever). The user would be
> responsible for disambiguation in case a class exists in multiple imported
> namespaces.

> Requirements
> ------------ 
> - Namespace/class naming convention

> Pros
> ----
> - No ambiguity
> - The include behavior is handled completely by the user

> Cons
> ----
> - In the majority of cases, a class name will not appear in more than one
> namespace, so there will be a performance loss by having to search all the
> directories in the class/include_path, even though there was a match on the
> first directory.

> 3) Simply pass an extra argument (or pass an array or object as the first
> argument) to __autoload containing the names of the imported namespaces of
> the calling file. __autoload can then use this array against the class name
> and perform its own lookup.

> Requirements
> ------------
> - None

> Pros
> ----
> - A namespace/class naming convention is not forced
> - The include behavior/lookup is handled completely by the user
> - No performance loss (all that's passed to __autoload is the class name and
> an array of imported namespaces, and this is done immediately).

> Cons
> ----
> - IMHO, I think most users would maintain a naming convention similar to
> Java's, so the user would have to add code for something which the language
> should handle for them. This can be minimized, though, if a function is
> added to handle this common behavior. The function can be called by the
> user in __autoload and will look something like the following (of course,
> the code would be in C):

> <?php
> function namespace_include($className, $importNamespaces)
> {
>     $paths = explode( PATH_SEPARATOR, `get_include_path()` );
 
>     foreach( $paths as $path )
>     {
>         foreach( $importNamespaces as $ns )
>         {
>             $fullPath = $path . `DIRECTORY_SEPARATOR` . str_replace( ':',
> DIRECTORY_SEPARATOR, $ns ) . `DIRECTORY_SEPARATOR` . $className . '.php';
 
>             if( file_exists( $fullPath ) )
>             {
>                 require_once( $fullPath );
>                 return true;
>             }
>         }
>     }

>     return false;
> }
?>>


> I still think the namespace import behavior should be separate from the
> __autoload function. Of course, this is just me. What does everyone else
> think? I'd like to gather opinions on which is preferred. I will also like
> to know if a separate class_path is preferred (as I have in my last patch)
> or if just leaving include_path is what most prefer.

None of the above makes any sense. Look __autoload() is just bein called at
any place where a class is missing. So looking for the file first and then
loading __autoload(I) makes no sense whatsoever. IMO what we need here is a
default implementation for import behavior accomplished by __autoload(). So
for example "import ns:cls;" leads to "__autoload('ns:cls')". Here the SPL
default implementation would relpace all ':' with the directory divider '/'
or '\', append '.inc' or '.php' or '.inc.php' and append the result to all
directories in the include_path to look for the file. If were are to support
import with '*' the the autoload implementation would need to take care of
this and load all matching files. A user land implementation can easily
achieve that by using SPLs (Recursive)DirectoryIterator and FilterIterator.

Best regards,
 Marcus

---

## #17406 — Marcus Boerger — 2005-07-26T08:11:37+00:00

URL: https://externals.io/message/17332#17406 · In reply to: #17404

Hello Weyert,

Tuesday, July 26, 2005, 10:04:28 AM, you wrote:

> Hello,

> How can I use the namespaces support, in such way that I can use with my 
> coding guideline?

> interfaces -> interface.NAME.inc.php
> classes -> class.NAME.inc.php

> It doesn't seem it's possible now, because it's hard coded against 
> NAME.php. Oh well, I might will have
> a look at it, and try to come with some workable, with support for 
> nameless namespaces, etc.


I have the same probelm and don't see any reason in a hard coded
naming scheme unless be it a default fallback. Look at my other
reply.

Best regards,
 Marcus

---

## #17407 — Weyert de Boer — 2005-07-26T09:05:37+00:00

URL: https://externals.io/message/17332#17407 · In reply to: #17406

Hello,

May I make some sort of suggestion, without having a closer look at the 
internal working of PHP, the below is jsut one big day dream for me.

My idea is to wrap namespaces by default, for example when you aren't 
using any namespace-keywords into your code, the parser will add these 
accordingly to a nameless namespace (i.e.: namespace { }) this means 
that you can access a class just as normal via MyClassName() etc. But 
when you are using namespaces i..e

namespace innerfuse {

    namespace RepositoryEngine {
      
       final interface IRepistory {
          blabla
       }

       class Repository implements IRepository {
          // blabla
       }
    }
}

You can now access those stuff via innerfuse.*; 
innerfuse.RepositoryEngine.* or the exact "path" to the class or 
interface innerfuse.RepositoryEngine.*. Now probably will ask but how do 
you want to lookup the class files? Well, I think this can be done 
through by defining a classPath. I won't mind putting my files which use 
namespaces in a specified directory, as long this can be altered i.e. 
set_classes_path( 'blabla' ) or through comments magic. 

Now because each PHP file needs to be parsed anyway before it can be 
used, i.e. transformation to opcode. You can of course just get all the 
php files, from the classes path recursively. Keep a list of all 
namespaces found and classes which belong to these in a hierarchy, for 
example you could give each class a unique number/name  internally. 
After all the available classes and namespaces are available, or when a 
namespace confliction is encountered, a fatal error should be raised. 
You now got a nice tree of available classes and to which namespaces it 
belongs, with a reference to the file where the class definition is 
available. Now you won't need this file anymore, though. It should now 
be possible to convert it into the opcode.

Anyways some sort of caching is always nice, for example a hidden file 
myphpfile.php.cache which includes a cached version of the php file in 
opcode, which same some parsing time :+

Still thinking in progress, lunch time now ;-)

-- 
Yours,

Weyert de Boer (wdb@innerfuse.biz)
innerfuse*

http://www.innerfuse.biz/

---

## #17408 — Weyert de Boer — 2005-07-26T12:11:42+00:00

URL: https://externals.io/message/17332#17408 · In reply to: #17407

I will work on a little proof of concept, thingy to see I can make this 
work.
Hopefully I have something nice to show in a while, hope guys won't have 
serious
problems when I use the current lexer etc.?

-- 
Yours,

Weyert de Boer (wdb@innerfuse.biz)
innerfuse*

http://www.innerfuse.biz/

---

## #17409 — Jessie Hernandez — 2005-07-26T15:50:35+00:00

URL: https://externals.io/message/17332#17409 · In reply to: #17405

Hi Marcus,

"Marcus Boerger" <mail@marcus-boerger.de> wrote in message
news:1374121835.20050726101045@marcus-boerger.de...
>
> > […]
first
> > […]
of
> > […]
name
> > […]
>
> None of the above makes any sense. Look __autoload() is just bein called
at
> any place where a class is missing. So looking for the file first and then
> loading __autoload(I) makes no sense whatsoever. IMO what we need here is
a
> default implementation for import behavior accomplished by __autoload().
So
> for example "import ns:cls;" leads to "__autoload('ns:cls')". Here the SPL
> default implementation would relpace all ':' with the directory divider
'/'
> or '\', append '.inc' or '.php' or '.inc.php' and append the result to all
> directories in the include_path to look for the file. If were are to
support
> import with '*' the the autoload implementation would need to take care of
> this and load all matching files. A user land implementation can easily
> achieve that by using SPLs (Recursive)DirectoryIterator and
FilterIterator.
>

Regarding a fully-specified class import, such as ns:cls, if I simply remove
my include logic, then __autoload('ns:cls') would automatically be called.
There are no issues with this type of import.

Now, namespace imports (wildcard imports) are a different story. Maybe I did
not make my explanations clear enough, but you basically agreed to point #3
in my previous email. Now, the class name cannot simply be passed to
__autoload, because there is no way for __autoload to know to which
namespace the class belongs to, and you only want __autoload to include the
classes belonging to the namespaces that have been imported. That is why the
list of imported namespaces for the __calling__ file must be accessible
somehow to the __autoload function, either as an additional argument or by
having the first argument be an array/object.

So the namespace imports will work like how you described simple imports,
but with a slight twist. To quote you:

"Simple" Imports
----------------
> So for example "import ns:cls;" leads to "__autoload('ns:cls')". Here the
SPL
> default implementation would relpace all ':' with the directory divider
'/'
> or '\', append '.inc' or '.php' or '.inc.php' and append the result to all
> directories in the include_path to look for the file.


By slightly modifying your sentence, we implement namespace imports:

Namespace Imports
-----------------
Here the SPL default implementation would, in a loop, prefix the class name
with each imported namespace, replace all ':' with the directory divider '/'
or '\', append '.inc' or '.php' or '.inc.php' and append the result to all
directories in the include_path to look for the file.


For example, here is how the userland __autoload might look (notice that
this code is exactly what I provided in the last post). In this example, the
user has the directory structure as "namespace-name/class-name.php".

<?php
function __autoload($className, $importNamespaces)
{
    $paths = explode( PATH_SEPARATOR, `get_include_path()` );

    foreach( $paths as $path )
    {
        foreach( $importNamespaces as $ns )
        {
            $fullPath = $path . `DIRECTORY_SEPARATOR` . str_replace( ':',
DIRECTORY_SEPARATOR, $ns ) . `DIRECTORY_SEPARATOR` . $className . '.php';

            if( file_exists( $fullPath ) )
            {
                require_once( $fullPath );
                break;
            }
        }
    }
}
?>


Let me know if the above make sense or if you see any problems with this
approach.

--
Jessie

---

## #17411 — Marcus Boerger — 2005-07-26T18:38:58+00:00

URL: https://externals.io/message/17332#17411 · In reply to: #17409

Hello Jessie,

Tuesday, July 26, 2005, 5:50:35 PM, you wrote:

> Hi Marcus,

> "Marcus Boerger" <mail@marcus-boerger.de> wrote in message
> news:1374121835.20050726101045@marcus-boerger.de...
> > […]
> first
> > […]
> of
> > […]
> name
> > […]
> at
> > […]
> a
> > […]
> So
> > […]
> '/'
> > […]
> support
> > […]
> FilterIterator.
> > […]

> Regarding a fully-specified class import, such as ns:cls, if I simply remove
> my include logic, then __autoload('ns:cls') would automatically be called.
> There are no issues with this type of import.

> Now, namespace imports (wildcard imports) are a different story. Maybe I did
> not make my explanations clear enough, but you basically agreed to point #3
> in my previous email. Now, the class name cannot simply be passed to
> __autoload, because there is no way for __autoload to know to which
> namespace the class belongs to, and you only want __autoload to include the
> classes belonging to the namespaces that have been imported. That is why the
> list of imported namespaces for the __calling__ file must be accessible
> somehow to the __autoload function, either as an additional argument or by
> having the first argument be an array/object.

> So the namespace imports will work like how you described simple imports,
> but with a slight twist. To quote you:

> "Simple" Imports
> ----------------
> > […]
> SPL
> > […]
> '/'
> > […]


> By slightly modifying your sentence, we implement namespace imports:

> Namespace Imports
> -----------------
> Here the SPL default implementation would, in a loop, prefix the class name
> with each imported namespace, replace all ':' with the directory divider '/'
> or '\', append '.inc' or '.php' or '.inc.php' and append the result to all
> directories in the include_path to look for the file.


> For example, here is how the userland __autoload might look (notice that
> this code is exactly what I provided in the last post). In this example, the
> user has the directory structure as "namespace-name/class-name.php".

> <?php
> function __autoload($className, $importNamespaces)
> {
>     $paths = explode( PATH_SEPARATOR, `get_include_path()` );

>     foreach( $paths as $path )
>     {
>         foreach( $importNamespaces as $ns )
>         {
>             $fullPath = $path . `DIRECTORY_SEPARATOR` . str_replace( ':',
> DIRECTORY_SEPARATOR, $ns ) . `DIRECTORY_SEPARATOR` . $className . '.php';

>             if( file_exists( $fullPath ) )
>             {
>                 require_once( $fullPath );
>                 break;
>             }
>         }
>     }
> }
?>>


> Let me know if the above make sense or if you see any problems with this
> approach.

On a first sight i only see that 'break' should be 'return'.

Best regards,
 Marcus

---

## #17410 — Jessie Hernandez — 2005-07-26T18:59:55+00:00

URL: https://externals.io/message/17332#17410 · In reply to: #17406

"Marcus Boerger" <mail@marcus-boerger.de> wrote in message
news:03165207.20050726101137@marcus-boerger.de...
> Hello Weyert,
>
> Tuesday, July 26, 2005, 10:04:28 AM, you wrote:
>
> > […]
>
> > […]
>
> > […]
>
> > […]
>
>
> I have the same probelm and don't see any reason in a hard coded
> naming scheme unless be it a default fallback. Look at my other
> reply.
>
> Best regards,
>  Marcus


Based on what I see above, there appears to be several users which do not
follow the PEAR file naming convention for their own classes. In order to
have flexibility in this area, we are forced to let __autoload handle the
include logic. I will post a patch in a few days with this change (as a
result, my patch will be much smaller). I will also add the namespace import
logic as described in my other post. Basically, the user will be responsible
for all importing behavior in __autoload.

In order for namespace imports to work correctly, an additional parameter
needs to be passed to __autoload that will contain an array of imported
namespaces from the file that triggered the __autoload call. Does anyone see
any problems with this additional argument? This argument would only be
passed if the class name does not contain a colon (meaning that the class
could *possibly* reside under one of these namespaces).

--
Jessie

---

## #17412 — Marcus Boerger — 2005-07-26T19:08:44+00:00

URL: https://externals.io/message/17332#17412 · In reply to: #17410

Hello Jessie,

Tuesday, July 26, 2005, 8:59:55 PM, you wrote:

> "Marcus Boerger" <mail@marcus-boerger.de> wrote in message
> news:03165207.20050726101137@marcus-boerger.de...
> > […]


> Based on what I see above, there appears to be several users which do not
> follow the PEAR file naming convention for their own classes. In order to
> have flexibility in this area, we are forced to let __autoload handle the
> include logic. I will post a patch in a few days with this change (as a
> result, my patch will be much smaller). I will also add the namespace import
> logic as described in my other post. Basically, the user will be responsible
> for all importing behavior in __autoload.

> In order for namespace imports to work correctly, an additional parameter
> needs to be passed to __autoload that will contain an array of imported
> namespaces from the file that triggered the __autoload call. Does anyone see
> any problems with this additional argument? This argument would only be
> passed if the class name does not contain a colon (meaning that the class
> could *possibly* reside under one of these namespaces).

Yes you cannot simply change signatures of internal functions. And also you
don't need to since you can easily provide a helper function(s) or you can
give direct access to the list itself.


Best regards,
 Marcus

---

## #17413 — Jessie Hernandez — 2005-07-26T19:13:06+00:00

URL: https://externals.io/message/17332#17413 · In reply to: #17411

Yes, you are correct, 'break' should be 'return'.


--
Jessie


"Marcus Boerger" <helly@php.net> wrote in message
news:1531018265.20050726203858@marcus-boerger.de...
>
> On a first sight i only see that 'break' should be 'return'.
>
> Best regards,
>  Marcus

---

## #17414 — Jessie Hernandez — 2005-07-26T19:28:14+00:00

URL: https://externals.io/message/17332#17414 · In reply to: #17407

Hello Weyert,

"Weyert de Boer" <wdb@innerfuse.biz> wrote in message
news:42E5FCE1.10706@innerfuse.biz...
> Hello,
>
> May I make some sort of suggestion, without having a closer look at the
> internal working of PHP, the below is jsut one big day dream for me.
>
> My idea is to wrap namespaces by default, for example when you aren't
> using any namespace-keywords into your code, the parser will add these
> accordingly to a nameless namespace (i.e.: namespace { }) this means
> that you can access a class just as normal via MyClassName() etc.

This already works in the current patch. If the class does not reside in a
namespace, then it belongs to the "global" namespace and it is left
unprefixed in the class_table. What you describe as "nameless namespace" is
what the global namespace is. Your syntax for "nameless namespaces" also
means something different in C++, which are "anonymous namespaces".
Anonymous namespaces can be used to declare classes in one file for use only
within the file in which it was declared (if the class is referenced from
another file, an error will be generated). I can easily add this feature in
my implementation. Does anyone find this feature useful?

> But when you are using namespaces i..e
>
> namespace innerfuse {
>
>     namespace RepositoryEngine {
>
>        final interface IRepistory {
>           blabla
>        }
>
>        class Repository implements IRepository {
>           // blabla
>        }
>     }
> }
>
> You can now access those stuff via innerfuse.*;
> innerfuse.RepositoryEngine.* or the exact "path" to the class or
> interface innerfuse.RepositoryEngine.*. Now probably will ask but how do
> you want to lookup the class files? Well, I think this can be done
> through by defining a classPath. I won't mind putting my files which use
> namespaces in a specified directory, as long this can be altered i.e.
> set_classes_path( 'blabla' ) or through comments magic.
>

Since __autoload will now be used, the class_path .ini variable seems
unnecessary.

> Now because each PHP file needs to be parsed anyway before it can be
> used, i.e. transformation to opcode. You can of course just get all the
> php files, from the classes path recursively. Keep a list of all
> namespaces found and classes which belong to these in a hierarchy, for
> example you could give each class a unique number/name  internally.
> After all the available classes and namespaces are available, or when a
> namespace confliction is encountered, a fatal error should be raised.
> You now got a nice tree of available classes and to which namespaces it
> belongs, with a reference to the file where the class definition is
> available. Now you won't need this file anymore, though. It should now
> be possible to convert it into the opcode.
>

Recursively reading/parsing each file under the class_path would be VERY
slow to say the least. Caching would be an absolute requirement. Regarding
this...

> Anyways some sort of caching is always nice, for example a hidden file
> myphpfile.php.cache which includes a cached version of the php file in
> opcode, which same some parsing time :+
>

Let's say all the classes have been searched and cached in the .cache file,
and that later I add a new class to the class_path and create a new script
that uses this new class. How will I know that a new file has been added to
a directory under the class_path? I would have to recursively go through the
directories again to see if the new class is defined there. Also, if I
change the name of a class in a file that has already been cached in the
.cache file, I will not be notified of this change either.

I also see locking issues with this approach. If multiple requests are being
performed and the .cache file does not exist yet, the other requests somehow
have to be notified to wait until the first request goes through all of the
files in the class_path and creates the .cache file. This is another big
performance issue.


--
Jessie

---

## #17416 — Alex Kiesel — 2005-07-26T21:14:27+00:00

URL: https://externals.io/message/17332#17416 · In reply to: #17398

> > […]
> 
> You already have the ability to overload __autoload or provide several
> userspace __autoload functions that would be called one after another
> until the first succeeds. What else do you want? Besides the fact that
> i am still convinced that we should find a way to pass the full namespaced
> name to __autoload instead of just the classname. If you ask me not doing
> so is simply an error.

Yes, I was saying to use __autoload instead of the proposed import
magic.

> > […]
> 
> > […]
> ?>>
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> 
> I don't see any reason to allow this. PHP is already far to dynamic (which
> already prevents some speed improvements to the engine). Namespaces are a
> means for working with several frameworks/libraries at a time and for
> spreading/controlling responsibilities. In all those cases you definitively
> won't need the above and its presents would circumvent what we'd achieve
> here.

import $this is just something I'd expect PHP to be able to deal with -
but I could live without it.

Btw, if you're saying "Namespaces are for spreading/controlling
responsibilities", do you mean something like the package access level
for methods and member variables Java has? Is anyone thinking of
introducing this?

-Alex

---

Next page: https://externals.io/message/17332.md?page=2
