Zend Weekly Summaries Issue #238

May 30, 2005


TLK: Reference issue
TLK: Greedy confusion
CVS: Derivable SQLite, array type hinting, sessions
PAT: PTY support, ext/openssl, new SAPI

TLK: Reference issue

In the middle of a deathly quiet week, Derick Rethans encountered a strange
increase of the reference count with the following script:

( "color: #0000BB">E_ALL "color: #007700">);
= array ( "color: #0000BB">1 => "color: #DD0000">'one', "color: #0000BB">2 => "color: #DD0000">'two', "color: #0000BB">3 => "color: #DD0000">'three');
function &
find_node "color: #007700">($key "color: #007700">, & "color: #0000BB">$node) {
"color: #0000BB">xdebug_debug_zval "color: #007700">('node' "color: #007700">);
=& "color: #0000BB">$node[ "color: #0000BB">$key];
"color: #0000BB">$item;
$node "color: #007700">=& "color: #0000BB">find_node "color: #007700">(3 "color: #007700">, $tree "color: #007700">);
= "color: #DD0000">'drie' "color: #007700">;
"color: #0000BB">?>

He explained that xdebug_debug_zval()looks up the given symbol in
the symbol table and prints its refcount/is_ref value
without modification. Logically, he would expect the refcount of
$node to be 2, once through the global variable $tree, and
once as local variable $node – but the reported refcount
was 3.

Derick had tracked down the places in the engine where the reference count of
$node was modified: in zend_send_ref_handler(), when
zend_ptr_stack_push() was called, and in
zend_assign_to_variable_reference(), when
value_ptr->refcount was incremented. It didn’t make any difference
whether the variable was passed by reference or by value; the refcount value was
always 3 inside the function. Why?

Zend developer Dmitry Stogov was bemused by the question: ‘One for global
$tree. One for stack. One for local $node. = 3′
. What
was wrong with that?

Derick replied that he hadn’t said it was wrong – he just wanted to know why it
was 3. He hadn’t known there was a reference kept for it being added to the stack.
Could Dmitry explain why that was? Dmitry obliged, saying that without this the zval
could be lost, because the pointer lives only on the stack, and is destroyed
on exiting the function.

Short version: There was more going on behind the scenes than I knew at
the time of writing. See week 239 for


In response to PHP user Hendy Irawan’s fairly elderly email and bug report on the
matter, Andrei Zmievski announced that he had finally upgraded the bundled PCRE
library across all branches of PHP.

Short version: Better Unicode support in the preg_* functions.

TLK: Greedy confusion

Wez Furlong mailed a terse reversion request to Antony ‘Call me Tony’ Dovgal
following his fix for bug
(fread() after tmpfile() reads only 8192

A rattled-sounding Tony wanted to know the reason for the request; he’d tested
his patch with all kinds of wrappers, and it worked fine for him.

Wez asked exactly which tests he’d run, and what problem he was trying to solve?
He explained more gently that Tony’s patch had made reads non-greedy for streams
with wrappers (except for plain files), and greedy for streams without wrappers:
The correct semantic is: only reads on local files should be greedy (for BC);
everything else should not
‘. Tony pointed Wez toward bugs "http://bugs.php.net/30441">#30441, "http://bugs.php.net/29023">#29023, "http://bugs.php.net/32649">#32649 and "http://bugs.php.net/32810">#32810 and asked if he considered
them all bogus? As far as he could see, they were all caused by

Wez scanned through the reports; #30441
couldn’t be reproduced and was probably bogus, "http://bugs.php.net/29023">#29023 was probably valid; "http://bugs.php.net/32649">#32649 must be a wrong number, being
a db2 bug report; #32810 was
valid, and occurred because tmpfile() is implemented as a wrapper-less
plain file. A correct fix for #32810
would be to tag the stream wrapper as
php_plain_files_wrapper in
_php_stream_fopen_tmpfile(); the others needed further investigation.
He ended with:

Please revert your commit, because it breaks a *lot* more stuff than
it fixes. Greedy reads for local files are only really around for BC
reasons (that nasty fread(, filesize()) thing).

Tony complied before responding. He’d meant #32469,
of course… and should wrapper-less streams exist at
all? Wez explained that they’re perfectly acceptable, and are in fact the default
for anything opened via fsockopen() and certain other ‘magic’ internal
functions. Could Wez give an example of a script that was broken by his commit? Sure:

= "color: #0000BB">fsockopen "color: #007700">(....);
fread "color: #007700">($fp "color: #007700">, 10000 "color: #007700">);
"color: #0000BB">?>

This was greedy following Tony’s patch, and should not be so, said Wez; the patch
breaks ‘proper’ network aware scripts.

Why didn’t Wez didn’t just fix #32810,
if he knew how it should be fixed? blurted Tony.

Pick one of:
- Busy 
- Mostly without internet access this weekend 
- Busy 
- Busy 
- Busy

Ilia Alshanetsky, who can take a hint, went in and fixed "http://bugs.php.net/32810">#32810 following this exchange, and
Tony fixed the compilation under Windows following his update.

Short version: We need a spare Wez.

CVS: Derivable SQLite, array type hinting, sessions

Jani Taskinen took issue with the first of new ext/ingres_ii maintainer
Grant Croker’s commits, which was a workaround for a build problem. ‘Fix it
‘ wrote Jani, usefully adding a note that would enable Grant to do
exactly that. A day later, Jani moved ingres_ii into PECL. Another one bites
the dust…

Notable commits of the week included:

  • Ilia’s scheme validation for parse_url(), always a tricky area
    (unreadable code in that file)
  • Marcus Börger’s change to make a SQLiteDatabase object
  • Array type hinting, courtesy of Dmitry Stogov:

    "color: #0000BB"><?php

    function "color: #0000BB">foo(array
    $a) {
    count "color: #007700">($a "color: #007700">). "color: #DD0000">"

    foo "color: #007700">(array( "color: #0000BB">1, "color: #0000BB">2, "color: #0000BB">3));
    // returns 3
    "color: #0000BB">foo( "color: #0000BB">123 "color: #007700">);  // Fatal
    error: Argument 1 must be an array


  • A new optional parameter, delete_old_session, in
    session_regenerate_id(), thanks to Ilia and also to Daniel J. Cain
    Jnr whose initial work in the area, "/article/491#Heading11">discussed a few weeks ago, inspired it
  • Some build hacking from Hartmut Holzgraefe (.cxx is now an allowed C++
    extension, the bison executable can be called something other than bison) and Jani
    (macro usage in the *nix build system extended to allow for greater flexibility)

Short version: Quiet but interesting week.

PAT: PTY support, ext/openssl, new SAPI

Michael Spector offered a patch for Pseudo Terminal Support in
proc_open(), introducing the --enable-pty configure option
and adding support for BSD4 PTS types. Wez had no objections to the patch, but said
it would be cooler to automagically detect support during configuration. However, he
wouldn’t be the person doing it, ‘due to the lack of any kind of positive
feedback to my last efforts
‘. Jani intervened to say that Sascha Schumann had
offered a convincing argument explaining why it wasn’t possible to add such
automagic; he was prepared to try with AC_TRY_RUN() if there was some
small test program available, but admitted to lacking the knowledge needed to write
such a program. Young Magnus Määttä chipped in to cast his positive vote for
Michael’s patch, saying he needed the functionality himself. The patch is in
PAT awaiting any kind of positive
feedback, etc.

Kamesh Jayachandra produced a patch against the 5_0 branch to fix reference
counting problems created by openssl_public_encrypt(). Wez reviewed the
patch and made a few suggestions; Kamesh rewrote it, and made it available "http://puggy.symonds.net/~kameshj/openssl.c.patch.5.0">here.

George Wang mailed in a tarball of an entire new SAPI for PHP 4 and PHP 5,
LiteSpeed. To enable it, expand the tarball under the /sapi directory, then
run buildconf and ./configure --with-litespeed. He
explained that his offering is similar to the FastCGI SAPI, with the key differences
being that the LiteSpeed SAPI is much faster, is configurable via the web server
configuration or the .htaccess file, and supports LiteSpeed Web Server
2.1RC1, about which there is more information at "http://www.litespeedtech.com/lsapi">http://www.litespeedtech.com/lsapi. He added that the company are new
to PHP SAPI programming, and would welcome comments or suggestions regarding their

Short version: PTS support for proc_open() and sapi/litespeed are
hanging out in PAT looking for action.

Comments are closed.