Zend Weekly Summaries Issue #286

      Comments Off on Zend Weekly Summaries Issue #286

TLK: openssl and patch authoring
FIX: ZSTR and NULL (again)
TLK: All about PECL
TLK: Static properties
TLK: Functions by reference
BYE: Ard Biesheuvel
RIP: PHP_5_0
TLK: Generating a backtrace on IIS
TLK: Upload progress revisited
CVS: Blame FastCGI

TLK: openssl and patch authoring

Brandon Fosdick kicked off the week with his hunt for the current maintainer of
ext/openssl. Having tracked down Wez Furlong, he explained that he needed the
PKCS12 functions and the ability to extract public keys, and was planning to
contribute both. He added that he had no experience with PHP internals, and could do
with some advice over it.

Wez checked that Brandon was aware of the existing function
openssl_pkey_get_public(); Brandon had, but needed the keys in PEM
format. Wez noted that openssl_pkey_export() comes close to Brandon’s
needs, but is limited to private keys; he wrote that he’d welcome a patch for that,
too, and gave Brandon a rundown of the resources available to internals beginners,
up to and including the file README.SUBMITTING_PATCH distributed with
PHP.

Looking into PHP source code for the first time, Brandon wondered what the
difference between a resource and an object is, from the
perspective of an extension? ‘Are resources somehow special?‘ Wez explained
that resources, prior to PHP 5, are used for mapping an arbitrary pointer to PHP
space; in PHP 5 and up, the pointer is mapped as a PHP object. The biggest
functional difference, other than OO support, is that you can’t create persistent
objects; resources are necessary for persistency. He went on to advise Brandon that
it’s generally faster to write a procedural extension using resources than it is to
write an OO extension using objects, but there is no rule regarding the approach to
take; extension authors should simply choose the best tool for the job.

Short version: New openssl functionality upcoming.

FIX: ZSTR and NULL (again)

Andrei Zmievski reported that CVS HEAD no longer compiled under gcc 2.95
following some changes Frank Kromann had made. (This impressed Nuno Lopes, who
hasn’t got PHP to build under gcc 2.95 in Solaris at all and had assumed it was
unsupported.) The error Andrei was seeing was:

/homes/andrei/dev/php-src/ext/spl/spl_directory.c:1359:
cast to union type from type not present in union

The line referred to there reads:


buf =
php_stream_get_line(intern->u.file.stream, NULL, 0,
&line_len);

and the definition of php_stream_get_line() reads:


#define php_stream_get_line(stream, buf,
maxlen, retlen)
_php_stream_get_line((stream), IS_STRING, ZSTR(buf), (maxlen), 0, (retlen)
TSRMLS_CC)

The problem was that under gcc ZSTR() is defined as:


typedef union _zstr {
    char *s;
    UChar *u;
    void *v;
} zstr;
#ifdef __GNUC__
# define ZSTR(x) ((zstr)(x))
# define NULL_ZSTR ZSTR((void*)NULL)

Did this mean (void*)NULL should be passed everywhere now under gcc,
or could anyone come up with a cross-platform solution?

Wez suggested that ZSTR(buf) should simply be removed from the
macro:


#define php_stream_get_line(stream, buf,
maxlen, retlen)
_php_stream_get_line((stream), IS_STRING, (buf), (maxlen), 0, (retlen)
TSRMLS_CC)

and the caller should apply ZSTR() to the argument manually where
required.

Dmitry Stogov had somehow missed the reason for Frank’s changes in the first
place, and wanted to know what the problem had been with NULL_ZSTR()?
Both Frank and Nuno replied that it made ZSTR(NULL_ZSTR) possible,
which is invalid; they also both backed Wez’ solution. Sara Golemon also supported
it, and wrote that she’d change the stream macro(s) herself if someone else didn’t
get there first. Frank got there first, and asked Andrei to run a test build under
gcc again, but PHP user Hannes Magnusson had already tried it and reported a compile
failure in ext/zlib as a result of the changes. Nuno, who had also found
ZSTR() macros missing from php_stream_get_line() calls in
ext/pdo, ext/standard and sapi/cli, presented a patch to fix
the lot, which Frank subsequently applied; he wrote, however, that there were a
couple more extensions in need of the same treatment, and set out on a mission to
find them all.

