Query => Array => Output = PHP警告:非法偏移类型

I try to select mysql data, save them in a two dimensional array and output the data. I get the error message mentioned above for each column and row.

Could someone please point out my mistake. How can I get it to work?

This is the code:

// connect database
    $db_connection = new mysqli (MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB);

    // execute query 
    $query_result = $db_connection->query($sql_career);

    // save carrer data
    while( $row = $query_result->fetch_assoc() )
    {
        $career[]['id'] = $row['career_id'];
        $career[]['season'] = $row['career_season'];
        $career[]['matches'] = $row['career_matches'];
        $career[]['goals'] = $row['career_goals'];
        $career[]['team_name'] = $row['career_team_name'];
    }

    // output
    echo '<table border="1">';
    foreach ($career as $i)
    {
      echo "<tr>";
      echo "<td>". $career[$i]['id'] . "</td>";
      echo "<td>". $career[$i]['season'] . "</td>";
      echo "<td>". $career[$i]['team_name'] . "</td>";
      echo "<td>". $career[$i]['matches'] . "</td>";
      echo "<td>". $career[$i]['goals'] . "</td>";
      echo "</tr>";
    }
    echo "</table>";

If you have a successful query with rows, then just implode the rows and only loop once.

if (!$query_result = $db_connection->query($sql_career)) {
    // check error
} elseif (!$query_result->num_rows) {
    // no rows
} else {
    echo '<table border="1">';

        // I assume you have column headings in mind, add them here

        while($row = $query_result->fetch_assoc()) {
            echo "<tr><td>", implode("</td><td>", $row), "</td></tr>";
        }
    echo "</table>";
}

Or if you have an actual requirement for storing the resultset as a multidimensional array, you can use Miller's top voted comment in the manual.

for ($set = array (); $row = $query_result->fetch_assoc(); $set[] = $row);

from the above one-liner, you can apply the same "loop and implode" logic like this:

if (sizeof($set)) {
    echo '<table border="1">';
        foreach ($set as $row) {
            echo "<tr><td>", implode("</td><td>", $row), "</td></tr>";
        }
    echo "</table>";
}

Or you can write it all out:

echo '<table border="1">';
    foreach ($set as $row){
        echo "<tr>";
            echo "<td>{$row['career_id']}</td>";
            echo "<td>{$row['career_season']}</td>";
            echo "<td>{$row['career_team_name']}</td>";
            echo "<td>{$row['career_matches']}</td>";
            echo "<td>{$row['career_goals']}</td>";
        echo "</tr>";
    }
echo "</table>";

And if you want to manipulate the associative keys in advance, you can adjust your SELECT clause like:

SELECT career_id AS 'id', career_season as 'season', career_team_name AS 'team_name', career_matches AS 'matches', career_goals AS 'goals' FROM ...

Just Replace this code,

You had already used foreach ,that gave current array.

foreach ($career as $i)
    {
      echo "<tr>";
      echo "<td>". $i['id'] . "</td>";
      echo "<td>". $i['season'] . "</td>";
      echo "<td>". $i['team_name'] . "</td>";
      echo "<td>". $i['matches'] . "</td>";
      echo "<td>". $i['goals'] . "</td>";
      echo "</tr>";
    }

You can try this one...

while( $row = $query_result->fetch_assoc() )
{
    $career[] = $row;
}

// output
echo '<table border="1">';
foreach ($career as $i)
{
  echo "<tr>";
  echo "<td>". $i['id'] . "</td>";
  echo "<td>". $i['season'] . "</td>";
  echo "<td>". $i['team_name'] . "</td>";
  echo "<td>". $i['matches'] . "</td>";
  echo "<td>". $i['goals'] . "</td>";
  echo "</tr>";
}
echo "</table>";

While this is not the best practice, it does solve the warning problem that was my original question.

// save carrer data
$row_counter = 0;
while( $row = $query_result->fetch_assoc() )
{
    $row_counter++;
    $career[$row_counter]['id'] = $row['career_id'];
    $career[$row_counter]['season'] = $row['career_season'];
    $career[$row_counter]['matches'] = $row['career_matches'];
    $career[$row_counter]['goals'] = $row['career_goals'];
    $career[$row_counter]['team_name'] = $row['career_team_name'];
}

// output
echo '<table border="1">';
foreach ($career as $i)
{
  echo "<tr>";
  echo "<td>". $i['id'] . "</td>";
  echo "<td>". $i['season'] . "</td>";
  echo "<td>". $i['team_name'] . "</td>";
  echo "<td>". $i['matches'] . "</td>";
  echo "<td>". $i['goals'] . "</td>";
  echo "</tr>";
}
echo "</table>";

After some further tests with @mickmackusa proposal i came to the following solution. The output function is just for testing. The main focus is preparing and providing the data for a later useage.

function get_career($player_id) {

    // sql placeholder to save code here
    $sql_career = "...";

    // connect database
    $db_connection = new mysqli (MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB);

    if (!$query_result = $db_connection->query($sql_career)) {
        // check error
    } elseif (!$query_result->num_rows) {
        // no rows
    } else {
        for (
            $career = array (); 
            $row = $query_result->fetch_assoc(); 
            $career[] = $row);
    }

    return $career;     

} // function end

function output_career($player_id) {

    // function call, get career data
    $career = get_career($player_id);

    // output
    echo '<table border="1">';
    foreach ($career as $career)
    {
      echo "<tr>";
      echo "<td>". $career['id'] . "</td>";
      echo "<td>". $career['season'] . "</td>";
      echo "<td>". $career['team_id'] . "</td>";
      echo "<td>". $career['team_name'] . "</td>";
      echo "<td>". $career['country_name'] . "</td>";
      echo "<td>". $career['country_abbreviation'] . "</td>";
      echo "<td>". $career['league_name'] . "</td>";
      echo "<td>". $career['matches'] . "</td>";
      echo "<td>". $career['goals'] . "</td>";
      echo "<td>". $career['status_name'] . "</td>";
      echo "</tr>";
    }
    echo "</table>";

} // function end