Hi,
We have ongoing debates about the pull between BC behaviour and wanting
to tidy up / optimize performance etc. And often BC for bizarre coding
practices means that there is a performance penalty for everyone else.
A common way of doing this in C etc. is the use of compiler pragmas, but
such a change would in itself be not BC and INI parameters are too blunt
an instrument here as these are set at runtime or globally as a
PER_INI_USER etc. They can't impact the current source being compiled,
and they can't be conveniently namespace-specific.
I am suggestion the overload of constants of the form PHP_PRAGMA_XXX to
define PHP / Zend compiler / executor behaviours. This approach would be
BC to 5.3 unless, of course, the application already used PHP_PRAGMA_*
constants, in which case we might also need an allow_php_pragmas INI
parameter to globally enable/disable their interpretation.
As a small example:
namespace fred;
echo \strlen("DDDD");
generates different .
SEND_VAL 'DDDD'
DO_FCALL 1 $0 'strlen'
and different (slower) opcode if you omit the \
INIT_NS_FCALL_BY_NAME 'strlen'
SEND_VAL 'DDDD'
DO_FCALL_BY_NAME 1 $0
Whilst most sane projects would have a simple programming standard which
basically says "Don't override builtin functions", the odd one might for
various reasons allow this. This practice can significantly complicate
optimization for performance (see
https://bugs.php.net/bug.php?id=64346). I've seen namespace-based
project where all builtins have the explicit global \ prefix. IMO, yukkk.
So my suggestion is that we allow the programmer to issue a pragma to
inform compiler and runtime handling, so in this case for example,
namespace fred;
const PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS=false;
echo strlen("DDDD");
would define the constant fred\PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS and
also have the desired compile-time and runtime effect. Alternatively the
corresponding global constant \PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS could
be set to false and individual namespaces could set the corresponding
namespace constant to true.
Thoughts and comments?
Terry Ellison
I am suggestion the overload of constants of the form PHP_PRAGMA_XXX to
define PHP / Zend compiler / executor behaviours. This approach would be
BC to 5.3 unless, of course, the application already used PHP_PRAGMA_*
constants, in which case we might also need an allow_php_pragmas INI
parameter to globally enable/disable their interpretation.
we already have declare() for this purpose exactly.
http://docs.php.net/declare
it might make sense to use it for more things
--
Alexey Zakhlestin
CTO at Grids.by/you
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc
I am suggestion the overload of constants of the form PHP_PRAGMA_XXX to
define PHP / Zend compiler / executor behaviours. This approach would be
BC to 5.3 unless, of course, the application already used PHP_PRAGMA_*
constants, in which case we might also need an allow_php_pragmas INI
parameter to globally enable/disable their interpretation.
we already have declare() for this purpose exactly.
http://docs.php.net/declareit might make sense to use it for more things
Alexey, perhaps you missed the subtlety of my example:
namespace fred;
const PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS=false;
echo strlen("DDDD");
define()
is a runtime function implemented by
Zend/zend_builtin_functions.c:ZEND_FUNCTION(define). The constant which
is defines is not available until the DO_FCALL_BY_NAME opcode is itself
executed sometime after the compile of the current source completes.
const is a syntactic construct that can be intercepted in
zend_compile.c, etc., and therefore can condition the remainder of the
compile of that source. That's what pragmas do.
However, you are quite correct that:
define('fred\PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS', false);
include "some_other_php_file_in_namespace_fred.php";
...
would set the pragma for subsequent source scripts in the "fred"
namespace, if we adopted this convention.
Hope this helps. Terry
Hello,
I am suggestion the overload of constants of the form PHP_PRAGMA_XXX to
define PHP / Zend compiler / executor behaviours. This approach would be
BC to 5.3 unless, of course, the application already used PHP_PRAGMA_*
constants, in which case we might also need an allow_php_pragmas INI
parameter to globally enable/disable their interpretation.we already have declare() for this purpose exactly.
http://docs.php.net/declareit might make sense to use it for more things
Alexey, perhaps you missed the subtlety of my example:
namespace fred;
const PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS=false;
echo strlen("DDDD");
define()
is a runtime function implemented by
Zend/zend_builtin_functions.c:ZEND_FUNCTION(define). The constant which is
defines is not available until the DO_FCALL_BY_NAME opcode is itself
executed sometime after the compile of the current source completes.const is a syntactic construct that can be intercepted in zend_compile.c,
etc., and therefore can condition the remainder of the compile of that
source. That's what pragmas do.However, you are quite correct that:
define('fred\PHP_PRAGMA_ALLOW_OVERRIDE_BUILTINS', false);
include "some_other_php_file_in_namespace_fred.php";
...would set the pragma for subsequent source scripts in the "fred" namespace,
if we adopted this convention.Hope this helps. Terry
Looks like you misread Alexey's post. He was talking about declare
construct, not define()
function.
--
Regards,
Felipe Pena
I am suggestion the overload of constants of the form PHP_PRAGMA_XXX to
define PHP / Zend compiler / executor behaviours...
we already have declare() for this purpose exactly.
http://docs.php.net/declareAlexey, perhaps ... and mindfart following.
Looks like you misread Alexey's post. He was talking about declare
construct, notdefine()
function.
Apologies to you Alexey, as the point that you made was very relevant,
and my reply was a response to a misreading as Felipe as kindly pointed out.
Yes, extending declare would be a more elegant approach, but there is a
problem with an extended the declare syntax -- statements such as:
declare( allow_override_builtins = 1);
would generate additional compiler warnings when used on all previous
versions, and one of my aims was to enable B/C back to PHP 5.3 at least.
Also as declare is a pure compiler construct that only applies to the
source, there would be no equivalent mechanism for, say, defining a
namespace-wide set of pragmas without further modifying every source file.