In PHP, does an array’s internal pointer make up its value?

Asked

Viewed 327 times

11

Let us consider the following array:

$a = [1, 2, 3, 4, 5];

As we make $b = $a we create a copy of array, so much so that changes made to one of the arrays will not affect the other.

However, I noticed that the position of the array is also copied. If before we set $b as a copy of $a we change pointer position:

$a = [1, 2, 3, 4, 5];

next($a);  // Move o ponteiro interno uma posição a frente

$b = $a;

When checking the current value of $b, we will have the value 2, because the pointer is in the second position:

echo current($b);  // 2

As we move the pointer of $a before the copy, the array $b will be generated already with the new pointer position; but if the pointer position is changed after copying, the change does not affect $b.

Therefore, the position of the inner pointer of a array composes its value, copied together when the object is copied? Would that be expected? My impression was that when copying a array I would just copy the values, reset the pointer position.

  • 5

    Yes, there is an interene value in the array that says which element it is pointing to, i.e., when copying the array it must copy yes the value of the current pointer. See more information here and here.

  • @fajuchem has already answered the question!

  • @Ivanferrer He commented on a possible response, but has not yet responded.

  • @fajuchem would be interesting to formalize as a response, taking the relevant part of the links

2 answers

1

One way to visualize what the internal workings of the array type are is to rely on the interface Iterator, a very simple implementation for this model would be:

<?php

class MyArray implements \Iterator
{
    /**
     * Valores úteis da array
     *
     * @var mixed[]
     */
    private $data = array('foo', 'bar', 'baz');

    /**
     * Representa o ponteiro interno
     *
     * @var int
     */
    private $key = 0;

    public function current()
    {
        return $this->data[$this->key];
    }

    public function key()
    {
        return $this->key;
    }

    public function next()
    {
        $this->key++;
    }

    public function rewind()
    {
        $this->key = 0;
    }

    public function valid()
    {
        return isset($this->data[$this->key]);
    }
}

Note that the internal pointer is an integral part of the object, but it is not possible to access it directly because it is an attribute private.

Following this idea, whenever you make a copy of an object based on this class, the internal pointer will also be copied without undergoing any changes and the appearance you described in the question is in fact what is expected.

If it is really necessary for the pointer to be reset when copying the object, you can implement a class similar to the one I demonstrated and add the magic method to it __clone():


class MyArray implements Iterator
{
    // ...
    public function __clone()
    {
        $this->rewind();
    }
}

When making a copy of the object, it will be necessary to use the instruction clone:

<?php

$a = new MyArray();
$a->next();

$b = clone $a;

echo sprintf("a: %s\nb: %s", $a->current(), $b->current());

and the result:

a: bar
b: foo
  • It’s an interesting approach. I would know how it works with array native, which does not implement Iterator? I even analyzed the C implementation of PHP and found the struct representing the array internally representing the pointer to the current position, only I did not find where it copies this pointer when I reassign the array to another variable.

  • Unfortunately, I’m not good enough of C to tell you where the magic happens. But I believe it works exactly the same way as Iterator, what changes is the paradigm POO for functional.

-1

The answer is yes. But it has nothing to do with the value itself, the fact is that the position of the key is that it contains the value. The pointer only tells you what the current key is, and if this key contains the current value, then, yes, it is composing its value. Whenever using an array, part of the premise that the position or key is who has value, and nothing else, the array is basically a collection of keys that have values.

Variable association is an exact copy of its origin... so it is evident that yes.

Even if there is one last interaction, which changes its origin behavior, internally it is a new structure, in this sense you will be copying this new structure, with its new conditions and rules, it has been mutated, and now this is also part of the array scope.

Every array has an internal pointer to the "current" element, which is initialized to point to the first element inserted in an array.

The function Current() simply returns the element of the array to which this internal pointer is pointing. It does not move the pointer at all. If the internal pointer is pointing beyond the end of the list of elements or the array is empty, Current() returns FALSE.

end() - Makes the internal pointer of an array point to its last element
key() - Returns a key from an array
each() - Returns the key pair/current value of an array and advances its cursor
Prev() - Back the internal pointer of an array
reset() - Makes the internal pointer of an array point to its first element
next() - Advance the internal pointer of an array

When defining a common array with values, no keys: $array = ('valor 1', 'valor 2', 'valor 3'), by default, when we do not define the keys, it is interpreted by number 0, 1, 2... in this way, internally it is the same thing, it has a pre-established order of inclusion of the keys/values:

$array = array(
0 => 'valor 1',  /* internamente : -> current é 'valor 1', 
                    que é chave 0 (pois é o primeiro valor a 
                    ser inserido no array  */
1 => 'valor 2', 
2 => 'valor 3'
);

When using the method: next($array), for example, you are internally modifying the position of the current (Current) value inserted in the array, to the next, but the key and the value remain in the same place, if you sort it, you will notice that the order of the keys nay changed nothing visually:

sort($array);
print_r($array);

Exit:

Array
(
    [0] => valor 1
    [1] => valor 2
    [2] => valor 3
)

$array[1] that holds key 1, and value 'valor 2'. That is, using the method current($array), you will be getting the key and value of the new "internal position".

  • I don’t know if I understand the answer, but there seems to be a confusion between the value of the object itself and the value stored in array. You can better detail how the copy process of this built-in pointer works when doing the assignment?

  • There is no object value, because array is not an object... array and objects are distinct things. Come on, what you have in the array is just a weight index, which is defined internally in the array method, and this can only be modified by the methods I put in the answer.

  • Array is an object in memory. I’m talking low level, pointers, not high level. The question deals with why/how the value of this pointer is copied together with the array object (forget PHP object and think of computation object itself). Most of the answer talks about how to manipulate the value of this internal pointer, but that’s not the focus of the question.

  • What is your question after all? I have answered, even at a low level, this binary value is changed internally. Only through these methods. keys and values do not change places. Through these methods.

  • 1

    The expected response is a demonstration of why the pointer that indicates which is the current position composes the value of the array object that is copied during the assignment.

  • But this is in my answer: (...Every array has an internal pointer to the "current" element, which is initialized to point to the first element inserted in an array.). This is the reason.

  • Yes, but this information was already known. The question is about the behavior of this pointer during the copy of the object. Just this, not about how to manipulate him.

  • It’s also in the answer, the behavior... When using the method: next($array), for example, you are internally modifying the position of the current (Current) value inserted in the array, to the next, but the key and value remain in the same place:

  • You know the hot potato... it’s in the hands of whoever you want it to be... it doesn’t change the fact that you are who you are.

  • So this is about how these functions deal with the pointer, not how PHP operates during copying. The question is much simpler than what you’re trying to answer. The answer would be "Yes, because during the copy of the object PHP will do... copying also the pointer". No need to talk about how the developer can change the position.

  • I see that the discussion is getting out of hand, so I will leave. I keep thinking that the answer did not answer my question. If you think so, you can keep it smooth. It’s always more content for the community. Thank you for trying.

  • 2

    What @Andersoncarloswoss wants to know is whether the internal pointer of are talking makes up the "object" of the array, that is, whether or not it is copied when the array is copied. What if it should be like this or not!? Like the array is composed by its elements + an internal pointer?

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.