Zend Weekly Summaries Issue #351

      Comments Off on Zend Weekly Summaries Issue #351

REQ: Bug tracker changes
REQ: Late static binding [again]
RFC: Multi-threaded testing
TLK: Namespaces [continued]
TLK: PHP 5.2.4 release plan
TLK: Universal PHP 5 binary
CVS: Mystery extension
PAT: Nowdocs revised

22nd July – 28th July 2007

REQ: Bug tracker changes

Tim Starling kicked off the week with a suggestion that it should be possible
for users to re-open bugs marked “no feedback”. He felt it frustrating that
updates from anyone other than the bug reporter and the developers don’t
alter a report’s “no feedback” status. Worse, wrote Tim, there are no contact
details that would allow a user to alert a developer to the need to re-open a
report.

Tony Dovgal took issue with Tim over that last assertion, pointing out that
developers are notified every time the status of a report is changed.
Re-opening a report is as simple as contacting the developer that asked for
feedback… or leaving a comment in the report itself. Jani Taskinen backed
him; adding a comment and then sending an email to the developer should be
enough. He mentioned that there once was a time when users could simply
re-open bugs in the way that Tim suggested, but it hadn’t worked well. Jani
promised, however, to come back to this issue once his scheduled changes to
the tracker are up and running.

Short version: It’s marginally less chaotic than it looks.

REQ: Late static binding [again]

A Sebastian Deutsch wrote to internals@ asking for a status update on the
late static binding proposal for PHP 6. Lukas Smith explained that the
problem is nobody’s yet found a way to implement late static binding without
a performance hit and increased memory usage.

Etienne Kneuss mentioned in passing that he’d been busy preparing and testing
a patch to implement the feature. He wasn’t prepared to publish his code at
this stage, but claimed that his most recent tests had suggested a bit of a
breakthrough.

Short version: Keep your fingers crossed.

RFC: Multi-threaded testing

Nuno Lopes announced that, following the move of http://gcov.php.net to a faster server, he’d
like to speed up the time spent running the test suite across all branches of
PHP. To this end, he proposed a multi-threaded version of run-tests.php
that could spawn a configurable number of processes, with each having
responsibility for a given number of extensions. He asked for comments.

Whoa. It seems that having your own hack for that particular script is a
popular pastime, and a handful turned up. These included one from Andrey
Hristov that iterates though different configuration settings, and a shell
script from Rasmus Lerdorf making it more straightforward to run tests on a
given extension.

Having read the feedback and written a hack of his own, Nuno noted that the
test suite script itself probably needs a full rewrite. Sebastian Bergmann
explained that this is actually on the TODO already – including the proposed
multi-threading support – and sundry people agreed that the script deserves a
page on Lukas’ wiki where ideas for its re-design can be collated.

Short version: The test suite gets some long overdue focus.

TLK: Namespaces [continued]

More people wrote to internals@ during the week with questions and
reflections about the namespace implementation. Markus Fischer couldn’t see
how to go about importing all classes from within a given namespace. He’d
expected import Foo or import Foo::* to achieve
this, but neither worked. Markus also thought an error should be thrown when
a class already existing in the current scope is imported. Stas agreed with
him over the need for an error, and explained that the correct approach to
importing namespaced classes was to stipulate each
namespace::class individually. Derick Rethans wrote smartly that
this didn’t answer Markus’ question, and one Jeremy Privett complained that
the implementation is non-intuitive precisely because of issues like the
impossibility of a global import. Stas Malyshev pointed out that ‘the
whole purpose was to get the classes OUT of the global space
‘; he saw no
reason to bring them back into it. Alexey Zakhlestin backed Stas here; in his
experience, it was rarely necessary to import more than a handful of classes
per file – just those explicitly used by that file.

Paweł Stradomski was unhappy with this. He wanted to know what would
happen if he wanted to access all classes from a third-party namespace within
just one of a group of namespaces in his own application. Would he need to
import each and every one of those third-party classes by name? Brian Moon
didn’t see any point in using namespaces just to bring classes into the
global namespace. To him the nice thing about namespaces was that it kills
the need to prefix classnames; instead of
SQLAlchemy_Transaction, he could now have a class named
Transaction in the SQLAlchemy namespace, and
instantiate it using new SQLAlchemy::Transaction. David
Zülke didn’t see what was so nice about being able to use
:: rather than _, and said so. Paweł, who only
wanted a local import for that part of his application that would use the
third-party classes, wrote that he couldn’t see how this was possible with
the current implementation. Every other language that has namespace support
(read: Java, python, C++) allows this… Stas pointed out again that names
that should be part of the global space shouldn’t use namespaces, and went on
to explain that Java classes and python modules have a far more rigid
relationship with the filesystem layout than is on offer here. Besides, Java
is a compiled language; the classes are known at compile time, which is not
the case with PHP. Paweł pointed out again that he didn’t want those
third-party classes to be available in his global namespace – just in the
files that needed them. ‘If using a bunch of imports is the only way that
is accepted – then at least a shortcut like python’s “from x import
a,b,c,d,e,f,g,h” would be nice.
‘ Stas agreed that supporting a comma
syntax for group imports was probably a good idea, and also agreed to think
about the python shortcut approach.

