# PHP 5.3 bug or changed feature??

- Thread: https://externals.io/message/33858
- Original archive: https://news-web.php.net/php.internals/33858
- Started by Frank M. Kromann on 2007-12-07T22:09:58+00:00
- Messages: 34
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/33858.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

---

## #33858 — Frank M. Kromann — 2007-12-07T22:09:58+00:00

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

Hello Everyon,

Casting a SimpleXML object to an array gives different results in PHP
5.2.5 and PHP 5.3-dev.

Source:

$xml = simplexml_load_file("sample.xml");

foreach($xml->column as $column) {
    var_dump($column);
    var_dump((array)$column);
}

sample.xml

?xml version="1.0"?>
<cpdata>
    <column name="ENTERTAINMENT">
        <module>cv</module>
        <module>entsimp</module>
    </column>
    <column name="SEAT CONTROL">
        <module>pp</module>
        <module>sc</module>
    </column>
</cpdata>

PHP 5.2 output:
object(SimpleXMLElement)#4 (2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(13) "ENTERTAINMENT"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "cv"
    [1]=>
    string(7) "entsimp"
  }
}
array(2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(13) "ENTERTAINMENT"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "cv"
    [1]=>
    string(7) "entsimp"
  }
}
object(SimpleXMLElement)#5 (2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(12) "SEAT CONTROL"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "pp"
    [1]=>
    string(2) "sc"
  }
}
array(2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(12) "SEAT CONTROL"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "pp"
    [1]=>
    string(2) "sc"
  }
}

PHP 5.3 output:

object(SimpleXMLElement)#4 (2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(13) "ENTERTAINMENT"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "cv"
    [1]=>
    string(7) "entsimp"
  }
}
array(1) {
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "cv"
    [1]=>
    string(7) "entsimp"
  }
}
object(SimpleXMLElement)#5 (2) {
  ["@attributes"]=>
  array(1) {
    ["name"]=>
    string(12) "SEAT CONTROL"
  }
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "pp"
    [1]=>
    string(2) "sc"
  }
}
array(1) {
  ["module"]=>
  array(2) {
    [0]=>
    string(2) "pp"
    [1]=>
    string(2) "sc"
  }
}

Not that the attributes are gone when SimpleXML objects are converted in
PHP 5.3. Is this a bug or a feature change?

- Frank

---

## #33870 — Marco Kaiser — 2007-12-08T20:15:24+00:00

URL: https://externals.io/message/33858#33870 · In reply to: #33858

Hi Frank,

please open a bugreport about this issue. This would start the internal
process of verifying this.

-- Marco



> Hello Everyon,
>
> Casting a SimpleXML object to an array gives different results in PHP
> 5.2.5 and PHP 5.3-dev.
>
> Source:
>
> $xml = simplexml_load_file("sample.xml");
>
> foreach($xml->column as $column) {
>    var_dump($column);
>    var_dump((array)$column);
> }
>
> sample.xml
>
> ?xml version="1.0"?>
> <cpdata>
>    <column name="ENTERTAINMENT">
>        <module>cv</module>
>        <module>entsimp</module>
>    </column>
>    <column name="SEAT CONTROL">
>        <module>pp</module>
>        <module>sc</module>
>    </column>
> </cpdata>
>
> PHP 5.2 output:
> object(SimpleXMLElement)#4 (2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(13) "ENTERTAINMENT"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "cv"
>    [1]=>
>    string(7) "entsimp"
>  }
> }
> array(2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(13) "ENTERTAINMENT"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "cv"
>    [1]=>
>    string(7) "entsimp"
>  }
> }
> object(SimpleXMLElement)#5 (2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(12) "SEAT CONTROL"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "pp"
>    [1]=>
>    string(2) "sc"
>  }
> }
> array(2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(12) "SEAT CONTROL"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "pp"
>    [1]=>
>    string(2) "sc"
>  }
> }
>
> PHP 5.3 output:
>
> object(SimpleXMLElement)#4 (2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(13) "ENTERTAINMENT"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "cv"
>    [1]=>
>    string(7) "entsimp"
>  }
> }
> array(1) {
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "cv"
>    [1]=>
>    string(7) "entsimp"
>  }
> }
> object(SimpleXMLElement)#5 (2) {
>  ["@attributes"]=>
>  array(1) {
>    ["name"]=>
>    string(12) "SEAT CONTROL"
>  }
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "pp"
>    [1]=>
>    string(2) "sc"
>  }
> }
> array(1) {
>  ["module"]=>
>  array(2) {
>    [0]=>
>    string(2) "pp"
>    [1]=>
>    string(2) "sc"
>  }
> }
>
> Not that the attributes are gone when SimpleXML objects are converted in
> PHP 5.3. Is this a bug or a feature change?
>
> - Frank
>
> --
> 
> 
>
>


