Warning: Illegal string offset

3

I am trying to show in the report the result of a INNER JOIN of 3 tables, I save the 3 values in a array and I make a foreach to go through all the records, but the following error appears:

  

Warning: Illegal string offset 'Fleet'

     

Warning: Illegal string offset 'FullName'

     

Warning: Illegal string offset 'Description'

My foreach looks like this:

<?php foreach ($acessos as $acesso) : ?>
<tr>
    <td><?php echo $acesso['Frota']; ?></td>
    <td><?php echo $acesso['NomeCompleto']; ?></td>
    <td><?php echo $acesso['Descricao']; ?></td>
    <td class="actions text-right">
        <a href="Editar.php?Codigo=<?php echo $acesso['Codigo']; ?>" class="btn btn-sm btn-warning"><i class="fa fa-pencil"></i> Inserir Entrada</a>
    </td>
</tr>

This is code that queries the database:

function INNERJOIN (){

    $database = open_database();
    $found = null;

    $sql = "SELECT tblacesso.Codigo, tblfrota.Frota, tblpessoa.NomeCompleto, tbldestino.Descricao FROM tblacesso INNER JOIN tblfrota ON(tblacesso.FrotaID = tblfrota.Codigo) INNER JOIN tblpessoa ON(tblacesso.MotoristaID = tblpessoa.Codigo) INNER JOIN tbldestino ON(tblacesso.DestinoID = tbldestino.Codigo)";
    $result = $database->query($sql);

    if ($result->num_rows > 0) {
        $found = $result->fetch_assoc();
    }    
    close_database($database);
    return $found;
}

I used var_dump($acessos); to check the data type of my variable and the following result appeared:

array (size=3)
'Frota' => string '9999' (length=4)
'NomeCompleto' => string 'Jean C. Galhardi' (length=16)
'Descricao' => string 'Palmares' (length=8)//////
    
asked by anonymous 11.05.2017 / 20:29

1 answer

3

This publication should be a "duplicate" of some several, I do not know if I should answer this, because the answer is in the error itself.

What is happening is because foreach() is causing only one key to be accessed at a time.

You have this:

$array = ['Frota' => 9999, 'NomeCompleto' => 'Jean', 'Descricao' => 'Palmares'];

If you do this:

foreach($array as $valor){
     echo $valor;
}

The $item will be "9999" then "Jean" and then "Palmares" instead of an array.

In a summary, in the way I can explain in a simpler way , this function will cause it to get every key in the array, ie loop is by key, in this if you have three keys, each "time it runs" will get a value from the respective key.

To use as you want you need to make an array inside the other, like this:

$array = [
    0 => ['Frota' => 9999, 'NomeCompleto' => 'Jean', 'Descricao' => 'Palmares']
];

In this way the 0 => , that can be omitted or have another name , is the key, so using the same foreach will cause $valor to be an array Fleet, FullName, Description).

So, using this new array with this (you're using):

foreach($array as $item){
    echo $item['Frota'];
    echo PHP_EOL;
    echo $item['NomeCompleto'];
}

It will work normally, because it will get the value of the key 0 which is the array, this array will be accessed by $item['Frota'] for example.

If you do not keep array as is and only remove foreach , it will work normally.

Change this:

if ($result->num_rows > 0) {
  $found = $result->fetch_assoc();
}    

For this:

if ($result->num_rows > 0) {
  while($linha = $result->fetch_assoc()){
     $found[] = $linha;
  }
}    

The rest remains as this, this will create an array within the other, correcting the problem of foreach The only caution is that if not found it will return null , due to $found = null; .

Another option, if you are using Mysqlnd is to use:

if ($result->num_rows > 0) {
  $found = $result->fetch_all(MYSQLI_ASSOC);
}  
    
11.05.2017 / 21:01