Short version: Wez saves the day.

TLK: All about PECL

Tony Dovgal wrote to internals@ proposing that a bunch of extensions should be
moved out of the PHP core and into PECL, in the as-yet-non-existing PHP_5_2 branch
and in CVS HEAD. He singled out ext/hwapi, ext/filepro and
ext/recode in particular, arguing that Hyperwave is very much a minority
interest; FilePro has been superceded by SQLite; and ext/recode, which is
known to break the ext/mysql build when enabled, has long been superceded by
iconv. However, he felt strongly that all unsupported, unmaintained or
underused extensions should be moved to PECL at this stage. He didn’t believe, for
example, that ext/snmp could be widely used, given its lack of maintenance.
Furthermore, there are nine ‘yes, NINE!‘ unmaintained and/or unsupported
SAPIs in the PHP core… he wasn’t certain whether it was possible to move these to
PECL (it is – see activescript), but if it was, that was where they should be.

I wanted to add ext/skeleton to that list, but was roundly shouted down by
Tony (who doesn’t consider it ‘unsafe’), Wez (who feels that an extension template
by definition should be shipped as part of the core), Ilia Alshanetsky (who doesn’t
want to have to search through PECL for an extension template) and Derick Rethans
(‘Yeah, I want to keep that too‘). So that’ll be a ‘no’, then. Hartmut
Holzgraefe wrote that he had given up trying to maintain ext/skeleton because
it depends on ‘arcane tools like awk‘, and he didn’t care what became of it.
He added that PECL_gen should be compatible with ext_skel, although he hadn’t
checked this recently; however, he couldn’t claim with confidence that the package
is more maintainable than ext/skeleton.

Mike Bretz suggested throwing a warning in the PHP 5.* extension configure
scripts that are slated for removal to PECL, and not actually moving them until PHP
6.0. He also came up with the idea of keeping options such as
--with-hwapi in PHP 6.0 and having them print an error message about
the PECL move, which would be helpful to those using outdated configuration
options.

I’d moved on to the problem (at least I think it’s a problem) of PHP for Windows
shipping with no de facto database support since PHP 5.1.0, unless the team
are prepared to count the unmaintained ext/odbc as providing that support.
Under win32, ext/sqlite is no longer enabled by default; it can’t be enabled
at all without PDO support being enabled in the php.ini first. It would make
sense to me to have PDO enabled by default at the very least; is there any reason it
isn’t? Wez argued that enabling SQLite is a one-step process; I argued that not only
is it not “one-step”, it’s also fairly “wtf”.

There was no answer to my question about built-in PDO except on irc, where
everyone assumed Wez doesn’t want PDO built-in because it’s not marked as stable
yet. Given that background, I provided a patch to allow ext/sqlite to build
with or without PDO, making built-in SQLite possible once more. If PDO were built as
shared alongside SQLite 2, the resulting binary would be named
php_pdo_sqlite2.dll. If SQLite 2 support were built as shared without
PDO, it would simply be php_sqlite.dll, the same as in the PHP 4.* and PHP
5.0.* branches. If built as static, it would ‘just know’ whether it had PDO support
or not and build appropriately.

Wez turned down my patch, arguing that it would mean the only version of SQLite 2
available in the official snapshot builds would be php_pdo_sqlite2.dll. I
pointed out that this is already the case, except that right now it happens
invisibly – but my arguments fell on deaf ears.

Short version: Some you win, some you lose…

TLK: Static properties

Edin Kadribasic wondered why it isn’t possible to create static properties on the
fly, and gave a short demonstration:


php -r 'class foo{}; foo::$bar = 1;'
Fatal error: Access to undeclared static property: foo::$bar in Command line
code on line 1

Was this something to do with the way static properties are implemented in the
Zend Engine?

Petar Nedyalkov wrote that, in his opinion, this was the right behaviour. Leaving
aside the fact that PHP is not a compiled language, having a member variable of an
object available only after its declaration – give or take stdClass – seemed correct
to him. He didn’t see why redefining the model at runtime should be allowed.

Jochem Maas argued that Ruby and javascript both allow exactly that and, given
that non-static properties can be defined on the fly in PHP, he found the severity
of the error surprising. He’d have expected an E_STRICT. Marcus Börger
pointed out brusquely that there is a difference between class-based and
prototype-based OO support.

Edin mentioned that he’d simply been asking whether this was the result of a
technical issue, or ‘someone else’s purist OO views‘. Marcus took pity on
him, and explained that there had been a conscious decision taken to make the newer
OO support more strict. Edin didn’t remember any such decision; in fact he didn’t
even remember an open discussion about it, and wrote rather bitterly that the only
thing he knew of were ‘the efforts of some people to make PHP less PHP and more
Java
‘. Having


class foo{};
foo::$bar 1;

throw a fatal error makes some of the things he really likes about PHP,
impossible. It made no sense to him to have false restrictions placed on new
features; he was used to working with a dynamic language. He has code
like:


