FIX: ASCII strings in PHP 6
TLK: ext/filter ready to go?
TLK: SoC Reminder
TLK: Internals newbies
TLK: Compile-time resolution
REQ: Reserved keyword leniency
TLK: #line macro in PHP?
TLK: Stop Breaking Our Apps For the Sake of OO!
TLK: The Marcus patch
CfP: International PHP Conference
TLK: Overriding E_NOTICE
REQ: Read-only properties
CVS: Zend Engine version bump
PAT: Cleaning up

FIX: ASCII strings in PHP 6

Nuno Lopes, being the newest of the core extension maintainers, recently started focusing his attention on CVS HEAD and the Unicode support therein. He wrote to the list at the end of last week asking whether there was any way to have zend_parse_parameters() check for an ASCII string? The only method he'd been able to find meant converting strings manually and 'messing around with the types'.

Andrei Zmievski, acknowledging that there was no way to do this other than manually at present, agreed it might be useful in the future. He asked whether anyone else saw a need for a parameter check for ASCII strings in PHP 6. Derick Rethans responded, but was against implementing it as a parameter check option; he thought it would be 'a pain for the users', and should only be implemented if a need for it was proven. Andrei, not a man to sit on a problem for long, promptly put something into the Zend Engine CVS to take the pain out of conversion and make Nuno's day.

Short version: Hello zend_unicode_to_ascii().

TLK: ext/filter ready to go?

Pierre-Alain Joye once again opened up the list first thing Monday morning, this time with an announcement that he'd more or less completed his changes in pecl/filter pending the extension's promotion to the core of PHP 5.2.*.

He went on to say that he had set the default filter to unsafe_raw, added the new SCALAR/ARRAY mode and implemented the input_get_args()function. He was certain that the default filter wouldn't break backward compatibility, saying that the superglobals had not been touched in any way. All that was left to be done, as far as Pierre was concerned, was to update input_get() and optimize the package. Could someone with the requisite karma please take care of the symlink binding the extension to the core?

Short version: All sounds well and good...

TLK: SoC Reminder

The deadline for the Google Summer of Code project was reached this week. Rasmus Lerdorf wrote a short note pressing those team members that had volunteered to be mentors for the Google Summer of Code project, to log in to the appropriate area of google.com and rank the applications that had flooded in over the previous couple of weeks or so.

Short version: Everybody hated that site.

TLK: Internals newbies

A couple of newbie Q & A sessions this week. First up was Thomas Moenicke, who wrote that he had two classes, A (implemented within an extension) and B (implemented in userland). B inherits from A, and contains an array:

class B extends A {
    public
$myArray = array("one""two""three");

    function
__construct() {
         
parent::__construct();
    }
}

Was it possible to access $myArray through the parent's constructor? And if so, how could he pick up the child's zval* pointer without passing it as an argument?

Marcus Börger explained that, unlike C++, PHP calls the constructors after default values are applied to class member variables. Because B was calling into A's constructor in the example, it would be just as easy to access that member as any other. Thomas thanked him for the explanation, but added that he'd now found the reason for the segfault he'd been experiencing was an uninitialized array.

Brandon Fosdick thought he'd found a bug - or possibly another man's feature - in the INIT_OVERLOADED_CLASS_ENTRY_EX macro. If he passed the classname to the macro as a const char, it worked fine; however, calling INIT_CLASS_ENTRY() from within a function where the classname had been passed as char*, didn't only not work - it also had gdb reporting the length of MyClass as 3. He'd done some digging, and found this stemmed from the length being defined in the macro using sizeof() rather than strlen(). Although noting that this approach 'provides a bit of a speed boost', he wondered whether it was really intended behaviour?

Marcus replied that it is indeed this way by design, and pointed Brandon to an existing workaround of his own:

PHPAPI void spl_register_sub_class(zend_class_entry ** ppce, zend_class_entry * parent_ce, char * class_name, void *obj_ctor, zend_function_entry * function_list TSRMLS_DC)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, class_name, function_list);
    ce.name_length = strlen(class_name);
    ...

Brandon, who had already come up with the same workaround, wrote fairly bitterly that the issue wasn't finding a fix so much as the amount of time it had taken to diagnose the problem of the class being reported 'not found', given that ce_name itself contains the expected value. 'Wouldn't it be worthwhile making this 'feature' more obvious?'

