MySQL says my 'Array' is not an array !? Please help

#1

I produced these 3 lines of code and expected it to have created an array with 4 columns and 16 rows

$conn = mysqli_connect('localhost','root','','sharediary';

$sql = "SELECT `tax_year`, `payment_number`, `company_name`, SUM(dividend_payable) FROM `shareholding` GROUP BY company_name, tax_year, payment_number WITH ROLLUP";

$records = mysqli_query($conn,$sql);

And indeed I can display the resuts in a browser using

while($row = mysqli_fetch_array($records))
echo "<tr>";
		echo "<td>".$row['tax_year']."</td>";
		echo "<td>".$row['payment_number']."</td>";
		echo "<td>".$row['company_name']."</td>";
		echo "<td>".$row['SUM(dividend_payable)']."</td>";
		echo "</tr>";
Et Cetera

within an html table

But then I needed to do some tweaking of the layout but this relied on $record being an array,
but it appears that MySQL does not think it is an array ??? Here is the story…

I googled around and found 4 methods to display the contents of an array
the first 3 viz. print_r, a user defined function based on print_r and vardump
told me that there are 4 columns and 16 rows which would be true,
but they did not display the contents of my supposed array.
When I tried a 4th method viz. a ‘for loop’ thus,

for ($i=0;$i<count($records);$i++) {echo $records($i);}

MySQL coughed up an error message …

Warning: count(): Parameter must be an array or an object that implements Countable in C:\xampp\htdocs\showonscreen2.php on line 76

So I tried this as a kind of debugging tool…
if (!is_array($records)) {echo “No, I’m not an array”;}
and it did indeed echo to screen the bad news “No, I’m not an array”

#2

$records is resource. Use mysqli_num_rows($records).

1 Like
#3

Relational databases are designed as being rows of columns, essentially two-dimensional arrays. However I have never heard of databases being referred to as arrays. It would be totally appropriate however for a language to contain database data in an array. Are you sure it is MySQL saying it is not an array? I assume it is PHP.

#4

In order to do this:

for ($i=0;$i<count($records);$i++) {echo $records($i);}

you must first download the results. as @igor_g said above, $records is effectively a pointer to a set of results, and you must extract the results from it. You could do something as easy as

$results = mysqli_fetch_all($records);
for ($i=0;$i<count($results);$i++) {echo $results[$i]['company_name');}

or something like it, keeping in mind that $results is a two-dimensional array, so you can’t just access $results[num].

2 Likes
#5

Dear Igor and dropsnoot,

Thanks for providing clues and details.
I see php has over 700 functions and recognising their practical uses is not easy.

I can now see that my 3 lines for connect, select, query produce a RESOURCE variable called $records,
until you mentioned this I had mistaken $records for an array.
I was surprised to discover that your solution for copying it’s contents to an array called $row is a one liner viz.

while ($row=mysqli_fetch_all($records))
{$content=$row;}

Now at last I’ve been able to ‘see’ the contents of my array using print_r, vardump and
an inner do while nested within an outer do while.

In coding the nested do while it dawned on me how different php is to dbIII+/BASICA.
Specifically, that a php array is not dimensional and doesn’t need to be defined
but is a dynamically allocated array of arrays!

This is a bit of a pain for me as the way I set the max/escape value on my 2 do while counters seems a bit lame viz.
count($content[0]) for the outer loop and
count($content[0][0]) for the inner loop

Is there a better way to discover the ‘dimensions’ of an array ?

ASIDE
Not knowing a basic fact about php is frustrating for newbies like me.
Overcoming this weakness is difficult because the on-line tutorials concentrate
on drip feeding instead of providing a helicopter view of the bigger picture.
It may help the next newbie to watch this guy as he tries to be more enyclopaedic.
‘clevertechie’ on youtube see …

#6

Not to discover the dimensions - count is the way to do that - but you can iterate through the array using foreach(), which can make things simpler:

foreach ($content as $key => $row) { 
   echo $row['company_name'];
}

Note that in this bit of code:

while ($row=mysqli_fetch_all($records))
 {$content[]=$row;}

the while() loop is redundant, and is making things worse for you. You are creating an array called $content, and then within an element of that array, you are putting the two-dimensional array that is returned by mysqli_fetch_all(), so you end up with another level of array that you don’t need. I suspect you are confusing it with:

while ($row=mysqli_fetch_array($records))
 {$content[]=$row;}

which would build up an array called $content, where every element contains a result row. But that’s what mysqli_fetch_all() does in a single function call.

1 Like
#7

Yes I wondered why a 3rd level with only 1 element had mysteriously appeared in my array.

And yes I was using that while…fetch_array as a model for my while…fetch_all

php certainly isn’t literal or intuitive !
Also old habits die hard. I keep thinking procedurally, processing records one by one instead of thinking in sets.

I’m currently looking at functions people have devised to determine the dimensions of an array. There seem to be a few ideas on stackoverflow, although how they work is not clearly explained.

#8

fetch_array fetches a row as an array.
fetch_all fetches all rows as an array of arrays.

I mean… it’s pretty literal.
What would you have called them?

1 Like
#9

An unspecified array does not have ‘dimensions’. It has a dimension - length.

[
[1,2,3],
[4],
[5,6,7,8,9,10]
]

Is a valid array declaration. You can’t define a size for a second dimension to the outer array.

If you’re specifically creating a rectangular array-of-arrays (Matrix), that is a user-defined constraint, not a language based one.

#10

Well, that’s OK too. Use your loop

while ($row = mysqli_fetch_array($records)) {
   // do whatever you like with the single-dimension array $row
   }

and handle each row / record one at a time.

Before you spend a lot of time doing that, why do you need the dimensions of the array?

#11

Dear m_hutley and dropsnoot,
You’ve given me a lot to think about and work with, thank you.
It’ll take me a few days to process it.

#12

Beware that PHP is not a new language and was originally created to make the interface between PHP and HTML web pages easier. Default sloppy undeclared types can now be overridden on a file wide basis by the following statement immediately after opening the PHP file:

<?php
declare(strict_types=1);

// also useful for local debugging
error_reporting(-1); // set maximum error reporting
ini_set('error_reporting', 'true'); display errors to screen

// try this and notice the error produced
ini_set('display_errors', true);
// Reason:
// without declaring strict types PHP has inbuilt "type juggling" 
// PHP takes a guess at the correct parameter type. 
// Guessing takes unnecessary processing time 
// which causes PHP to execute sluggishly.

// a couple of functions I frequently use are:
// count(...);
// get_type(...);
// is_int(...);
// is_array(...);
// is_bool(...);