Categories


Loading feed
Loading feed
Loading feed

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:

It has been a while since our last release and the ChangeLog has grown
quite a bit, so I think it is time to start thinking about 5.2.4
release before the change set becomes unmanageable. To this effect
I'd like to start the release cycle with RC1 planned for Thursday
next week. Hopefully after the RC1 we can get to the final release
within about a month's time. So, if you have any remaining major
changes you want to apply, you have until Thursday, after RC1 only
bug fixes and new test cases will be accepted.

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.

Comments