After complaining about the tumultuous task of writing the keyword function over and over, I asked someone about an easier way. The person said that PHP is going to have arrow function syntax similar to es6.
const foo = (x, y) => {
return x + y;
};
As I continued to look into this, I have not been able to find many examples online.
Can someone of the right caliber please expound upon this?
At this point, I am also really interested in how this would fit into the OOP aspect of PHP.
Original answer from February 2018:
This appears to be the syntax described in https://wiki.php.net/rfc/arrow_functions. It does have an experimental implementation.
In the arrow functions proposal, it is mentioned that it's an alternative to the "short closures" proposal, https://wiki.php.net/rfc/short_closures
As of February 2018, the current versions of PHP are 7.1.4 / 7.2.2.
I can't find any confirmation that either proposal has been approved. The former is in the "Under Discussion" state, the latter is "Declined / Withdrawn in favor of http://wiki.php.net/rfc/arrow_functions". I think it's too soon to know whether it will be adopted in any future version of PHP.
Update December 2019:
The feature has been released in PHP 7.4, according to https://www.php.net/manual/en/migration74.new-features.php
Arrow functions provide a shorthand syntax for defining functions with
implicit by-value scope binding.
<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
But the usage has not been updated yet in the PHP manual page about Anonymous Functions
Here's a blog going into detail: https://stitcher.io/blog/short-closures-in-php
Yes. The new RFC has been accepted for PHP 7.4 https://wiki.php.net/rfc/arrow_functions_v2
Based on RFC for PHP 7.4 code could look like
$users->map(
fn($user) => $user->first_name.' '.$user->last_name
);
instead of
$users->map(function($user) {
return $user->first_name.' '.$user->last_name;
});
Related
My apologies if stackoverflow isn't the right place for this. I'm just trying to figure out why the PHP team would vote No on this RFC: https://wiki.php.net/rfc/skipparams
Basically it is suggesting the following code be valid:
function foo($a, $b = "2", $c = "3") {
echo "$a $b $c";
}
foo(1, default, 5); // prints "1 2 5"
This looks like a great idea to me... why reject it?
Because named_params is a better solution (though this RFC has stalled for 3 years now).
htmlspecialchars($string, default, default, false);
// vs
htmlspecialchars($string, double_encode => false);
Reasons quoted from the php-internals mailing list:
Basically, even though not having to specify the default-value for some
parameters could be useful in some situations, this approach doesn't
feel right and we would really prefer something like named-parameters
(even if this RFC is not incompatible with named-parameters and they
most likely won't make it for PHP 7.0).
One of the downvoters, #philstu, also blogged,
While I am glad Stas went to the trouble of making this, I am so much more glad that people downvoted it. It’s a band aid solution to named parameters, and I really hope we see them for later versions of PHP 7.x.
Derick Rethans has an old article that says:
Please do note that it is harmful not to accept a reference from a
function that returns a reference. In some cases, PHP will get
confused and cause memory corruptions which are very hard to find and
debug. It is also not a good idea to return a static value as
reference, as the PHP engine has problems with that too. In PHP 4.3,
both cases can lead to very hard to reproduce bugs and crashes of PHP
and the web server. In PHP 5, this works all a little bit better. Here
you can expect a warning and it will behave “properly”.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
By that, I mean this:
function &GetRef(&$array){
$item =& $array[0];
return $item;
}
$array = array(0, 1, 2);
$item =& GetRef($array); /* Normal usage of the function using assign by reference
also known as "accepting" the reference. */
$item = GetRef($array); /* Notice that here we didn't assign by reference.
Are we allowed to ignore the returned reference
and simply do normal assignment? */
The PHP Manual states:
Unlike parameter passing, here [return by reference] you have to use &
in both places - to indicate that you want to return by reference, not
a copy, and to indicate that reference binding, rather than usual
assignment, should be done for $myValue.
It doesn't explicitly say that we must accept the returned reference.
Does it mean that we are free to ignore returned references?
As discussed in the comments, you should generally ignore at least that section in the linked article, if not the entire thing.
The article talks about references in the context of PHP 4.3, released in December, 2002 and EOL'd at the end of 2007. PHP 4 should never be used today. As a general rule, when it comes to learning about working with PHP, you should not trust any article that targets PHP versions older than 5.2 (as of mid-2013).
PHP 5.0 features Zend Engine 2, a new virtual machine on which PHP runs. This is where references are implemented. 5.1 introduces some backwards-incompatible changes with regard to manipulation of return values. 5.3 introduces real garbage collection and deprecates both call-time pass-by-reference and assigning new by reference. These important changes are not addressed by that prehistoric article.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
Yes. Modern PHP versions have no problem with discarding the return value of any function, reference or not. If you encounter behavior that seems to contradict this expectation, create a reduced test case and file a bug with the PHP maintainers.
Also, think twice before using references in your code. Passing around references will not save time, will not save memory and will not increase performance except in rare cases. Use them sparingly to keep complexity under control.
We recently had a disaster and had to move our php web application from PHP Version 5.2.6-1+lenny16 to PHP Version 5.3.3-7+squeeze15 and found a seemingly important difference.
In our application, there were instances where we incorrectly called an array's index using object syntax:
echo $array->index;
However, 5.2.6 seemed to forgive this, and correctly treat it as if $array['index'] was written.
Upon further testing, what 5.2.6 is specifically doing is disagreeing with 5.3.3 as to whether $array->index is empty();
Here is the test code I've run on both servers:
<?php
echo phpversion() . '<br>';
$array = array(
'x' => 1,
'y' => 2
);
if (!empty($array->x))
{
echo "not empty";
}
else
{
echo "empty";
}
?>
Here are the two different outputs:
5.2.6-1+lenny16
not empty
5.3.3-7+squeeze15
empty
Naturally, there are now a few outbreaks of broken functionality because we were never alerted to these errors during development. Is there a way we can configure php 5.3 to permit this incorrect syntax while we take a bit more time to find all the incorrect instances of it?
I don't think it's a configuration issue, is it? Was something changed in the way empty() works in between versions?
I just have put your example code to a general test across PHP versions (test) and it shows that you are correct, there are differences:
From PHP 5.0.0 up to 5.2.11 (and also early 5.3.0 to 5.3.1), this "undefined property" was reported as not empty which does qualify as a flaw or bug.
The related change in 5.2.12 (17 Dec 2009) was (ref):
Fixed bug #50255 (isset() and empty() silently casts array to object). (Felipe)
Technically this is not a backwards incompatible change from PHP 5.2 to 5.3 because it was a flaw in both branches and also fixed in both. Those are harder to spot if you migrate, because the standard migration guide does not cover them. Instead you need to go through the changes of the software and look for notes and references to tickets.
So to answer your question: This is a configuration issue because the PHP version used counts as configuration. You changed the configuration and then you had the issue.
Also as the report shows, this is limited to empty() and isset(), not general object/array access. As you can imagine, if that would have been the case, you would have found much more reference about it.
I build a (so far) pretty nice templating mechanism for a cms. Now I also added a set of developer tools to the UI for a better UX during development. The only problem I'm left with is that I have to use create_function to add my templates, and therefore have lambda_xyz instead of meaningful template or function names.
Question: Is there a way/work around to give meaningful names to lambda functions in php?
This reference might be able to point you in the right direction:
http://php.net/manual/en/functions.anonymous.php
Anonymous functions require PHP 5 >= 5.3.0
$function_name = 'meaningful_name';
// PHP 5 >= 5.3.0
$$function_name = function(){echo "I am connected to a meaningful name";};
// PHP 4 >= 4.0.1, PHP 5
$$function_name = create_function('', 'echo "I am connected to a meaningful name";');
// Then you can call your function like this
$meaningful_name();
If this isn't what you are looking for, can you update your question with what you are trying to accomplish in more detail?
In PHP, the following code is valid
$a=array(0);$a[0];
but that one is invalid:
array(0)[0]
What is the terminology corresponding to that behaviour? (has it anything to do with "dereferencing"?)
What is the motivation behind such a behaviour (besides user spite :-P)
I am looking for the general terminology, not necessarily the terminology associated with PHP.
(Other example: in MATLAB, the following is valid:
s = size(M)
s(0)
but that is invalid:
size(M)(0)
In both PHP and MATLAB, adding parenthesis does not help, i.e., (array(0))[0] and (size(M))(0) are both invalid)
That's called Array dereferencing, and will become available in PHP 5.4 (which is currently in alpha)
Note (thanks Gordon) : what you are asking for, with array()1, is not possible even in PHP 5.4 -- but it'll work for functions.
A couple of sources :
RFC - Function Array Dereferencing
Features in PHP trunk: Array dereferencing, when it was unsure whether there would be a PHP 5.4 or a PHP 6
And, last but not least, the (currently last) news on php.net : PHP 5.4 alpha1 released
Quoting that last news :
Here is an incomplete list of changes: - Added: Traits language
construct - Added: Array dereferencing support - Added:
DTrace support - Improved: Improved Zend Engine memory usage and
performance - Moved: ext/sqlite moved to pecl (sqlite3 support is
still built-in)
1.array() is not a function, even if it looks like one -- it's actually what PHP calls a language construct ; and those don't behave like functions.
This is called "array dereferencing" and it will be available for use in PHP5.4.