Derick agreed with the critics; he couldn’t see how the current
implementation was useful. Brian explained how it would be useful for
his team; they had had to check third-party code to avoid naming conflicts
with their own code in the past, and this implementation will allow them to
avoid that problem. Brian added, though, that this approach to namespaces was
perhaps better for project-wide namespacing than for smaller parts; he
wouldn’t want to work with 50 different namespaces with this solution either.
Then again, he wouldn’t want to find himself working with 50 different
namespaces in the first place… Someone named Giedrius wrote that it
wouldn’t always be within the power of the developer to decide whether
namespaces were needed or not. Third-party libraries might well use them, and
that was where it might be useful to be able to import all classes from a
given namespace. Stas argued that putting everything into the global space
would in no way solve the problem of potential naming conflicts. Blanket
imports would make compile-time name resolution completely impossible, and
would also cause technical problems when it came to maintaining separate
per-file global scopes. Using tools (such as an IDE) would help the developer
when it comes to groups of import statements.

Andrew Minard wrote that, in his view, the restriction on blanket imports
meant that PHP was trying to solve an application-level problem at language
level. He’d rather see a discussion of the technical reasons for not
supporting them. Stas explained the difference between compile-time and
runtime resolution: ‘allowing blanket imports means we don’t know what
“new Foo()” means until it is executed – meaning we need to make extra
lookups on each class fetch, even if the code doesn’t use namespaces at
all.
‘ Andrew argued that the extra lookups come from applying imports at
runtime; a blanket import could only be applied if classes were available at
compile time. He agreed, though, that this might lead to some confusion. Stas
retorted that Andrew couldn’t imagine just how broken that would be… there’d
be absolutely no way to know what was being imported. Any change in load
order, configuration values or class dependencies could potentially break
code relying on compile-time imports, and trying to explain why the code was
broken to programmers who don’t necessarily grasp the difference between
compile-time and runtime class definition would be problematic. The whole
point of PHP was that it was supposed to be easy… Further problems with
blanket imports include global space pollution (as mentioned earlier) and
unfriendliness to bytecode caches‘. Andrew backed down gracefully,
just as Rasmus joined the conversation to support Stas’ assertions. Matthew
Kavanagh, though, wanted to know why it wasn’t possible to import namespaced
functions and constants into the global namespace? Rasmus didn’t see why not,
so long as there was an alias in place for them; import foo::* as
myfoo
had no performance issues, so far as he was aware, although a
direct import would. Stas simply didn’t see the point in that; you might as
well just call namespace::function() and have done with it.

Larry Garfield was next up, wanting to know more about supporting utilities.
Was there a way to pick up the full name of a function or class, so that you
could see where it came from? Would the import statement work for functions
as well as for classes? He could see potential for namespace usage in
plugin-based architectures, where each plugin has its own namespace;
iterating over a list of plugin namespaces and invoking the same operation on
each would require call_user_func() and
call_user_func_array() to be namespace-aware. Was this possible?
Wouldn’t the callback type need to be able to handle namespaces? Stas didn’t
see why call_user_func() shouldn’t be able to use namespaced
names already, since the namespace is just part of a class name. That said,
they’d need the full class name to work currently; it wasn’t clear to him yet
which functionality would be needed to support short names there. Larry ran a
quick test and found this an accurate assessment of the situation, much to
his joy. Stas added that __autoload() should get full classname
information, too.

Marcus Börger finally weighed in with his opinion. He gravely thanked
Dmitry Stogov for the implementation, but felt that this is actually a
package model masquerading as namespaces. Shouldn’t the name be changed to
better reflect the functionality? Stas felt it was actually neither one nor
the other, but came closer to namespaces than packages in his opinion.
Sebastian Bergmann backed Marcus, noting that this implementation is very
close to the concept of packages in Java. Dmitry agreed that it was similar,
and – although Ada and python also have package models that are completely
different conceptually – he wouldn’t be against renaming the PHP version.

Short version: When is a namespace not a namespace?

TLK: PHP 5.2.4 release plan

Ilia Alshanetsky, as Release Master of the PHP 5.2 series, announced his
plans for the PHP 5.2.4 release cycle as follows:

Short version: PHP_5_3 can’t be too far away now.

TLK: Universal PHP 5 binary

One Christian Speich wrote to internals@ about a problem he’d come across
when using PHP 5 as a universal binary on MacOS X. The binary had been built
on an Intel Mac, and worked well there, but a copy of that same binary on a
PowerPC Mac had been unusable. Strange error messages and applications that
repeatedly tried to load were two of the issues Christian was seeing there.
His PHP 4 universal binary, on the other hand, worked fine on both machines.
Was there a bug in PHP 5?

Tony explained that the Intel Mac is little-endian and the PPC Mac
big-endian. Because endianness is detected during configuration, the binary
could be guaranteed to run normally on the system it was built on. However,
to make the binary work on both platforms there would either need to be
separate binaries for PPC and Intel Macs, or the PHP sources would need to be
patched. That said, Tony declared himself open to suggestions when it came to
improving universal binary support.