class Customer {
    function 
get($id) {
        
$res $DB->query("select * from customer where id="
.((int)
$id);
        while (
$row $DB->fetchRow($res)) {
            foreach (

$row 
as $key $value) {
                

$this
->{$key} = $value;
            }
         }
     }
}

and had planned to make his site options work in a similar way, only using class
variables:


class options {
    function 
load() {
        
$res $DB->query("select * from options");
        while (
$row $DB->fetchRow($res)) {
            

self
::${$row['KEY']} = $row['VALUE'];
        }
     }
}

This would allow him to use


if (options::$allow_anon
) {
    ...
}

throughout his site, without ever having to create an instance of the class. To
add a new site option variable, he could simply insert a key/value pair into the
options database. However, the existence of that fatal error prevented this; and he
was less than happy to discover that this was caused ‘not by any technical
difficulty, but by a desire to make PHP less PHP
‘. Edin proposed removing the
restriction in the PHP_5_2 branch, and reconsidering the attitude towards making PHP
less dynamic in the future.

Marcus confirmed that there had been ‘no endless discussion like we too often
do on the list
‘; this was more of a private agreement between those implementing
it, while implementing it. He went on to point out that any feature would
have an advantage for somebody, and a disadvantage for somebody else. Adding this
particular feature would lead to PHP having to support the interception of static
properties, which he didn’t think anyone on the team would be happy with.

Edin was unhappy that there’d been ‘no public discussion whatsoever‘,
arguing that such a basic question about the future direction of PHP deserves some
attention. He strongly disagreed with the current approach, and didn’t want to see
PHP’s dynamism disappear under pressure from those who preferred the way things are
done in other languages; ‘for me, PHP is the cool language‘. He hoped
to hear the rest of the PHP group members’ and core developers’ thoughts on the
subject. As for the perceived problem of static property interception, Mike Wallner
had already provided a simple patch to implement it…

Short version: One man’s heaven is another man’s hell.

TLK: Functions by reference

PHP user Brian Moon had discovered a shifting error between PHP versions, and
wanted to know where the land really lies. In PHP 4 the following was legal
code:


function test() {
    return array(
1,2,3);
}

$var array_shift(test());

Under PHP 5.0.0, the same code threw a fatal error with the message that only
variables could be passed by reference. Brian’s team had looked into the reasoning
behind the new error and, concluding there was a good argument for it, had begun the
tedious task of migrating their code base. They’d recently upgraded their
development boxes to PHP 5.1, only to find the error gone. Was it a deliberate fix,
or was that piece of code likely to start throwing errors again in the future?

Rasmus Lerdorf explained that it will always be a bad idea to pass a temporary
variable by reference, which is why doing so in PHP 5.1 results in an
E_STRICT; it would be best to write code that is E_STRICT
compliant.

Brion Vibber wanted to know why it’s a bad idea. He would have expected


func_taking_reference(some_func());

and


$temp some_func();
func_taking_reference($temp);

to be equivalent, where $temp is never used again and quickly passes
out of scope. Is there some reason they aren’t? Brion recalled that the reason given
for the reference handling changes was that reference abuse caused memory
corruption, but this explanation didn’t make sense if reference abuse was allowed
again in PHP 5.1.

Rasmus pointed out that it does actually cause memory corruption in the PHP 4.3
series, and any code likely to be run under PHP 4.3.* really needs to be
clear of reference abuse. Beyond that, it tends to be indicative of a bug in the
code. There are exceptions to that rule, and in such cases – assuming the code
doesn’t need to run under PHP 4.3.* – it could be valid to pass a function by
reference. However, he felt it would be a better idea to write something like


func_taking_reference($quiet=some_func()); // throw away reference modification

with the stress on the documentation part. This would both avoid the
E_STRICT warning and make the reasoning clear to those maintaining the
code base. He went on to remark that the same argument could be made when it comes
to using undefined variables. Much of the time the E_NOTICE thrown is
useful, because it indicates a bug. The fact that it gets in the way sometimes isn’t
a reason to write non-compliant code.

On a different tack, Peter Brodersen noted that many of the reference problems
came about because people used array_shift() or
array_pop() as a shortcut to retrieve an element returned from a
function. Although agreeing that the reference handling changes were necessary, it
seemed to him that such functions are misused because of the lack of array operators
such as array(2, 4, 3)[1]. Peter wasn’t arguing that there is a demand
for such beasts, but wanted to make the point that when there is no simple ‘right’
way to do something, people will find a simple ‘wrong’ way.

Short version: No (real) change.

BYE: Ard Biesheuvel

Interbase/Firebird guru Ard Biesheuvel wrote to the internals list apologizing
for the lateness of his reply to queries regarding the status of the PDO_Firebird
extension. He went on to write, ‘As you might have guessed already, PHP is not a
high priority for me at the moment
‘.

First of all, you will probably remember that I was not completely satisfied
with the direction set out for PDO, the reason being that the chosen model for PDO
doesn’t map really well to Firebird/Interbase. I wholeheartedly agree with ‘majority
rules’ and all of that, and I’m convinced that PDO will be a great success. But for
me, PDO/Firebird isn’t that much of a challenge anymore.

The main reason for not participating lately, however, is that I’m really busy
working in a completely different field. I’m doing research on PVR-applications for
Philips [no, I had nothing to do with the patent about blocking the controls during
a commercial block :-)], and it doesn’t involve PHP or Firebird. So it seems I won’t
be of any use to you lot in the near future.

So it’s official now, then – php.net are looking for a new PDO_Firebird author
and ext/interbase maintainer.

Short version: If anyone wants to thank Ard for the hard work he put
into making ext/interbase usable, his wishlist is very modest.

RIP: PHP_5_0

Sönke Rümpler wrote to internals@ wondering what the status of the PHP 5.0 series
is these days. His assumption was that the branch is no longer being updated; was he
correct in believing that he should upgrade to PHP 5.1.*?

Andi Gutmans confirmed that PHP 5.0.* development has now been discontinued in
favour of the PHP_5_1 branch, and advised Sönke to go with the 5.1 series.

Short version: It’s official.

TLK: Generating a backtrace on IIS

PHP user Sharad Gupta wrote to the internals list with a problem. His employer
had recently switched its servers from Apache 1.3 to IIS 6, ‘not for technical
but for business reasons
‘, and his team had been unable to get any PHP 4 ISAPI
to work with it. They were seeing a PHP crash and an access violation message.

Sharad understood that it would be difficult for anyone to help without extra
debug information, but he was having problems obtaining it. He’d tried the Microsoft
Diagnostics Toolkit shipped with IIS, but the server itself was not crashing when
the error occurred, meaning that he couldn’t get the information needed for the MS
bug report. Was there any way to obtain debug information from PHP 4?

Hannes provided a link to Edin’s site, which carries a Windows
debug pack
for PHP 4.4.3-dev. William A. Rowe, Jnr, claimed that ‘Dr. Watson
or any other Windows debugger
‘ can use the .pdb files matching a release
binary to spit out a backtrace. However Nuno – who is a more than competent user –
wrote that he’d never been able to use any Windows debugging tool with .pdb
files himself, and asked Sharad to write a tutorial for the bugs.php.net site if he
manages it.

Sharad started compiling a debug version of PHP 4.4.2 himself at this stage, but
found he was getting an “input file not found” error when using the .dll he’d
created. Wez suggested that he should switch to linking against the release version
of libc.lib – but whether this helped, we never heard.

Short version: Debugging under win32 is still not a simple
matter.

TLK: Upload progress revisited

Rasmus took another look at one of the upload progress patches available after falling
across Joshua Eichorn’s AJAX implementation, which uses it. He recalled that there had
been some valid reason for not adding the patch into PHP, but ‘looking over the
code, it doesn’t jump out at me’; it seemed safe enough, although he admittedly
could be missing some thread safety issue. Did anyone remember what the problem was
with it?

I drew his attention (off-list) to another implementation from Klaus
Reimer, which has been sitting in the PAT directory for the last 18 months. Rasmus
commented that the patches were very similar; the only change he would make to both
offerings would be to put the temporary filename into the function calling the
callback. This would offer the extension a way to track the upload that triggered
the callback, even in a threaded environment with concurrent uploads.

Short version: No takers?

CVS: Blame FastCGI

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

  • In the new hash extension, bug #37192 (cc fails on hash_adler.c:32) was
    fixed in CVS HEAD and PHP_5_1 branch [Mike]
  • Core bug #37191
    (chmod takes off sticky bit when safe_mode is On) was
    fixed in HEAD and 5_1 [Tony]
  • A bug in the Apache
    SAPI
    preventing external data from being imported correctly was fixed in HEAD
    and 5_1 [Edin]
  • FastCGI bug #37205
    (Serving binary content/images fails with “comm with server aborted” FastCGI err)
    was fixed in HEAD and 5_1 [Dmitry]
  • In ext/iconv, bug
    #37176
    (iconv_strpos() fails to find a string) was fixed in HEAD
    and 5_1 [Moriyoshi Koizumi]
  • PDO_ODBC bugs #35552
    (access violation on any invalid odbc query), #36632 (SQLSTATE[] unknown error using MSAccess
    and write SQL with 0 matching records) and PECL #6544 (Wrong
    syntax in config.m4) were fixed in the PHP_5_1 branch (only) [Wez]

– but mostly the CVS news this week was all about the PHP 5.1.3 release. Ilia,
as Release Master for the PHP 5.1 series, rolled the 5.1.3 tarball on April 26th,
just before Dmitry committed something into CVS with the message “Revert wrong fix”.
Dmitry came up with “a proper fix for bug #37205” the next morning, and Ilia asked whether this meant the
source needed re-tagging for 5.1.3 with the new FastCGI patch included. Dmitry
agreed that it did.

At the end of the week PHP 5.1.3 – although available as a tarball for testing
purposes – was still not available on php.net downloads page.

Following the rolling of the tarball, Wez went ahead and committed two new SSL
context options in ext/openssl; capture_peer_cert and
capture_peer_cert_chain. He wrote that, if TRUE, the peer
certificate/peer certificate chain would be captured and made available as SSL
context variables. The certificates are exposed as x509 certificate resources and
can be inspected using the existing extension functions, allowing extended
validation.

Short version: PHP 5.1.3 will be out in the wild next week.