-- 
Marco Kaiser

---

## #33882 — Rob Richards — 2007-12-09T12:22:09+00:00

URL: https://externals.io/message/33858#33882 · In reply to: #33858

Hi Frank,

Frank M. Kromann wrote:
> Hello Everyon,
>
> Casting a SimpleXML object to an array gives different results in PHP
> 5.2.5 and PHP 5.3-dev.
>   
This is due to the implementation of the get_debug_info handler merged 
from HEAD.
The same result happens when calling get_object_vars on a 
SimpleXMLElement object.

Marcus, was it intended to only include @attributes with print_r/var_dump?

Rob
> Source:
>
> $xml = simplexml_load_file("sample.xml");
>
> foreach($xml->column as $column) {
>     var_dump($column);
>     var_dump((array)$column);
> }
>
> sample.xml
>
> ?xml version="1.0"?>
> <cpdata>
>     <column name="ENTERTAINMENT">
>         <module>cv</module>
>         <module>entsimp</module>
>     </column>
>     <column name="SEAT CONTROL">
>         <module>pp</module>
>         <module>sc</module>
>     </column>
> </cpdata>
>
> PHP 5.2 output:
> object(SimpleXMLElement)#4 (2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(13) "ENTERTAINMENT"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "cv"
>     [1]=>
>     string(7) "entsimp"
>   }
> }
> array(2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(13) "ENTERTAINMENT"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "cv"
>     [1]=>
>     string(7) "entsimp"
>   }
> }
> object(SimpleXMLElement)#5 (2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(12) "SEAT CONTROL"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "pp"
>     [1]=>
>     string(2) "sc"
>   }
> }
> array(2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(12) "SEAT CONTROL"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "pp"
>     [1]=>
>     string(2) "sc"
>   }
> }
>
> PHP 5.3 output:
>
> object(SimpleXMLElement)#4 (2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(13) "ENTERTAINMENT"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "cv"
>     [1]=>
>     string(7) "entsimp"
>   }
> }
> array(1) {
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "cv"
>     [1]=>
>     string(7) "entsimp"
>   }
> }
> object(SimpleXMLElement)#5 (2) {
>   ["@attributes"]=>
>   array(1) {
>     ["name"]=>
>     string(12) "SEAT CONTROL"
>   }
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "pp"
>     [1]=>
>     string(2) "sc"
>   }
> }
> array(1) {
>   ["module"]=>
>   array(2) {
>     [0]=>
>     string(2) "pp"
>     [1]=>
>     string(2) "sc"
>   }
> }
>
> Not that the attributes are gone when SimpleXML objects are converted in
> PHP 5.3. Is this a bug or a feature change?
>
> - Frank

---

## #33883 — Marco Kaiser — 2007-12-09T13:51:58+00:00

URL: https://externals.io/message/33858#33883 · In reply to: #33882

This happens with many more functions. So i can verify this bug.

php -r "echo md5(serialize(simplexml_load_file('example.xml'))) . `PHP_EOL` .
 `phpversion()` . PHP_EOL;"

Output PHP 5.2.5:
a6d7776fcb0e9c085b0d5972df792dac
5.2.5

Output PHP 5.3.0-dev (latest snap)
3e442cb7c8507c8941011735bb46e6de
5.3.0-dev

-- Marco



> Hi Frank,
>
> Frank M. Kromann wrote:
> > […]
> This is due to the implementation of the get_debug_info handler merged
> from HEAD.
> The same result happens when calling get_object_vars on a
> SimpleXMLElement object.
>
> Marcus, was it intended to only include @attributes with print_r/var_dump?
>
> Rob
> > […]
>
> --
> 
> 
>
>


-- 
Marco Kaiser

---

## #33913 — Marcus Boerger — 2007-12-10T21:00:25+00:00

URL: https://externals.io/message/33858#33913 · In reply to: #33882

Hello Rob,

  this is intended. The 5.2 solution is just a hack and returns a wrong
result in the first place. The hack was however introduced to make
development easier. Now with 5.3 we were able to change the API and coudl
apply the solution that was first developed in HEAD.

marcus

Sunday, December 9, 2007, 1:22:09 PM, you wrote:

> Hi Frank,

> Frank M. Kromann wrote:
> > […]
> This is due to the implementation of the get_debug_info handler merged 
> from HEAD.
> The same result happens when calling get_object_vars on a 
> SimpleXMLElement object.

> Marcus, was it intended to only include @attributes with print_r/var_dump?

> Rob
> > […]




Best regards,
 Marcus

---

## #33916 — Sam Barrow — 2007-12-10T21:48:16+00:00

URL: https://externals.io/message/33858#33916 · In reply to: #33913

Ok, it's supposed to be this way right? If i define a custom class in
the global namespace called "myClass" and I'm in another namespace, I
can only access it using ::myClass, not just myClass (without the
colons)? Seems to me that it should check the local namespace and then
the global, but it only checks the globl if i specifically tell it to
with the preceding "::".

---

## #33918 — Matthias Pigulla — 2007-12-11T07:31:56+00:00

URL: https://externals.io/message/33858#33918 · In reply to: #33916

> -----Ursprüngliche Nachricht-----
> Von: Sam Barrow [mailto:sam@sambarrow.com]
> Gesendet: Montag, 10. Dezember 2007 22:48
> An: internals@lists.php.net
> Betreff: [PHP-DEV] Namespace resolution
> 
> Ok, it's supposed to be this way right? If i define a custom class in
> the global namespace called "myClass" and I'm in another namespace, I
> can only access it using ::myClass, not just myClass (without the
> colons)? Seems to me that it should check the local namespace and then
> the global, but it only checks the globl if i specifically tell it to
> with the preceding "::".

From http://www.php.net/manual/en/language.namespaces.rules.php:

--
Inside namespace (say A::B), calls to unqualified class names are resolved at run-time. Here is how a call to new C() is resolved:

   1. It looks for a class from the current namespace : A::B::C().
   2. It tries to find and call the internal class C().
   3. It attemts to autoload A::B::C(). C().

To reference a user defined class in the global namespace, new ::C() has to be used.
--

Which is exactly what you observed.

-mp.

---

## #33919 — dz@bitxtender.com — 2007-12-11T09:01:34+00:00

URL: https://externals.io/message/33858#33919 · In reply to: #33918

The problem I see with that is that if I have an application that uses  
a 3rd-party library which does not use namespaces, I need to  
use ::LibClass everywhere. Until they switch to namespaces - then I  
need to touch hundreds and thousands lines of code. If LibClass were  
looked up in the global namespace, too, I could simply add the  
appropriate import statements at the top of each file.

Anyways, the process you described seems flawed in another fashion: It  
looks up a class in the namespace first, then an internal php class,  
then it tries an autoload. That does not make sense. Lets say I run  
some code as you described, and there is a class C(), but it's not  
been autoloaded yet. The internal class C is used. Then, later, the  
autoloading of A::B::C() is somehow forced. Now, if the same code runs  
again, a different class is used. That sounds like nonsense.


David




Am 11.12.2007 um 08:31 schrieb Matthias Pigulla:

>
>
> > […]
>
> > […]
>
> --
> Inside namespace (say A::B), calls to unqualified class names are  
> resolved at run-time. Here is how a call to new C() is resolved:
>
>   1. It looks for a class from the current namespace : A::B::C().
>   2. It tries to find and call the internal class C().
>   3. It attemts to autoload A::B::C(). C().
>
> To reference a user defined class in the global namespace, new ::C()  
> has to be used.
> --
>
> Which is exactly what you observed.
>
> -mp.

---

## #33920 — Lokrain — 2007-12-11T09:13:28+00:00

URL: https://externals.io/message/33858#33920 · In reply to: #33919

Calm down David :) He is referring only 3 cases. Please check the link he is
providing too :)

---

## #33921 — Matthias Pigulla — 2007-12-11T09:20:01+00:00

URL: https://externals.io/message/33858#33921 · In reply to: #33919

> Von: David Zülke [mailto:dz@bitxtender.com]

> The problem I see with that is that if I have an application that uses
> a 3rd-party library which does not use namespaces, I need to
> use ::LibClass everywhere. Until they switch to namespaces - then I
> need to touch hundreds and thousands lines of code. If LibClass were
> looked up in the global namespace, too, I could simply add the
> appropriate import statements at the top of each file.

You got a point.

> Anyways, the process you described seems flawed in another fashion: It
> looks up a class in the namespace first, then an internal php class,
> then it tries an autoload. That does not make sense. Lets say I run
> some code as you described, and there is a class C(), but it's not
> been autoloaded yet. The internal class C is used. Then, later, the
> autoloading of A::B::C() is somehow forced. Now, if the same code runs
> again, a different class is used. That sounds like nonsense.

Exactly what Chuck and Greg tried to point out, providing examples for what you describe.
http://www.mail-archive.com/internals@lists.php.net/msg31217.html

In my opinion one of the biggest weak points. In order to make things work consistently and reliable (behaviour does not change because of the order in which files are included or because new core classes are added), you need to 1) make sure all the stuff you use is already known (that is, refrain from using __autoload and revert to require() at the top of your files) or 2) explicitly use/import all your classes, even the ones from your namespace inside your namespace.

That is because __autoload comes after internal classes (which comes after already known classes from the current NS) for unqualified names. Approach 1) makes the names "already known", 2) turns the unqualified names into qualified ones by means of aliasing.

:(

-mp.

---

## #33927 — Stanislav Malyshev — 2007-12-11T18:00:24+00:00

URL: https://externals.io/message/33858#33927 · In reply to: #33919

> The problem I see with that is that if I have an application that uses a 
> 3rd-party library which does not use namespaces, I need to use 
> ::LibClass everywhere. Until they switch to namespaces - then I need to 
> touch hundreds and thousands lines of code. If LibClass were looked up 
> in the global namespace, too, I could simply add the appropriate import 
> statements at the top of each file.

But also it means that namespaced library would be influenced by any use 
code around, which was exactly the thing we tried to avoid.

> Anyways, the process you described seems flawed in another fashion: It 
> looks up a class in the namespace first, then an internal php class, 
> then it tries an autoload. That does not make sense. Lets say I run some 

Actually, it does :)

> code as you described, and there is a class C(), but it's not been 
> autoloaded yet. The internal class C is used. Then, later, the 
> autoloading of A::B::C() is somehow forced. Now, if the same code runs 
> again, a different class is used. That sounds like nonsense.

Not, it's not nonsense - try to find other way that allows overriding 
internal class names and doesn't force exhaustive autoload search on 
each access to internal class - and you'll understand why it makes sense.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #33928 — dz@bitxtender.com — 2007-12-11T20:15:00+00:00

URL: https://externals.io/message/33858#33928 · In reply to: #33927

Am 11.12.2007 um 19:00 schrieb Stanislav Malyshev:

> > […]
>
> But also it means that namespaced library would be influenced by any  
> use code around, which was exactly the thing we tried to avoid.
>
> > […]
>
> Actually, it does :)
>
> > […]
>
> Not, it's not nonsense - try to find other way that allows  
> overriding internal class names and doesn't force exhaustive  
> autoload search on each access to internal class - and you'll  
> understand why it makes sense.

Ah. Yes, that makes perfect sense to me. The logical solution must be  
then, however, not to implement namespaces at all, or requiring code  
that is either namespaced or has imported a namespace to do sth like  
"use __php__;", as others suggested last week. I understand the reason  
for the behavior from an implementational standpoint, but I think it  
really is obvious that such a namespace solution would be completely  
useless, as it would not be possible under any circumstances to  
provide code that works in a reliable fashion.

