Hi Internals,
especially with (radical) userland API changes coming up in PHP6,
might I suggest something like a ifdef feature which turns blocks of
code into comments?
This would allow framework authors to provide backwards compatibility
with "older" PHP versions while being able to take advantage of new
PHP features.
In theory, it could also be supplied as "update" to the already
existing minor versions (5.4,5.5 and 5.6) so that these versions can
also use the new code.
especially with (radical) userland API changes coming up in PHP6,
might I suggest something like a ifdef feature which turns blocks of
code into comments?
Why is that needed? PHP checks function names and arguments at runtime, not compile-time. You can already do this:
if (some_condition) {
PHP_5_6_function();
} else {
PHP_5_2_function();
}
--
Andrea Faulds
http://ajf.me/
Hi,
especially with (radical) userland API changes coming up in PHP6,
might I suggest something like a ifdef feature which turns blocks of
code into comments?Why is that needed? PHP checks function names and arguments at runtime, not
compile-time. You can already do this:if (some_condition) {
PHP_5_6_function();
} else {
PHP_5_2_function();
}
This breaks if you use new syntax features like the array shortcut
$var=[];, traits or similar.
Marco
$var=[];, traits or similar
Neither of these is something you'd really do a version switch around, as it would lead to a lot of duplicated code, that needs to be kept in sync. Of the top of my head there are three situations where branching based on the PHP version is necessary/useful:
-
I'm using an API which is deprecated/unavailable in the newer version I support but the replacement is not available in the older version.
-
I can improve performance, security or functionality by using some new native function that is not available in the newer version. (For example hex2bin only being available in PHP >= 5.4)
-
Working around bugs in specific PHP versions.
It would be incredibly unlikely for any of these to involve recently improved syntax. Also note that from what I'm understanding the OPCache Optimizer will actually remove some branches which can't be called, so there's some chance that there will be no runtime performance impact at all by these checks.
Best regards
Rouven
This breaks if you use new syntax features like the array shortcut
$var=[];, traits or similar.
Right, but those aren’t problems. I can’t see anyone willingly writing:
#ifdef PHP_5_4
$a = [1,2,3];
#else
$a = array(1,2,3);
#endif
They will simply write:
$a = array(1,2,3);
For traits, again, it’s unlikely people will want to write two sets of code and deliberately duplicate things. They’ll simply just not use traits.
The only case where what you’re saying makes sense is where features are removed in favour of alternatives, and I can’t see that happening for any syntactic features.
--
Andrea Faulds
http://ajf.me/
This breaks if you use new syntax features like the array shortcut
$var=[];, traits or similar.Right, but those aren't problems. I can't see anyone willingly writing:
#ifdef PHP_5_4 $a = [1,2,3]; #else $a = array(1,2,3); #endif
They will simply write:
$a = array(1,2,3);
For traits, again, it's unlikely people will want to write two sets of code and deliberately duplicate things. They'll simply just not use traits.
The only case where what you're saying makes sense is where features are removed in favour of alternatives, and I can't see that happening for any syntactic features.
--
Andrea Faulds
http://ajf.me/
I'm not necessarily in favour of this idea as a core feature but to
give a more practical example of how this could be useful: generators
can give considerable efficiency gains where previously more resources
would have been consumed by a process yielding values over time.
Before 5.5, generator code would cause a parse error.
Imagine the following somewhat contrived example:
function some_func() {
$fp = fopen('some_file.ext');
$result = array();
while (false !== $line = fgets($fp)) {
$result[] = $line;
}
return $result;
}
foreach (some_func() as $foo) {
// do stuff
}
Imagine that some_func() is only ever used in the context of a
foreach. For BC reasons, we have to keep this API. Since 5.5, we could
use a generator (yes, we could use an iterator, I said it was
contrived :-P), but we need to provide BC with older PHP versions:
function some_func() {
$fp = fopen('some_file.ext');
#if PHP_VERSION
>= 5.5.0
while (false !== $line = fgets($fp)) {
yield $line;
}
#else
$result = array();
while (false !== $line = fgets($fp)) {
$result[] = $line;
}
return $result;
#endif
}
As another example, imagine a heavy data processing routine that uses
goto for performance reasons, but before 5.3 would fall back to using
private methods instead:
#if PHP_VERSION
>= 5.3.0
private function partOfRoutine()
#else
partOfRoutine:
#endif
{
/* stuff */
#if PHP_VERSION
>= 5.3.0
anotherPartOfRoutine();
#else
goto anotherPartOfRoutine;
#endif
}
Another advantage for performance-minded people is that a
pre-processor is a one-shot deal, whereas runtime checks are
potentially performed a few hundred times a second with the exact same
result every time for ever more.
However the thought occurs that, while potentially useful, a
pre-processor of this nature could easily be done with a userland
implementation, a composer dependency and a composer
after-install/after-update script...
Thanks, Chris
Imagine that some_func() is only ever used in the context of a
foreach. For BC reasons, we have to keep this API. Since 5.5, we could
use a generator (yes, we could use an iterator, I said it was
contrived :-P), but we need to provide BC with older PHP versions:function some_func() {
$fp = fopen('some_file.ext');
#ifPHP_VERSION
>= 5.5.0
while (false !== $line = fgets($fp)) {
yield $line;
}
#else
$result = array();
while (false !== $line = fgets($fp)) {
$result[] = $line;
}
return $result;
#endif
}
Ah, that’s a good example.
However the thought occurs that, while potentially useful, a
pre-processor of this nature could easily be done with a userland
implementation, a composer dependency and a composer
after-install/after-update script…
Right. You could also just use include or require to load a file with a PHP 5.6 implementation or a PHP 5.5 implementation, conditionally, though for differences which are just a few lines, this would be inconvenient.
Andrea Faulds
http://ajf.me/
Hi Chris,
I'm not necessarily in favour of this idea as a core feature but to
give a more practical example of how this could be useful: generators
can give considerable efficiency gains where previously more resources
would have been consumed by a process yielding values over time.
Before 5.5, generator code would cause a parse error.
[...]
Another advantage for performance-minded people is that a
pre-processor is a one-shot deal, whereas runtime checks are
potentially performed a few hundred times a second with the exact same
result every time for ever more.However the thought occurs that, while potentially useful, a
pre-processor of this nature could easily be done with a userland
implementation, a composer dependency and a composer
after-install/after-update script...
Yep, I had code like yours in mind when asking.
One problem of doing it with Composer, for example, is that it is not
compatible with stuff like WordPress plugins - I personally would
really like to be able to use "modern" features while still allowing
for all those myriads of version combinations provided by web hosts.
One idea to do this with a "polyfill" could be (expensive)
preprocessing with file_get_contents()
and eval(), but I think that
step would offset any performance gains by using goto, generators etc.
Marco
--
Marco Schuster
IT-Beratung, Web Development
Blütenstr. 23
80799 München
Hello Internals.
This really sounds strange. Why? Because you already have all the tools in
userland to do all that since like PHP 4.
You have "function_exists"
http://lv.php.net/manual/en/function.function-exists.php , you have
"phpversion" http://lv.php.net/manual/en/function.phpversion.php, you have
PHP_VERSION_ID
constant (details about the constant are in
http://lv.php.net/manual/en/function.phpversion.php too), you have
version_compare http://lv.php.net/manual/en/function.version-compare.php
Sometimes you just need to look up the actual manual...
Hi,
On Sun, Mar 9, 2014 at 12:41 AM, Arvids Godjuks
arvids.godjuks@gmail.com wrote:
Hello Internals.
This really sounds strange. Why? Because you already have all the tools in
userland to do all that since like PHP 4.You have "function_exists"
http://lv.php.net/manual/en/function.function-exists.php , you have
"phpversion" http://lv.php.net/manual/en/function.phpversion.php, you have
PHP_VERSION_ID
constant (details about the constant are in
http://lv.php.net/manual/en/function.phpversion.php too), you have
version_compare http://lv.php.net/manual/en/function.version-compare.phpSometimes you just need to look up the actual manual...
This helps against API-layer changes, but once you try out new syntax
features (not just yield/goto, but I have stuff like named parameters
or that argument unpacking stuff in mind), then you need a parse-time
filter so that older PHP versions do not cough up on syntax errors.
Marco
This helps against API-layer changes, but once you try out new syntax
features (not just yield/goto, but I have stuff like named parameters
or that argument unpacking stuff in mind), then you need a parse-time
filter so that older PHP versions do not cough up on syntax errors.
Try out? Why do you need to support multiple versions of PHP when testing some new feature?
If you have to support the old version anyhow, what advantage do you gain by shipping the same code twice, just one version a bit prettier?
Why would I want to do
#ifdef version >= 5.6
function(...$array);
#else
call_user_func_array('function', $array);
#endif
instead of just
call_user_func_array('function', $array);
I really don't want to come across as hostile, but this seems poorly thought out. We all like to play with the new shiny, but I don't see such a feature benefitting the quality of the code out there.
Best regards
Rouven