Short version: Now where would be the fun in that?

TLK: Compile-time resolution

Sara Golemon had gotten curious again. She'd noticed before that, as of PHP 5.1, constants are resolved to literals by the Zend Engine during compile time where possible. However, what she hadn't spotted until now was that this only happens if the constant has the flag CONST_CT_SUBST set, and none of the constants in the standard PHP distribution are setting that flag. Setting it for 'an assortment of internal constants' yielded the expected results, which rather begs the question - why isn't compile time substitution the default behaviour for persistent internal constants, and NOSUBST the optional flag?

Sara noted that the performance boost from making such a change wouldn't be great, but felt that 'every little helps'. The only argument she could see against applying it would be that it might cause problems for encoders, where the meaning of certain constants changes from system to system - but even so, this was the exceptional rather than general case, and should be catered for more appropriately.

Having thrown that firework into the oven, Sara went on to tell us that class constant resolution doesn't happen at all during compile time at present, with the exception of static initializers. Given that resolving class constants 'costs' two hash table lookups, there are more potential performance gains to be had from rectifying this situation than the other issue. She acknowledged that the way class constants are picked up in the parser makes accomplishing this a little tricky - read her full email if you feel like taking your brain out for a spin - but felt she had come up with a workable compromise. Her solution was to delay the call to fetch the class by simplifying the parser rule to T_STRING rather than fully_qualified_class_name, and dispatching from zend_do_fetch_constant() back to zend_do_fetch_class() only as necessary.

Naturally Sara ended her journal with a patch, alongside a note that the translated .c file is not included in with it, so anyone wanting to test this will need bison on board.

Short version: It's in the PAT directory.

REQ: Reserved keyword leniency

Ralph Schindler nearly started a small riot when he asked whether there was any chance that userland methods whose names match reserved PHP keywords could be supported in PHP 6? He felt sure there must be some way for PHP to 'know' the usage context and determine the meaning of the name from that?

This suggestion (unsurprisingly) got some fairly vocal support from other PHP users. List veteran Jochem Maas threw off core developer Tony Dovgal's attempt to move the discussion to the php-general list, and Jasper Bryant-Greene wrote that he was currently faced with over 100,000 lines of legacy PHP 4 code that relies on a set of interrelated classes, each having a try() method...

You have to feel for that man.

A strangely buoyant Ralph argued that it isn't unusual for a 'common sense' method name to match a PHP keyword, and came up with a fun list to prove it:

$session->isset($variable);
$session->unset($variable);
$trash->empty();
$long_hallway->echo();
$stage->exit();
$baseball_player->catch();
$baseball_player->throw();
$game_of_life_member->die();
$wood->break();
$vegetarian->food-> steak->try();
$lawyer->case-> try(); // double fault

before being slapped down by both Sean Coates (PHP Manual, among other things) and (more surprisingly) Pierre. Sean, with his usual precision, pointed out to Jasper that try() has been documented as a reserved word 'since Fri Oct 1 08:07:16 2004 UTC'. Jasper mentioned sourly that the application in question was originally developed in 2001.

Much sobered, Ralph wrote that he was fully aware that adding a context switch in the parser would mean a lot of work for somebody, which was his reason for requesting it in PHP 6 and not sooner. However, it must be possible to allow keywords as method names within a class context (only), mustn't it?

Wez Furlong put an end to the discussion with a fairly pointed note that 'reserved means reserved and ... if you use those identifiers and your app breaks on newer versions of PHP, you get to keep all the pieces'.

Short version: It was worth a try().

TLK: #line macro in PHP?

Aspectologist William Candillon wrote to internals@ wondering whether it would be possible to write a function, accessible from userspace, that would modify the line number in the PHP interpreter. He felt this would be useful for tools generating PHP code:

echo __FILE__//show parser.php
__setLine(8);__setFile('parser.y');
toto();

Warning: Call to undefined function: toto() in parser.y at line 9

Xuefer backed the idea, but Marcus argued that implementing such a tool would require goto before apparently remembering that actually CVS HEAD already has it... Sara mentioned a Google Summer of Code proposal for a preprocessor to evaluate #define statements. She suggested 'we could try to scope-creep this sort of thing into that project...' before coming back to Earth and adding that this should probably stay out of the Zend Engine, since it could be done by an extension. In fact, she went on to point out, so long as you didn't mind skipping out on parse errors it could even be done in userspace:

/** Generated code blah blah... */
$yyfoo = $yybar;
blah();
/**#line parser.y 123 */
whatever::thingymabob();
$foo = $$yy29188;

//Then use a set_error_handler() callback:

function my_error_handler($errstr$errno$errfile$errline) {
    list(
$probedfilename$probedfileline) =
scan_through_file_watching_for_line_directives_and_counting ($errfile$errline);
    die
"Error came from {$probedfilename} on line {$probedfileline} ";
}

Short version: She said 'scope-creep'! (Shh.)

TLK: Stop Breaking Our Apps For the Sake of OO!

Derick wrote a fairly poignant note to the internals list following his discovery that abstract static methods - which were completely legal in PHP 5.1 - throw a fatal error in the current PHP_5_2 branch. 'While I welcome new developments in either procedural or OO interfaces in PHP I do not agree with breaking BC ... just for the sake of OO purity.' In between mentioning the word 'bogus' a few times, he demanded to know when this check was going to be removed so that older applications might work again?

Pierre backed him fully over this, saying he also feels that the attitude toward breakage in minor releases lately is poor. Anything not critical or security-related should simply raise an E_STRICT message for the time being, and change in the next major version. Furthermore, when it comes to issues of purity, there probably shouldn't be any change at all; 'purists may use other languages'. Outside of anything else, the fact that any related tests are immediately updated to reflect new behaviour makes it difficult for the development team to be alert to this kind of change going into CVS. If you're lucky, you'll spot it when you're bitten by it, and that might or might not be before release. Commit messages and changelog entries are rarely explicit enough to warn about behavioural changes...

Sebastian Bergmann smelled a test-related thread opening up, and bounced into the spotlight to suggest a test system that would run automated tests across all four open development branches of PHP, on the grounds that this would show up any behavioral differences. PHP user Jared Williams pointed out that the tests would have to be diff'd too, and suggested that test cases should have their expected results altered rather than be removed outright. This way a diff between test suite versions would show up any changes in behaviour... Derick, however, was on a separate mission entirely at this point: 'How to test if you're using PHP 5.1 or PHP 5.2?'

<?php

class Bla {}
$b = new Bla;

if (
$b != null) {
    echo
"PHP 5.1";
} else {
    echo
"PHP 5.2";
}

?>

Lukas Smith piped up to agree with Pierre and request that anything requiring changes in existing tests due to BC breakage be clearly labelled in the NEWS file. Marcus wrote a nice note to Jared; he thought the existing .phpt system could easily be extended to have different expectations for different PHP versions; but Jared was by this stage busy swapping notes with Derick and Jasper over a new bit of illogic he'd found that had a value being neither NULL nor not NULL:

$foo = new stdClass();
if (
$foo == null || $foo != null) { echo 'Never gets echoed'; }

Marcus, who had spent over 12 consecutive hours working on the changes he committed into the PHP_5_2 branch this week, was already miffed at the community anyway, and exploded into a short complain@ about the lack of willingness on the part of all concerned (he means you, dear reader) to write tests for the test suite. He has a point; code coverage for PHP currently stands at less than 50%. 'Things change at will because we have nothing to test against until somebody screams after a release', he screamed, and headed off into a side battle with Derick over application design that relies on 'wrong' behaviour. He argued that the check Derick wanted removed from the 5_2 branch should really be added to the 5_1 branch, and the only reason he didn't do so there and then was that the 5_1 branch had just been closed down for run-of-the-mill changes...

Pierre defended Derick's code, and suggested that Marcus was being a bit arrogant in attacking it. He went on to attack Marcus' approach to the TODO list himself, arguing that a 300 Kb patch wasn't necessarily the best way to go about things. He felt there could and should have been a series of smaller commits rather than one massive one that would make it difficult to track down changes leading to future bug reports. He'd noticed that the Zend Engine API had been bumped, and that there are a lot of new functions in the commit, but had failed to find any mention of the API changes behind the version bump in amongst all that code. On a softer note, Pierre added that he really appreciates the 'fresh air' Marcus brings to Engine development, but it would be better if the core and PECL developers had something to hold onto - like smaller (and thus more readable) patches, and informative commit messages, and helpful NEWS entries.