Or, as an alternative, introduce an optional third argument to  
spl_autoload_register where people can give a namespace name for which  
the autoloading should be performed. That would cut down overhead  
since just the autoload functions of currently imported namespaces  
would have to be called.

I don't really think, though, that doing something like use __php__;  
is a tall order, is it? It would only be necessary for those that  
consume namespaces in their code via "use" statements, hence no BC  
break.

- David

---

## #33929 — Stanislav Malyshev — 2007-12-11T20:22:13+00:00

URL: https://externals.io/message/33858#33929 · In reply to: #33928

> Ah. Yes, that makes perfect sense to me. The logical solution must be 
> then, however, not to implement namespaces at all, or requiring code 

It's not a solution, it's refusing to solve a problem.

> for the behavior from an implementational standpoint, but I think it 
> really is obvious that such a namespace solution would be completely 
> useless, as it would not be possible under any circumstances to provide 

If it's "obvious" for you that namespaces are useless, probably you need 
to give your obviousness-meter a check-up. They were found useful by 
many people, even if there are things to work out here and there - which 
happens with each new concept not tested in the field.

> Or, as an alternative, introduce an optional third argument to 
> spl_autoload_register where people can give a namespace name for which 
> the autoloading should be performed. That would cut down overhead since 

There's no such thing as "namespace name for which autoloding is 
performed". Autoloader receives a full class name, that's it. How this 
name was created is irrelevant.

> just the autoload functions of currently imported namespaces would have 
> to be called.

I don't understand what do you mean here, but it doesn't matter, since 
autoload call on each class access is very bad regardless of how it's 
implemented internally.

> I don't really think, though, that doing something like use __php__; is 
> a tall order, is it? It would only be necessary for those that consume 

"use whatever;" is a no-op. There's even warning about it in the engine.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #33930 — dz@bitxtender.com — 2007-12-11T20:35:17+00:00

URL: https://externals.io/message/33858#33930 · In reply to: #33929

Am 11.12.2007 um 21:22 schrieb Stanislav Malyshev:

> > […]
>
> It's not a solution, it's refusing to solve a problem.

Well, if your answer is that it makes sense this way and that it's not  
gonna be changed because it cannot be implemented without significant  
overhead, then I need to say that it would be better to have no  
namespaces rather than significantly flawed namespaces.


> > […]
>
> If it's "obvious" for you that namespaces are useless, probably you  
> need to give your obviousness-meter a check-up. They were found  
> useful by many people, even if there are things to work out here and  
> there - which happens with each new concept not tested in the field.

They are not useless. They would just be useless


> > […]
>
> There's no such thing as "namespace name for which autoloding is  
> performed". Autoloader receives a full class name, that's it. How  
> this name was created is irrelevant.
>
> > […]
>
> I don't understand what do you mean here, but it doesn't matter,  
> since autoload call on each class access is very bad regardless of  
> how it's implemented internally.

Yes, because you didn't bother to even read what I wrote. I'll explain  
it with an example for you, maybe that helps:

Let's assume we have ten autoloaders. We are, by import, in namespace  
Name::Space. Someone does new DateTime();

You would now have to go through all ten autoloaders before you can  
decide that no userspace class DateTime exists in any namespace, and  
thus the PHP internal class DateTime may be used.

However, if it were possible to do this:

spl_autoload_register(array('Name::Space::Ship', 'autoload'),  
'Name::Space');

Then you could would not have to call ten autoloaders, but just those  
registered for the currently imported namespaces. As we've only  
imported "Name::Space", this is just the one I showed above. Class not  
found? Okay, use PHP's DateTime. Overhead gone.


> > […]
>
> "use whatever;" is a no-op. There's even warning about it in the  
> engine.

Stas, really, stop retreating to technical details and making me look  
like a fool when you're tired of coming up with arguments. You very  
well know I meant "import". Reply to the suggestion in a respectful  
manner, or give it a miss.

