0

I am a new user to PHP from C++/Python/Java. In PHP, there is a built-in array type, how can I prove the array is the same array after I insert a new object into it or a copy of the old one? In C++/Python/Java, I can use the object address, id(), or hashcode to test if the object is same, how can I do the same test in PHP?

<?php
    $a['0'] = "a";
    $a['1'] = 'b'; //here, $a is a new copied one or just a reference to the old?
?>

OK, I update my question, actually, there is no specific problem. I just want to know if the array object remains same before and after insert new values. In Python, I could make a test like this:

a = [1]

print id(a)
a.append(2)
print id(a)

BTW, this is the id() function manual in Python.

id(...)
    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory address.)

Code updated:

 # -*- coding: utf-8 -*-

a = [1, 2, 3]
b = [1, 2, 3]

print id(a)
print id(b)  //the id(b) is not same as id(a), so a and b has same content, but they both own their own values in the memory

c = a  // c is a reference to a 
c.append(4)
print c
print a  //after appending a new value(which means insert a new value to array), a has same value as c

so the problem is I can prove the memory layout by code in both C++/Python/Java, I want to make sure if I can do the same thing in PHP.

python
  • 1,870
  • 4
  • 24
  • 35
  • 1
    What problem do you need to solve? Your code doesn't give much hints... Sounds weird that C++ creates an entirely new array when you append an element to it :-? – Álvaro González Mar 29 '16 at 08:00
  • 2
    I don't know anything about C++ / python / Java, but in php the array is the same when you add a new element to it. – Epodax Mar 29 '16 at 08:00
  • 1
    PHP doesn't have any such mechanism. You'll have to describe what problem you're trying to solve for us to suggest an appropriate way to do it in PHP. – deceze Mar 29 '16 at 08:02
  • array would be same but we can't check here objects like in java or c++,i.t array[0].getId(); – Muhammad Nasir Rajput Mar 29 '16 at 08:02
  • 1
    i think he want to check that both `a` and `b` belong to the same array and for this he want to access the address of that array – Alive to die - Anant Mar 29 '16 at 08:02
  • 1
    http://stackoverflow.com/questions/5153528/how-check-memory-location-of-variable-in-php and then http://stackoverflow.com/questions/4194073/unexpected-observation-var-dump-of-an-array-is-flagging-referenced-elements – Alive to die - Anant Mar 29 '16 at 08:04
  • what `print id(a)` shows in python? – Alive to die - Anant Mar 29 '16 at 08:10
  • Out of interest... what language creates an entirely new array when adding elements to it? Unless the array is explicitly immutable, which PHP's are not. – deceze Mar 29 '16 at 08:19
  • @Epodax Proving the *content* is the same is not the same as proving the *container* is the same. Not sure why it makes a difference to the OP, but there you go... – deceze Mar 29 '16 at 08:23
  • @deceze So, OP wants to check that `$a` is the same container before and after a new value is assigned? (In case `$a` for X reason might turn into `$b` after a value has been assigned?) – Epodax Mar 29 '16 at 08:26
  • 2
    @Epodax Yes, OP seems to be worried that *the array* might change into a new instance for some reason. I'd argue that's the wrong thing to worry about in PHP. – deceze Mar 29 '16 at 08:27
  • @deceze I'm inclined to agree, I can't think of a instance where it would matter (if it did ever happen). Plenty of other (more vital) things to check / ensure is correct. – Epodax Mar 29 '16 at 08:31
  • 2
    @python Regarding all your Python examples: if you do the same thing in PHP, your arrays *will* differ. `$c = $a` would create a new array copy/instance. No need to prove it, it's a given. – deceze Mar 29 '16 at 08:34

3 Answers3

5

By default, In PHP only objects are assigned by reference. Everything else (including arrays) is assigned by value. The only way to have two variables that point to the same array is to explicitly set a reference with the & operator. The References Explained chapter gives a pretty good overview on the subject.

In the case of objects you can spot references rather easily, even with a simple var_dump():

$a = new DateTime;
$b = $a;
$c = clone $a;
var_dump($a, $b, $c);
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2016-03-29 10:18:28.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Madrid"
}
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2016-03-29 10:18:28.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Madrid"
}
object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2016-03-29 10:18:28.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Madrid"
}

Please note the #1 identifier shared by $a and $b.

With other types is not trivial at all. In the Spotting References section of the aforementioned chapter there's a user comment with some convoluted code you might want to check, though it's quite old.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
4

Yes, the array remains the same "object" (not what PHP calls it, but conceptually) when you modify its contents. Copies ("soft copies", copy-on-write copies) are only made when you

  • assign the array to another variable without using a reference (=&)
  • pass it into a function without reference
  • return it from a function without reference

(Which really is all the same thing: assigning it to another variable.)

deceze
  • 510,633
  • 85
  • 743
  • 889
  • What specifically would you like to see clarified in a code example? – deceze Mar 29 '16 at 08:20
  • In the context of OP's can you bind your statement with example code.Means how's anyone check programmatically your statements? – Alive to die - Anant Mar 29 '16 at 08:21
  • I suppose you could use low level debugger functions which dump the underlying zval structures, but there's no real userland API in PHP to do such things/it's not something PHP gives you access to/PHP explicitly isolates you from such specifics (pick you favourite statement). – deceze Mar 29 '16 at 08:25
3

In addition to what @Anant posted, see PHP Reference Counting which illustrates how variables are stored by PHP's runtime engine.

You'll see that even array members are references which could be pointed to (referenced) by other objects, arrays and variables. So two "identical" arrays that in C or Python might exist two different places in memory, PHP will store separately with references pointing to individual values.

If one of those values is pointed to by two non-reference variables, it will then make a new reference for the changed value and now each variable points to different references. This is Copy On Write optimization.

This post from StackExchange programming is also good. The first answer provides more good links: Why are array references rarely used.

Community
  • 1
  • 1
drew010
  • 68,777
  • 11
  • 134
  • 162