(Jasper felt that it'd all make perfect sense to a computer, and explained why.)

PEAR developer Bertrand Gugger put his head above the parapet to say that he'd be happy to run tests, he just didn't have any idea about internals, and there would need to be some kind of infrastructure in place before he could hope to run all of them... Marcus replied a little wearily that there's already a perfectly good infrastructure in place: you just type make test. Turning his attention to Pierre, Marcus explained that the changes he'd committed were interdependent, and it hadn't been possible to separate the issues in the normal way.

(Jared wrote that tristate logic makes perfect sense in some languages, but he was fairly certain PHP wasn't intended to be one of them.)

Pierre refuted Marcus' claim but, having made his point, brought nothing further to the debate. PHP user Brian Moon did: 'I don't give a crap about tests. I want my code to work'. Marcus went to defend his position, and Rasmus weighed in quickly to back him up: 'If every complaint included a nice clean .phpt test file that can be dropped right into the system, things would go a lot smoother'. He hoped for a scenario where discussions could focus on how things should behave, rather than everyone getting up in arms over breakages that were obviously not intentional in the first place.

(Novelist Richard Lynch didn't like the way computers think; he uses PHP, and called the use of 'pure' logic 'asinine' there. Jasper agreed that it would be good to be able to compare NULL using equality in PHP; he'd just been trying to point out the likely reason behind the change.)

Marcus, meanwhile, was introducing Bertrand to the gcov site. Derick pounced to say he'd now written the test cases Marcus had requested for the issue that started the debate, and Ilia Alshanetsky explained to Brian that the team hoped for something more proactive than complaints about non-working code from the wider community. Jochem, who still seems to think of php.net as a service industry, predictably seized the opportunity to attack Ilia's customer care skills.

It wasn't the best timing.

Short version: We desperately need volunteers to work on the QA side (all the ways).

TLK: The Marcus patch

Marian Kostadinov was the first to notice something amiss. He transferred the E_ALL-using php.ini he'd been using with the PHP_5_1 branch to a PHP_5_2 build, and found E_STRICT was suddenly turned on. Was this an intended change or a bug?

Bastian Grupe was under the impression that E_ALL was supposed to include E_STRICT from 5.2 onwards, and suggested Marian change error_reporting to E_ALL & ~E_STRICT.

Marcus at this point officially announced that he'd finished the worst of the changes on the PHP 5.2 TODO, the remainder being a handful of Engine issues due to those items already diagnosed. The test results he was seeing looked quite reasonable, but he stressed again that the code coverage isn't good enough for this to provide an accurate measure of actual breakage. He added that, although he'd done his best to avoid interrupting everyone else's development work while making core changes, two areas had caused him trouble. One was overloaded iterators - following a change in the iterator API - which couldn't be grepped for, and the other was due to the fact that PDO in CVS HEAD is 'completely out of sync' with PDO in the PHP_5_* branches. He anticipated issues arising from both.

Returning to the subject of tests, Marcus went on to say that that the newly detected behaviour change leading to the equality test failure for NULL would need fixing in both HEAD and PHP_5_2; he'd had no intention of changing that behaviour. Again, if the test Derick had now added had been in place before Marcus made his huge commit, he would have been able to easily avoid creating that particular bug. The gcov site gives a clear view of the areas of the code base that are/are not covered; he put out a plea for extension developers to at least check their own extensions there. Finally, Marcus talked about Jared's idea of extending the test suite to handle multiple PHP versions per script, before apologizing once more for the interruptions and pointing everyone to what's left of the 5.2 TODO.

Ron Korving went obediently to look, and came back jubilant over __toString() being complete: 'Does this mean that finally __toString acts like the whole world would want it to?' Marcus replied modestly that he feared he may have missed some of the places where the Engine needs altering to use the new semantics, and asked for a test case should Ron find any. (He meant Yes.)

Pierre, meanwhile, had started arguing against the wisdom of adding E_STRICT into E_ALL at any stage, following a note from Ilia which explained that this change was actually intended for PHP 6.0. Ilia himself didn't have a problem with keeping it in PHP 5.2.*. Marcus confessed to backporting it by mistake, but also didn't see why it shouldn't stay; in fact he saw several good reasons why it should...

PHP user Oliver Block wrote asking for guidance so that he could help out with QA. Marcus pointed him towards the various READMEs about the test suite, and also to the QA team's 'manpage' on writing tests for the PHP test suite. Jeff Moore mentioned that there was an existing w3c XML test suite, which he believed might be useful for detecting changes in XML processing between PHP versions. Hartmut Holzgraefe pointed out that PHP doesn't actually do XML processing, it simply relies on libraries that do - 'or have I missed something lately?' - and the onus was on the developers of those libraries to test them. Marcus disagreed. He argued that the access functions in PHP's libxml2 support have nothing to do with those teams, and should be tested by the PHP community.

Somewhere in the middle of all the task about tests, Edin Kadribasic popped up to ask whether FastCGI was broken in the PHP 5.1.4 release? He'd noticed through the PHP general list that people were having problems with it across the board...

Short version: Engine changes can affect all kinds of things in unexpected ways. (But not FastCGI.)

CfP: International PHP Conference

Bj?rn Schotte mailed out the call for papers for this year's International PHP Conference in Frankfurt/Main. This is the longest standing large-scale conference with a focus on PHP, dating back to 2001, and most of the internals@ regulars know Bj?rn (and his duck fetish) well as a result:

Like last year, I just wanted to invite you to submit a
session proposal to this year's International PHP Conference,
5th - 8th November 2006 at Frankfurt/Main.

You can see the CfP at http://www.phpconference.com/, please
submit your proposals at http://input.entwickler.com/. The
CfP will end on May, 21st.

I would love to see you all again like last year. If you need
a special conference room for some dev meeting, please drop me
an e-mail, I will care for that together with Frank Stepan.

If you're maintaining any Open Source project, please consider
the possibility to having a free booth at the OpenSource pavillon.

Furthermore, there's room for one or two 6-hour PowerWorkshops.
If you have any good topic, please drop me an e-mail, I'll
arrange a slot.

Short version: See y'all there!

TLK: Overriding E_NOTICE

D. Dante Lorenso, still looking into his ifsetor() implementation, wanted to know whether it was possible to define a function in an extension that would not require a variable passed to it to exist, i.e. override the Zend Engine's behaviour. If not, he proposed adding a new macro to the Engine's compile-time ZEND_SEND_BY_* series, something like

#define ZEND_SEND_WHO_CARES_IF_IT_EXISTS_OR_NOT 4

Having a macro along these lines would, he believed, provide an API that would enable ifsetor() and friends to be written.

Tony thought ZEND_SEND_BY_REF should be enough for that anyway, but Dante said passing by reference makes the variable exist after the call; isset() would return TRUE in that case. No it wouldn't, wrote Tony, unless you created it during the call:

<?php

function foo(&$arg ) {}

foo($nonex);
var_dump(isset($nonex)); // bool(false)

?>

Marcus explained that 'the compiler generates code that makes the executor generate the variable and complain prior to performing the call', and said Dante would need a Zend extension to hook into that process. Dante asked for clarification, but Marcus could only point him towards Sara's book and runkit extension as potential sources of enlightenment.

Short version: Off-the-wall stuff.

REQ: Read-only properties

Jason Garber sparked a long discussion when he wrote to say that he finds himself using __get() and __set() to create public read-only properties 'horridly inefficiently' most of the time. Would it be possible to create a new attribute, readonly, for object properties? The attribute would allow reading as if the property were marked public, but allow writing only from within the class; and it would boost performance when it comes to complex application logic enforcing good visibility practices, as he'd found when diagnosing serious problems with a piece of code he was working with that relied on __get() to do the job.

Etienne Kneuss felt that readonly shouldn't replace the visibility definition, because it could also be useful with protected properties. He also felt that the issue was one of discipline; Jason could simply not edit those properties, which would totally eliminate the performance problem. Besides, checking whether a property was read-only or not before attempting to call it would require an isReadonly() method in there somewhere; the 'expensive' function call would remain. It would be just as simple to leave the Engine alone and check whether the property was empty/set before attempting to set it.

Andi Gutmans agreed with Etienne that adding a new attribute would be 'bloat'. He explained to Jason that 'we have to relax with the OO features because the increased code size has already made it harder to maintain, and it has the potential to make PHP far more complicated than it should be'. Hartmut argued that in that case we might as well drop private/protected/public altogether, since it only requires a bit of discipline...

Ron Korving suggested that PHP should be as C++ (use private; all object members are readable, but modifiability depends on the caller/object relationship). Bastian Grupe recommended Java style (use private; use a limited getter and no setter), which at least has the advantage that it can be done in current PHP; but Hartmut responded that the idea was to lose the need for that extra 'getter' line. Bastian thought the whole point of visibility was to use setters and getters consistently, saying it 'feels wrong' to be able to access some private members and not others. Hartmut pointed out that 'ppp is way older than the setter/getter fashion', and explained that the reason for its introduction in Java was to provide a standard way for Java IDEs to give access to Java Bean properties. Bastian should see visibility as a fine-grained permission system; to Hartmut it made perfect sense to distinguish between types of operation as well as ownership. If PHP were to go the getter/setter route, he concluded, everything would be private and the getter and setter alone would decide the access rights. Etienne concurred, and wrote that he also considers visibility 'candy functionality'. Gareth Ardron pointed out that visibility is extremely useful candy when it comes to maintainability in large applications.

Jason lectured the entire PHP development team on unfinished implementations:


For example, if you provide __get() and __set(), provide an efficient
way of handling the normal use case.

If you start triggering an E_NOTICE when an undefined variable is
accessed, then provide an easy way to access variables that may or may
not be set.

If you provide a __tostring() method, then finish it so that is gets
called when an object is cast to a string, concatenated with a string,
as well as being output with echo, print.

Noting Andi's reluctance to extend PHP's OO support further, Jason concluded severely: 'It's not about what YOU WOULD NOT use, it's about what a lot of people need'. Andi wrote that he could take any feature in PHP and add features. Dante jokingly took this as an offer.

Sara went straight to the 'how could it be done?' part, and suggested that readonly could be accomplished via an extension that exports an interface overriding the object's read_property() method. It would be possible to flag which properties were read-only by giving them a distinct name. The special getter would see that property bar was missing from the properties table and look for __ro__ bar instead. As there would be no write_property() override, the property would be unwritable from outside the object. Marcus suggested a slightly different approach, but also noted that the proposal couldn't work for overloaded internal objects. Jason came up with a cleaner proposal outline:

class x {
    public
readonly $xyz;
    protected
readonly $abc;
}

Definitions:
- public readonly - outside class can only read, not write.
- protected readonly - subclass can only read, not write.
- private readonly - does not make sense - do not support.

and asked Marcus how difficult it would be to build this into the Engine?

Jeff Moore, with his long history of Delphi programming, came into the discussion at this point with a plea for full property support at language level. He thought it could be implemented by adding a getter and setter field to zend_property_info and checking for it in zend_std_read_property, although he suspected there was more to it than that. He also threw in 'a few' use cases and syntax suggestions while he was at it.

Meanwhile Marcus had knocked up a patch following Jason's outline, which he later improved upon. The patch allowed properties to be marked with any visibility and also as public readable; it also implements an item from the PHP 6.0 TODO list, ZEND_ACC_READONLY. The userland syntax for using it looks like this:

<?php

class Test {
    private:public
$x = 42;
}

$obj = new Test;
var_dump($obj->x);

?>

and adheres to the following syntax:

<property> := <write_access>+ (':' <read_access>)? '$' <name> ';'
<write_access> := 'var' | 'public' | 'protected' | 'private'
<read_access> := 'public'
<name> := [_a-zA_Z][_a-zA_Z0-9]*

Marcus added that it would also be possible to add protected to <read_access>, if a little more complex. It would also be possible to change the order.

Short version: Possibly, but probably not with that exact syntax.

CVS: Zend Engine version bump

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

  • In ext/gd, bugs #37346 (invalid colormap format) and #37360 (bad gif size) were fixed across all branches [Pierre]
  • ext/curl's new function, curl_multi_info_read(), went into PHP_5_2 branch [Brian France]
  • ext/pcre gained pcre_last_error() and backtrack/recursion limit settings in 5_2 branch and HEAD [Andrei]
  • Also in ext/pcre 5_2 and HEAD, pcre_get_compiled_regex_cache() support was added [Marcus]
  • FastCGI gcc compilation bug #37376 was fixed in 5_2 and HEAD [Ilia]
  • Build bug #37413 was fixed in 5_2 and HEAD - non-working version of flex are now rejected during compilation [Ilia]
  • Core bugs #37394 (substr_compare() returns an error when offset equals string length) and #36630 (umask not reset at the end of the request) were fixed in HEAD and 5_2 [Ilia]
  • ext/oci8 bug #37392 (Unnecessary call to OCITransRollback() at the end of request) was fixed across all affected branches [Tony]
  • The Apache SAPI gained an input_filter hook call in getenv(), presumably to help the new filter extension along [Rasmus]
  • CLI bug #37306 (max_execution_time = max_input_time) was fixed in all affected branches [Dmitry]
  • SPL bug #37416 (iterator_to_array() hides exceptions thrown in rewind() method) was fixed in all affected branches [Tony]
  • A new internal property was added in ext/xsl in 5_2 and HEAD, allowing the XSLT processor to perform XIncludes [Rob Richards]
  • In ext/xmlreader, readInnerXML, readOuterXML, readString, and setSchema functionality was added and parser options can now be passed when loading (5_2 and HEAD) [Rob Richards]
  • In PDO, new attribute ATTR_DEFAULT_FETCH_MODE and fetch mode FETCH_PROPS_LATE were added in 5_2 and HEAD; the latter fixes bug #36428 (Incorrect error message for PDO::fetchAll) [Marcus]

The contents of Marcus' huge and (by agreement) binary compatibility breaking commit in PHP_5_2 branch were as follows:

. zend_exception_get_default() is now
zend_exception_get_default(TSRMLS_D)
. zend_get_error_exception() is now
zend_get_error_exception(TSRMLS_D)
. added E_RECOVERABLE_ERROR
. added ZEND_TOSTRING_FUNC_NAME
. added __tostring function cache to zend_class_entry
. added ZEND_NAMED_ME and ZEND_MN
. modified ZEND_ME_MAPPING to support method flags
. method entries now use prefix zim_ instead of zif_
. dropped EG(ze1_compatibility_mode)
. changed cast handler, removed int should_free:
typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type
TSRMLS_DC);
. changed get_iterator, now receives whether value is by ref:
zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int
by_ref TSRMLS_DC);
. added zend_objects_store_add_ref_by_handle
. added zend_objects_store_del_ref_by_handle
. convert_to_explicit_type(pzv, type)