David

---

## #33932 — Stanislav Malyshev — 2007-12-11T21:31:29+00:00

URL: https://externals.io/message/33858#33932 · In reply to: #33930

> You would now have to go through all ten autoloaders before you can 
> decide that no userspace class DateTime exists in any namespace, and 
> thus the PHP internal class DateTime may be used.

Even one autoloader is bad enough to not even have to consider the case 
of ten autoloaders. Remember, autoloader is filesystem access. 
Filesystem access on each class mention is a disaster.

> like a fool when you're tired of coming up with arguments. You very well 
> know I meant "import". Reply to the suggestion in a respectful manner, 
> or give it a miss.

I'm afraid I still do not understand what did you mean. Could you 
explain in more detail?
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #33933 — Jochem Maas — 2007-12-11T21:41:36+00:00

URL: https://externals.io/message/33858#33933 · In reply to: #33932

Stanislav Malyshev wrote:
> > […]
> 
> Even one autoloader is bad enough to not even have to consider the case
> of ten autoloaders. Remember, autoloader is filesystem access.
> Filesystem access on each class mention is a disaster.

it's just slow. regardless namespaces need to work in conjunction with
autoload in a perdictable and understandable manner ... I get the distinct
impression that namespaces+autoload is going to introduce a serious wtf factor.

given that autoload is 'out there' and the raison d'etre of namespaces is,
amongst other things, to enable better leveraging of third party code namespaces
must concede to autoload if only for the reason that one is garanteed to have to
deal with both together at some point if one is ever to seriously make use of
third party namespaced code.

as an aside, is autoload becoming the new 'magic_quotes'?

> 
> > […]
> 
> I'm afraid I still do not understand what did you mean. Could you
> explain in more detail?

---

## #33934 — dz@bitxtender.com — 2007-12-11T22:08:43+00:00

URL: https://externals.io/message/33858#33934 · In reply to: #33932

Am 11.12.2007 um 22:31 schrieb Stanislav Malyshev:

> > […]
>
> Even one autoloader is bad enough to not even have to consider the  
> case of ten autoloaders. Remember, autoloader is filesystem access.  
> Filesystem access on each class mention is a disaster.
>
> > […]
>
> I'm afraid I still do not understand what did you mean. Could you  
> explain in more detail?

Sure. My basic idea was that since the issue we're talking about can  
only occur either in namespaced code, or in code that uses namespaced  
components, there would not be any backwards compatibility problem  
with something like:

import Name::Space;
// only stuff from Name::Space available, no PHP internal stuff
import __php__;
// now PHP's classes are loaded, too.
$d = new DateTime(); // this loads __php__'s DateTime, since the first  
existance check gives that one, so no autoloading is ever performed,  
even if there is a Name::Space::DateTime class.

Now, assuming that someone wants to use PHP stuff _and_ Name::Space  
stuff of the same name, they can do import __php__ as __php__; (or  
import Name::Space as NS and then new NS::DateTime()) for either  
statement to work around that. In any case, it would never introduce  
issues. My statement 'doing a "use __php__" is not a tall  
order' (which means it's not asking much from the developer to do  
that) from one of the previous mails was referring to just that. Think  
of other languages with namespace/package concepts. If you want to use  
java's date/time features, you need to do some kind of import  
java.util.blah stuff, too. I don't think that PHP's internal stuff  
needs to be magically available. We can force developers to explicitly  
request access to it.

Did that explanation help? :)

David

---

## #33935 — dz@bitxtender.com — 2007-12-11T22:10:18+00:00

URL: https://externals.io/message/33858#33935 · In reply to: #33932

Am 11.12.2007 um 22:31 schrieb Stanislav Malyshev:

> > […]
>
> Even one autoloader is bad enough to not even have to consider the  
> case of ten autoloaders. Remember, autoloader is filesystem access.  
> Filesystem access on each class mention is a disaster.

A simple

if(strpos($className 'My::Namespace::') === 0)

will fix that just fine.


- David

---

## #33936 — Stanislav Malyshev — 2007-12-11T22:36:10+00:00

URL: https://externals.io/message/33858#33936 · In reply to: #33934