Jani – who is responsible for most of the configuration scripts used in PHP
builds – suggested someone should probably sponsor him with an Apple laptop,
but everyone ignored him. Uwe Schindler came up with another suggestion:
endianness should be defined and included after the generated header
file, using a macro that goes something like:


#if defined(MACOSX)
# undef WORDS_BIGENDIAN
# define WORDS_BIGENDIAN __BIG_ENDIAN__
#endif

Another option might be to update to a recent version of
autoconf, but Uwe didn’t see how this approach could be made
feasible in PHP.

Tony wasn’t at all sure about that macro. He didn’t think it would work for
anything other than a universal binary; besides, he didn’t believe the
constant __BIG_ENDIAN__ actually existed. That said, Tony added
that this wasn’t actually an area of interest for him. If Uwe cared to spend
some time on it, he’d help where he could.

David Wang was confused; he thought a ‘universal binary’ was a pair of
binaries packaged together, one compiled for Intel and the other for PPC. How
could this be achieved in a single run on Christian’s machine? Was there some
special build tool or compiler for universal binaries? Tony explained that
GCC on an Intel box is able to build both PPC and Intel; to create both
binaries in a single run would be as simple as adding


CFLAGS="-arch ppc -arch 386"

into the mix.

Uwe meantime had checked to see exactly what the
Apple developer site
has to say on the subject of runtime endianness
checks. It offered three options: the use of C preprocessor macros
(__BIG_ENDIAN__ does exist after all); the use of certain
functions to guarantee big-endian representation regardless of the platform
architecture; or individual byte extraction through bitwise masking and
shifting.

Christian had by now tested Uwe’s initial suggestion by adding the script to
php-config.h, and reported that this had worked perfectly for him.

Short version: A way through the woods.

CVS: Mystery extension

Changes in CVS that you should probably be aware of include:

  • In ext/sockets, bug
    #21197
    (socket_read() outputs error with
    PHP_NORMAL_READ) was fixed [Jani]
  • Zend Engine bug #42071 (ini
    scanner allows NULL to be used as option name) was fixed
    [Jani]
  • Core bug #42072 (No warning
    message for clearstatcache() with arguments) was fixed in
    PHP_5_2 branch only [Ilia]
  • TSRM bug #42027
    (is_file() / is_dir() matches file/dirnames with
    wildcard char or trailing slash) was fixed [Dmitry]
  • In ext/soap, bug #41983
    (Error fetching http headers terminated by ‘
    '
    ) and the
    streams-related bug #41984 (Hangs on
    large SoapClient requests) were fixed [Dmitry]
  • A huge number of Zend Engine bugs were fixed: #40757 (get_object_vars get
    nothing in child class), #41929
    (Foreach on object does not iterate over all visible
    properties), #41372 (Internal pointer
    of source array resets during array copying), #37715 (array pointers resetting on
    copy), #40705 (Iterating within
    function moves original array pointer), #40509 (key() function
    changed behaviour if global array is used within function) and #41713 (Persistent memory consumption on
    win32 since 5.2) [Dmitry]
  • The PCRE extension gained a new constant, PCRE_VERSION
    [Tony]
  • In ext/json, bug #42090
    (json_decode causes segmentation fault) was fixed [Hannes
    Magnusson]
  • Reflection gained a new method,
    ReflectionExtension::info() function, which prints the
    phpinfo() block for an extension [Johannes Schlüter]
  • Core bug #42107
    (sscanf broken when using %2$s type format
    parameters) was fixed [Jani]
  • In ext/libxml, bug
    #42112
    (deleting a node produces memory corruption) was fixed [Rob
    Richards]

In other CVS news, Jani got around to fulfilling an antique feature request, as a result
of which the display_errors INI directive will now accept
"stderr" as a value in both PHP_5_2 branch and CVS HEAD. If you
use this setting with the CGI or CLI SAPIs, your error messages will go to
STDERR rather than STDOUT.

Jani was also responsible for the mysterious appearance this week of a “sort
of” extension in CVS HEAD, ext/mysqlnd. If this is what I think it is,
it’s good news for all you PHP/MySQL users out there… but I’ll confirm this
in a future Zend summary.

Short version: Is there such a thing as too much caffeine?

PAT: Nowdocs revised

Gwynne Raskind wrote to internals@ to say that she’d revamped her
original nowdocs patch
to make it ‘more efficient and functional‘.
The new version allows nowdocs to be used in static_scalar
contexts, such as class constants and static variable initializers. Gwynne
had also cleaned up her opcode usage and the code in the Zend language
scanner, written a bunch of tests and ensured that her patch merges cleanly
to anywhere it might end up.

The patch is available for download at http://phpdoc.gwynne.dyndns.org/nowdocs.zip,
or you can browse the code at http://phpdoc.gwynne.dyndns.org/nowdocs/.

Short version: It’d be nice if someone took the time to look it
over.