He went on to add constructors in interfaces and a pair of new flags, ZEND_FE_RESET_VARIABLE and ZEND_FE_RESET_REFERENCE, which are used to signal to the handler whether or not foreach() is by reference.

The items there that most obviously affect PHP users are:

  • ze1_compatibility_mode has been dropped
  • __toString() support should be fully operational
  • constructors for interfaces are in
  • E_RECOVERABLE_ERROR is in (a near-fatal error that can be handled with a userspace error handler) - see http://derickrethans.nl/erecoverableerror.php

- and of course the binary compatibility breakage itself. Sebastian promptly signalled that breakage with a change in the Zend Engine version from 2.1.0 to 2.2.0.

Pierre opened up the new upgrading file for the 5_2 branch with a plea, 'Please fill it!', and Marcus promptly did.

Marcus went on to add support for RFC 2397 in the streams API (data:stream rather than data://stream), but Wez challenged him over an assumption made there and requested further analysis and discussion prior to any PHP 5.2 release.

Short version: A very busy week, particularly for Marcus.

PAT: Cleaning up

Hannes Magnusson and Rob Richards both threw in a bunch of patches to clean up after Marcus' epic patch. Tony and Marcus applied the patches and thanked both.

Edin applied a patch from me to clean up the win32 build system a little (removing pecl includes), but sadly not the one that would make the GREP_HEADER macro work for the first time ever.

Brandon Fosdick sent out his preliminary OpenSSL work for review, implementing import and export of PEM strings for both public and private keys using an OO interface. The interface adds two classes, PrivateKey and PublicKey, and Brandon asked for advice both on the class naming and about the constructor for PublicKey. He planned to add a further object for certificates before going on to add PKCS12 support. 'Thoughts? Suggestions? Problems?'

Wez responded, saying that the biggest problem was that the patch requires C++, which tends to cause more problems than it's worth when part of the core PHP distribution. He asked whether Brandon could write it in C? Brandon replied that he hadn't been aware of this, and it was difficult for him to justify the time spent on a complete rewrite. Would it be acceptable if, rather than rewriting, he forked his code and submitted a module to PECL instead? Wez, who has even less time than Brandon, didn't respond; the files are zipped and linked in PAT in the hope that someone will get back to looking at this some day.

Apart from that, there were only Sara's CT class constant changes and Marcus' read-only ideas to put in the cupboard.

Short version: More a week for sketched ideas than for completed patches in the PAT directory.