> import Name::Space;
> // only stuff from Name::Space available, no PHP internal stuff
> import __php__;
> // now PHP's classes are loaded, too.

So "import php" make internal classes always take priority even when 
there's a class in this namespace by that name? But you could achiever 
the same just by avoiding naming classes the same as internal classes, 
you surely know which classes are in your own namespace? Since in both 
cases code change is needed, why that one is better? If you created 
Name::Space::DateTime, surely there was some intent in having it named 
specifically the same as DateTime class in PHP?

> issues. My statement 'doing a "use __php__" is not a tall order' (which 
> means it's not asking much from the developer to do that) from one of 

Not using names of classes same as internal classes is not a big deal 
either - all PHP programmers do it right now :) I just don't see any 
added value in inventing artificial syntax constructs which don't do 
what they implied meaning is (they don't import anything) but instead 
change engine rules.

> the previous mails was referring to just that. Think of other languages 
> with namespace/package concepts. If you want to use java's date/time 
> features, you need to do some kind of import java.util.blah stuff, too. 

Java package system is very different. For starters, they don't have 
global space at all. And they have offline compilation stage which 
verifies all the dependencies.

> I don't think that PHP's internal stuff needs to be magically available. 
> We can force developers to explicitly request access to it.

We can, but we should not. Internal classes are internal for a reason - 
people use them a lot. Making it hard to access frequently used classes 
to enable rarely used functionality is not the right way to go.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #33937 — Stanislav Malyshev — 2007-12-11T22:38:10+00:00

URL: https://externals.io/message/33858#33937 · In reply to: #33935

> A simple
> 
> if(strpos($className 'My::Namespace::') === 0)
> 
> will fix that just fine.

Fix what? If you write:

namespace My::Namespace;
function foo() {
	$a = new DateTime();
}

then on each call to foo() autoloader for My::Namespace::DateTime would 
be called, then it would go to disk and see if there's some file 
implementing that class, search all include path for it and fail, and 
only then use internal DateTime. That's not "just fine".
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #33938 — dz@bitxtender.com — 2007-12-11T22:46:16+00:00

URL: https://externals.io/message/33858#33938 · In reply to: #33937

Am 11.12.2007 um 23:38 schrieb Stanislav Malyshev:

> > […]
>
> Fix what? If you write:
>
> namespace My::Namespace;
> function foo() {
> 	$a = new DateTime();
> }
>
> then on each call to foo() autoloader for My::Namespace::DateTime  
> would be called, then it would go to disk and see if there's some  
> file implementing that class, search all include path for it and  
> fail, and only then use internal DateTime. That's not "just fine".


namespace Name::Space;

class Ship {
   public static function __autoload($className) {
     if(strpos($className, 'Name::Space::') === 0) {
       // the real deal
      }
   }
}

...

spl_autoload_register(array('Name::Space::Ship', '__autoload'));

No disk access. And with my suggestion to allow limiting autoloaders  
to certain namespaces, it would be cut down even further.


- David

---

## #33939 — dz@bitxtender.com — 2007-12-11T22:57:13+00:00

URL: https://externals.io/message/33858#33939 · In reply to: #33936

Am 11.12.2007 um 23:36 schrieb Stanislav Malyshev:

> > […]
>
> So "import php" make internal classes always take priority even when  
> there's a class in this namespace by that name? But you could  
> achiever the same just by avoiding naming classes the same as  
> internal classes, you surely know which classes are in your own  
> namespace? Since in both cases code change is needed, why that one  
> is better? If you created Name::Space::DateTime, surely there was  
> some intent in having it named specifically the same as DateTime  
> class in PHP?

Ah. Now that you mention it, there was a flaw in my logic. The idea  
was not that PHP classes take precedence, but in this case, PHP's  
DateTime class would already be "loaded" so no autoload would be  
attempted for a Name::Space::DateTime. If, however, that  
Name::Space::DateTime was already autoloaded by the time we reach that  
code, things would just break. Hmmh. Jochem pointed it out in the  
other message; I think this autoloading thing is going to be tricky...

> Java package system is very different. For starters, they don't have  
> global space at all. And they have offline compilation stage which  
> verifies all the dependencies.

Yes, sure. I was just saying that other languages also require you to  
import language-internal stuff from time to time.

> > […]
>
> We can, but we should not. Internal classes are internal for a  
> reason - people use them a lot. Making it hard to access frequently  
> used classes to enable rarely used functionality is not the right  
> way to go.

Okay, but what do we do about the issue described initially then?  
Here's a concrete example to show the problem:

<Name/Space/DateTime.php>
   namespace Name::Space;

   class DateTime {}

<Name/Space/Ship.php>
   namespace Name::Space;

   class Ship {
     public static function __autoload($className) {
       // ... autoloader, can load Name::Space::DateTime
     }
   }

<somestuff.php>
   function someStuffWeDoNotHaveControlOver() {
     $foo = new Name::Space::DateTime();
     // ...
   }

<setup.php>
   require_once('Name/Space/Ship.php');
   spl_autoload_register(array('Name::Space::Ship', '__autoload'));

<example.php>
   require_once('setup.php');
   import Name::Space;
   $d = new DateTime(); // a PHP DateTime
   someStuffWeDoNotHaveControlOver();
   $d = new DateTime(); // a Name::Space::DateTime now!


See what I mean?


David

---

## #33940 — Matthias Pigulla — 2007-12-11T23:03:00+00:00

URL: https://externals.io/message/33858#33940 · In reply to: #33936

> Von: Stanislav Malyshev [mailto:stas@zend.com]

> But you could achiever
> the same just by avoiding naming classes the same as internal classes,
> you surely know which classes are in your own namespace? 
...
> Not using names of classes same as internal classes is not a big deal
> either - all PHP programmers do it right now :)

