Zend Weekly Summaries Issue #288

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 "color: #007700">extends A
{
    public
"color: #0000BB">$myArray =
array(
"one" "color: #007700">,  "color: #DD0000">"two" "color: #007700">,  "color: #DD0000">"three");

    function "color: #0000BB">__construct() {
         
"color: #0000BB">parent:: "color: #0000BB">__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:


"color: #0000BB">$session "color: #007700">-> "color: #0000BB">isset( "color: #0000BB">$variable "color: #007700">);
"color: #0000BB">$session "color: #007700">-> "color: #0000BB">unset( "color: #0000BB">$variable "color: #007700">);
"color: #0000BB">$trash "color: #007700">-> "color: #0000BB">empty "color: #007700">();
"color: #0000BB">$long_hallway "color: #007700">-> "color: #0000BB">echo();

$stage
-> "color: #0000BB">exit "color: #007700">();
"color: #0000BB">$baseball_player "color: #007700">-> "color: #0000BB">catch "color: #007700">();
"color: #0000BB">$baseball_player "color: #007700">-> "color: #0000BB">throw "color: #007700">();
"color: #0000BB">$game_of_life_member "color: #007700">->die "color: #007700">();
"color: #0000BB">$wood "color: #007700">-> "color: #0000BB">break "color: #007700">();
"color: #0000BB">$vegetarian "color: #007700">-> "color: #0000BB">food->
steak
-> "color: #0000BB">try "color: #007700">();
"color: #0000BB">$lawyer "color: #007700">-> "color: #0000BB">case->
try
();  "color: #FF8000">// 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 "color: #007700">(8 "color: #007700">); "color: #0000BB">__setFile "color: #007700">( "color: #DD0000">'parser.y' "color: #007700">);
"color: #0000BB">toto "color: #007700">();

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:


"color: #FF8000">/** Generated code blah
blah... */
$yyfoo
= "color: #0000BB">$yybar "color: #007700">;
"color: #0000BB">blah "color: #007700">();
/**#line parser.y
123 */
whatever "color: #007700">:: "color: #0000BB">thingymabob "color: #007700">();
$foo
= $ "color: #0000BB">$yy29188;

//Then use a set_error_handler()
callback:

function "color: #0000BB">my_error_handler "color: #007700">($errstr "color: #007700">,  "color: #0000BB">$errno "color: #007700">,  "color: #0000BB">$errfile "color: #007700">,  "color: #0000BB">$errline) {
    list(
"color: #0000BB">$probedfilename "color: #007700">,  "color: #0000BB">$probedfileline "color: #007700">) =
"color: #0000BB">scan_through_file_watching_for_line_directives_and_counting
(
$errfile "color: #007700">,  "color: #0000BB">$errline);
    die
"Error came from
{$probedfilename} on line {$probedfileline}
"
"color: #007700">;
}

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 "color: #0000BB">Bla "color: #007700">{}
$b
= new "color: #0000BB">Bla;

if ($b "color: #007700">!= null "color: #007700">) {
    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 "color: #0000BB">stdClass();
if (
$foo "color: #007700">== null "color: #007700">|| $foo "color: #007700">!= null "color: #007700">) { 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 "http://www.zend.com/lists/php-dev/200605/msg00203.html">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 "http://oss.backendmedia.com/PhP52">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 "http://cvs.php.net/viewcvs.cgi/*checkout*/php-src/README.TESTING">various "http://cvs.php.net/viewcvs.cgi/*checkout*/php-src/README.TESTING2">READMEs about the test suite, and also to "http://qa.php.net/write-test.php">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 "color: #0000BB">foo "color: #007700">(&$arg
) {}

foo "color: #007700">($nonex "color: #007700">);
var_dump "color: #007700">(isset( "color: #0000BB">$nonex "color: #007700">));  "color: #FF8000">// 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 "http://www.amazon.com/gp/product/067232704X">book and "http://pecl.php.net/package/runkit">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 "http://www.zend.com/lists/php-dev/200605/msg00280.html">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 "http://oss.backendmedia.com/PhP60">PHP 6.0 TODO list,
ZEND_ACC_READONLY. The userland syntax for using it looks like
this:


<?php

class "color: #0000BB">Test {
    private:public
"color: #0000BB">$x = "color: #0000BB">42;
}

$obj "color: #007700">= new "color: #0000BB">Test "color: #007700">;
var_dump "color: #007700">($obj "color: #007700">->x "color: #007700">);

?>

and adheres to the following syntax:


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

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 "http://bugs.php.net/37360">#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:

- 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 "http://www.libssh2.org/patches/ct_class_constants.diff">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
.

Published: May 15th, 2006 at 12:00
Categories: Uncategorized
Tags: