2

I thought I have some basic PHP skills, at least enough to do the development for simple applications, but I found myself to be stuck with very basic array operation problem.

I have results of curl operation set on $results variable. For easier code, (blame me it is too primitive.), I have used the basic loop to loop through $results variable to produce the favored results for my next operation.

$data = array();
for ($i = 0; $i < count($results); $i++) {
    $row = $results[$i];
    $atom->objectId = $row['objectId'];
    $atom->username = $row['username'];
    array_push($data, $atom);
}
var_dump(json_encode($data));

Sample data:

{ 
  [0] => { ["objectId"]: "12345", ["username"]: "user1" },
  [1] => { ["objectId"]: "12567", ["username"]: "user2" },
  [2] => { ["objectId"]: "12789", ["username"]: "user3" },
  [3] => { ["objectId"]: "13579", ["username"]: "user4" }
}

You can simply figure out the expected output, but the real output turned out to be:

[
  { "objectId": "13579", "username": "user4" }, 
  { "objectId": "13579", "username": "user4" },
  { "objectId": "13579", "username": "user4" },
  { "objectId": "13579", "username": "user4" }
]

Any idea why this is giving me ridiculous result? Any help would be appreciated. Thanks in advance.

4
  • 1
    Just check that your sample data is really what you claim it is here? i.e. print it out in your code. Commented Mar 18, 2014 at 0:23
  • and what if you use $data[] = $atom instead of array_push? BTW it should work faster too. Commented Mar 18, 2014 at 0:23
  • I tried $data[]=$atom as well. You are right, it should work faster, as far as I checked on the internet. However, I have written array_push in this question in order to make question more understandable and searchable. So in a word, $data[]=$atom gives me the same weird result. Commented Mar 18, 2014 at 0:43
  • @david-d-c-e-freitas, I am a mainly javascript guy and I have written those sample data and output in my favor format, thinking the format really doesn't matter. It really doesn't matter, does it? Commented Mar 18, 2014 at 0:46

2 Answers 2

5

What your code is doing right now:

Every loop, it is changing the properties of one object, and appending the object's reference (pass by value, but the value is the reference.) to the $data array, so you have 4 spots in the $data array pointing to only one object. Each time you loop, you change the value, the last time it is assigned is on the last value. This is why all your values are the same.

What you want to do:

Create a new object every iteration with the data and point to the new object each time.

Other solution:

If you just want an array containing the values and not a reference to an object(like your output), you could try this:

$data = array();
for ($i = 0; $i < count($results); $i++) {
    $row = $results[$i];
    $data[$i]['objectId'] = $row['objectId'];
    $data[$i]['username'] = $row['username'];
}
var_dump(json_encode($data));
Sign up to request clarification or add additional context in comments.

2 Comments

You were on the right track, your solution works but the explanation is not 100% correct.
Yeah sorry, your explanation was right, it was just very confusing, even to me, and I knew what was going on...
1

Akshay2598's answer might work out, but the explanation isn't quite right. This has nothing to do with pass-by-value or pass-by-reference: no variables are being passed.

The reason you are getting the same results is indeed related to references. When you initially create an object, the $atom variable isn't set to the object itself, but to a reference to that object, a memory address.

What you basically are doing, is changing the properties of the object $atom is pointing to, and later add that reference to that object to your array.

Because you never assign a new object to $atom, it'll keep pointing to the same object. Because it'll keep pointing to the same object, you will keep adding more references to the same object to your array.

To fix this you can simply do:

$data = array();
for ($i = 0; $i < count($results); $i++) {
    $atom = new Atom(); // Add this bit to assign a new object for $atom to point to
    $row = $results[$i];
    $atom->objectId = $row['objectId'];
    $atom->username = $row['username'];
    array_push($data, $atom);
}
var_dump(json_encode($data));

10 Comments

Actually this is what I was looking for, thanks for your attention, Jeroen. I will try this code snipetts tomorrow and will let the publicity know what the real answer is for my question.
I didn't mean for sure.
@JeroenBollen It does have to do with pass-by-value and pass-by-reference because you are passing the object to array_push()
@Alfred I had the same answer, just not the code for it. :P
@Akshay2598 If it was pass by reference like you said that'd mean that when you create a new object and put it inside $atom it'd still result in the same output for every array element.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.