Rumor exists that sometimes new internal classes show up in late RCs. And as you try to name your classes so that the name describes the modeled construct best, it is not surprising that core wants to name such a new class "Date" just as userland folks had their classes named "Date" as well before (shame on them).

I always thought that one of the prime reasons for providing namespaces was to mitigate this risk of breakage in a simple, predictable and user-friendly manner.

-mp.

---

## #33941 — Gregory Beaver — 2007-12-11T23:09:37+00:00

URL: https://externals.io/message/33858#33941 · In reply to: #33940

Matthias Pigulla wrote:
> > […]
> 
> > […]
> ...
> > […]
> 
> Rumor exists that sometimes new internal classes show up in late RCs.
> And as you try to name your classes so that the name describes the
> modeled construct best, it is not surprising that core wants to name
> such a new class "Date" just as userland folks had their classes
> named "Date" as well before (shame on them).
> 
> I always thought that one of the prime reasons for providing
> namespaces was to mitigate this risk of breakage in a simple,
> predictable and user-friendly manner.

Hi,

I brought this issue up in the original thread about namespace
implementation.  I've also brought it up since then twice, including in
the long rebuttal to Derick's RFC.  Here again is the obvious solution:

<?php
namespace Foo;
use Foo::DateTime;
$a = new DateTime;
?>

now __autoload() is called.  End of crisis.  Also possible is:

<?php
namespace Foo::Long::Thing;
use Foo::Long::Thing as me;
$a = new me::DateTime;
?>

for a namespace with many classes.

Could we move on from this problem?  It is easily solved with the
current implementation.

Greg

---

## #33943 — Stanislav Malyshev — 2007-12-11T23:24:31+00:00

URL: https://externals.io/message/33858#33943 · In reply to: #33938

> namespace Name::Space;
> 
> class Ship {
>   public static function __autoload($className) {
>     if(strpos($className, 'Name::Space::') === 0) {
>       // the real deal
>      }
>   }
> }
> 
> ...
> 
> spl_autoload_register(array('Name::Space::Ship', '__autoload'));
> 
> No disk access. And with my suggestion to allow limiting autoloaders to 

I don't understand. Is your autoloader going to do any disk accesses at 
all or it's just a stub that doesn't load any classes? If it does disk 
access, it would do it on any internal class access inside namespace 
Name::Space. Please explain me in detail how it could ever happen otherwise.

-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

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