Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outdated or Confusing Information on What References Are Not #2740

Open
Sunthief opened this issue Sep 4, 2023 · 3 comments
Open

Outdated or Confusing Information on What References Are Not #2740

Sunthief opened this issue Sep 4, 2023 · 3 comments

Comments

@Sunthief
Copy link

Sunthief commented Sep 4, 2023

From manual page: https://php.net/language.references.arent


The information on the mentioned page seems outdated or at least very confusing:

<?php
function foo(&$var)
{
    $var =& $GLOBALS["baz"];
}
foo($bar); 
?>

There's no way to bind $bar in the calling scope to something else using the reference mechanism, since $bar is not available in the function foo (it is represented by $var, but $var has only variable contents and not name-to-value binding in the calling symbol table).

You coud just use $GLOBALS["bar"] =& ... Unless I am misunderstanding something, for which I would apoligise, the problem of $bar not being available would only be the case if the defined function would be itself in another function scope. I am also unsure what is meant by

but $var has only variable contents and not name-to-value binding in the calling symbol table

as it is a reference, first to $bar and then to global $baz. This part is probably meant to make the distinction between references and c pointers clear?

@Girgias
Copy link
Member

Girgias commented Sep 4, 2023

The point is that trying to assign by reference a variable which is out of scope will not work.

The example could probably be expanded to have all the relevant information, as the result of this example should make clear what is implied here: https://3v4l.org/o5MHR

@damianwadley
Copy link
Member

as it is a reference, first to $bar and then to global $baz.

There is no such thing as a reference to a variable. That's not how they work.

Check the PHP Internals Book for more information. It's not exhaustive on the matter, but the most important point there is what it says at the very beginning of the "Reference semantics" section:

Before going into the internal representation of PHP references, it may be helpful to clarify some common misconceptions about the semantics of references in PHP. Consider this basic example:

$a = 0;
$b =& $a;
$a++;
$b++;
var_dump($a); // int(2)
var_dump($b); // int(2)

People will commonly say that “$b is a reference to $a”. However, this is not quite correct, in that references in PHP have no concept of directionality. After $b =& $a, both $a and $b reference a common value, and neither of the variables is privileged in any way.

A "reference" is simply when the "common value" is being shared by multiple variables at once.

So regarding the documentation's example code,

  1. The $bar in the global scope and the $var parameter are two different variables that share a common value
  2. After the by-ref assignment, $var and the global $baz variable are two different variables that share a common value; the value that $var had before is still in use by the outer $bar, but it's not being shared with any other variables anymore

If the assignment was a normal assignment instead, the common value shared by both $var and $bar would be updated with a copy of the $baz value's data, It's similar to how this PHP code looks:

// normal assignment: copy the value's data to another value
$var->value->data = $GLOBALS["baz"]->value->data;
// $var->value and $baz->value are two different things, but now they have copies of the same data

// by-ref assignment: share the entire value with another variable
$var->value = $GLOBALS["baz"]->value;
// now $var->value and $baz->value are actually the same thing

@Sunthief
Copy link
Author

Sunthief commented Sep 5, 2023

Thanks a lot for your answers. I think I got what references are in PHP in general. I should have been more precise. I did not mean a reference to a variable, but to a value shared by two variables.
But the point I was trying to make is that $bar would be available in the function if you add it from the global scope. There is even an example exactly like this on the page before: https://www.php.net/manual/en/language.references.whatdo.php
I understand that the point of this specific page is to let readers know that references are not pointers in a C language sense, but the way it is done seems to be a contradiction or confusing at best. The same is true for the sentence I mentioned. I have no coding background in C, so it is not clear what is actually meant by name-value-binding.
So what I am advocating here is to make the information on this page less ambiguous and easier to understand for beginners.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants