0

Not a bug, but wondering if someone can explain why this works... I'm attempting to display someone's name and cash position.

In index, I query the tables for the relevant values. This returns an array of rows, as I've found out.

I'm then passing an element of the array to another view (portfolio). For example:

render("portfolio.php", ["title" => "Portfolio", "positions" => $positions, "cash" => $cash[0], "name" => $name[0]]);

However, when I go to portfolio.php and attempt to do something like this:

<h2>You have $<?=$cash ?> to spend</h2>

It throws up an invalid 'array to string conversion'.

OK so maybe it's put the cash in an array. Let's try:

<h2>You have $<?=$cash[0] ?> to spend</h2>

Nope. There you get an 'undefined offset' error.

OK, so maybe we need to call the the 'cash' value in the 'cash' array?

<h2>You have $<?=$cash['cash'] ?> to spend</h2>

It works!

The question is why? In C, if we index an array, it returns a value of type [int, string, whatever], not another array. Why isn't that the case in PHP?

Is it because the rows themselves are associative arrays, and so I can never actually extract a single value? If that's the case, how would I just pass one variable out of an associative array?

1 Answer 1

1

You have answered yourself:

Is it because the rows themselves are associative arrays, and so I can never actually extract a single value? If that's the case, how would I just pass one variable out of an associative array?

CS50::query() returns a normal integer indexed array of rows and each row is an associative array. So, all things considered, the return value is an integer indexed array of associative arrays.

If you had tried to query for more than one user in the same query, let's say users with IDs >= 1 && <= 2, CS50::query would return something like (simplifying the fields a little):

$results = [["id" => 1, "cash" => 343, "username" => John], ["id" => 2, "cash" => 232, "username" => Mary]] 

So the first user, John, is $results[0], the second user, Mary, is $results[1]

If you query just for the ID 1, the return value would still be an array of rows, although with just one row in it, like this:

$results = [["id" => 1, "cash" => 343, "username" => John]]

So you'd still need to use $results[0] to get the associative array that represents the user John.

When you passed $cash[0] to your view, you thought you were passing something related to cash, but that was just the result of giving a misleading name to the array of associative arrays that I labeled as $results.

If you had used another name for the result value of the query (like $users for example), you'd be less confused.

You've done something like:

$cash = [["id" => 1, "cash" => 343, "username" => John]]

And when you do $cash[0] you're left with:

$cash[0] = ["id" => 1, "cash" => 343, "username" => John]

If you had given a better name like $users to your array, it would be clearer:

$users = [["id" => 1, "cash" => 343, "username" => John]]
$users[0] = ["id" => 1, "cash" => 343, "username" => John]
$users[0]["cash"] = 343

So to finally answer your question, how do you make sure you pass just one variable to the view? Like this:

$rows = CS50::query(.....)
$user = $rows[0]
$cash = $user["cash"]

or more concisely:

$rows = CS50::query(.....)
$cash = $rows[0]["cash"]

Done. This way $cash would represent the cash value, not an associative array.

6
  • Helpful - however, I can't imagine modern web programming uses 3 lines of code to pull a single variable from a database every single time. Seems wasteful / slow. Is PHP behind in this regard? Or how do modern web apps do this?
    – borker
    Dec 13, 2016 at 20:24
  • Well, that's the way CS50 staff decided to design the function! You can go there inside their library and alter the function to do something like: if array length == 1, return array[0] , right? So it's not the language, it's a design decision from someone. Dec 13, 2016 at 20:29
  • And I've used 3 lines to explain it in a cleaner way. You could just query and then do $cash = $rows[0]["cash"]. So it would be one additional line, not much trouble. Dec 13, 2016 at 20:36
  • Got it - not meaning to question the decisions. Just wondering if there are ways around this. Seems like I should just go tinker with the query return function... I just have a feeling I'd break it if I tried ;-)
    – borker
    Dec 13, 2016 at 20:48
  • I also don't like this stuff very much! In fact, I don't even like PHP in general and only learned it to the point I was required to finish this course! I prefer Python! Dec 13, 2016 at 20:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .