All,

We've been working in the last few days to test and tune the Coercive STH
patch.  I think the results are quite nice, and surprisingly better than
one might have expected.

Before diving into the results, we did update the RFC
(wiki.php.net/rfc/coercive_sth) - with the most notable difference being
allowing NULL->scalar conversions, for two reasons - it's not uncommon for
code to use 'null' as a way to denote an empty optional parameter to for
internal functions, and many internal functions seem to rely on that
behavior themselves.  It should be possible to alter this behavior in the
future by changing the internal functions to explicitly handle NULL inputs
as 'please use the default value' - but it's outside the scope of the RFC.

In addition, coercion from scalar to boolean is now limited only to
integer - which seems to be the most popular use case; Beforehand,
coercion was also allowed from float and string - but based on feedback
from Mike, we're reconsidering accepting strings again.

Another change being considered and not yet in the RFC is re-allowing
leading and trailing spaces for numeric strings (sorry Paddy.)

Now to the tests we ran.  The goal was to see what kind of effect the
changes to the internal function APIs had on real world apps with large
codebase.  The test methodology was done by placing a debugger breakpoint
on zend_error, to ensure no error gets lost in the ether of settings or
callbacks.  Here are the results:


Drupal homepage:  One new E_DEPRECATED warning, which seems to catch a
real bug, or at least faulty looking code:
  $path = trim($path, '/');  // raises E_DEPRECATED, as $path is boolean
false.
  return $path;

Drupal admin interface (across the all pages):  One  new E_DEPRECATED
warning, which again seems to catch a real bug - stripslsahes() operating
on a boolean.

Magento homepage (w/ Magento's huge sample DB):  One new E_DEPRECATED
warning, again, seems to be catching a real bug of 'false' being fed as
argument 1 of in json_decode() - which is expecting a string full of json
there.

WordPress homepage:  One new E_DEPRECATED warning, again, seems to be
catching a real bug of 'false' being fed as argument 1 of substr().

Zend Framework 2 skeleton app:  Zero  new E_DEPRECATED warnings.

Symfony ACME app:  Zero new E_DEPRECATED warnings (across the app).

 As I'm sure you know, the above tests invoke a huge number of lines of
code in total, handling filesystem ops, database ops and all sorts of
other things.  This is much of the mini test suite that we use to test
PHP's performance and compatibility (e.g. phpng, now PHP 7).  So while
this isn't proof that code in the wild isn't going to have more issues -
it's a pretty good initial indication regarding the level of 'breakage' we
can expect.  I'm putting breakage in quotes, as people would have several
years to fix these few issues, before the E_DEPRECATED becomes an error
(or an exception, if the engine exceptions RFC passes).

In terms of the test suite (.phpts), the changes cause approximately 700
extra tests to fail out of 13,700, in comparison to w/o the patch.
However, even though I didn't have a chance to go over all of them, it
seems that the vast majority of the failed tests are tests that were
intentionally designed to cover the exact parameter passing behavior,
rather than real likely real world code pieces.   A huge number of the
internal functions have this in their test suites:

$variation = array(
  'float 10.5' => 10.5,
  'float -10.5' => -10.5,
  'float 12.3456789000e10' => 12.3456789000e10,
  'float -12.3456789000e10' => -12.3456789000e10,
  'float .5' => .5,
  );

foreach ( $variation as $var ) {
  var_dump(readgzfile( $filename, $var  ) );
}

Which clearly isn't a very likely input to the size argument of
readgzfile().  All of these now trigger E_DEPRECATED warnings since we no
longer allow float->int conversions if there's no data loss.  For some
reason (perhaps a good one, not sure), we have virtually identical pieces
of code for dozens if not hundreds of internal functions that expect
integers - and these types of failures account for the (looks like vast)
majority of phpt failures.  Quoting Andrea from a couple of days ago on
this very topic, "to be fair, most of PHP's test suite basically just
tests zpp's behavior", which appears to be absolutely true.  The
real-world app tests are probably a much better indicator of the kind of
behaviors our users are going to see than our test suite is.

The takeaway from this seems to be that the approach of tightening the
existing rule-set and applying it to both internal functions and new
user-land code is viable, and does not cause the sky to come down falling.
Preliminary tests suggest it actually finds real potential problems.

More tomorrow.

Zeev

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to