2
votes

I have a problem with foreach I have been wrestling with for a long time. I'm not new to the concept, but I'm getting strange results, and I don't know why. I'm using php, MySQL, Active Record, and CodeIgniter. I am trying to echo all the comments of a news peice. The current version below is the closest to working. It gives me the earliest comment four times. When I go into the model and change asc to desc, I get the most recent comment four times.

View

<?php
foreach ($comments as $row) {
    echo '<h4>'.$comments['name'].'</h4>';
    echo $comments['text'];
}
?>

Yes, I realize that I should be echoing the row, like so.

<?php
foreach ($comments as $row) {
    echo '<h4>'.$row['name'].'</h4>';
    echo $row['text'];
}
?>

But that gives me "illegal string offset", for both name and text, four times each, which seems to suggest that $row is holding a string instead of an array. As to why it's still trying to echo the same comment four times, I have no idea. It's always four, no matter how many comments I actually have in my database.

Controller

public function view($slug)
{
    $this->load->helper('form');
    $this->load->library('form_validation');
    $data['news_item'] = $this->news_model->get_news($slug);
    $data['comments'] = $this->news_model->get_news_comments($slug);
    $this->form_validation->set_rules('name', 'Name', 'required');
    $this->form_validation->set_rules('text', 'text', 'required');

    if (empty($data['news_item']))
    {
        show_404();
    }

    $data['title'] = $data['news_item']['title'];
    $slug = $data['news_item']['slug'];

    if ($this->form_validation->run() === FALSE)
    {
    $this->load->view('templates/header', $data);
    $this->load->view('news/view', $data);
    $this->load->view('templates/rowter');
    }
    else
    {
        $this->news_model->set_news_comment($slug);
        $this->load->view('news/success');
    }
}

Model

public function get_news_comments($slug)
{
$this->db->order_by("id", "asc"); 
$query = $this->db->get_where('news_comments', array('news' => $slug));
return $query->row_array();
}

If you have any idea what I'm doing wrong, please help me. Also, I'd like to know the why behind what's going wrong, and why it's echoing the same row four times.

While/foreach Loops Returning Four of the Same Row is somewhat related but was of no help.

UPDATE 1:

print_r($comments); gives me

Array ( [id] => 7 [name] => Mos Def [text] => And you call yourselves intellectuals [news] => tribe )

var_dump($comments); gives me

array (size=4)
  'id' => string '7' (length=1)
  'name' => string 'Mos Def' (length=7)
  'text' => string 'And you call yourselves intellectuals' (length=37)
  'news' => string 'tribe' (length=5)

That explains why it's echoing the same row four times, but I'm still lost as to how to include an array with all the relevant comments, and not just one. I have a feeling there's a problem with my model. Will start exploring further.

var_dump($row);

string 'tribe' (length=5)
2
Best friend in debugging these types of things is print_r or var_dump. What does print_r($comments) / var_dump($comments) give you? Also, your order_by statement looks like it's not being incorporated into the query. - Dan
I did it, and at least figured out why it's printing four. My database table has four columns. ID, name, text, news. Will update my question to include more information. - Goose

2 Answers

0
votes

In your model use result_array() on your $query object. This will return you all results in an array. The row_array() function will only return row by row.

FYI: This means in first time calling row_array() returns the first row of your result, calling same function again the second row, third time third row,... . It is intended for use in a while-loop. result_array()on the other hand will return ALL results in the result set in a single array (which is what you expected as far as I can see from your code in the controller).

0
votes

row_array() only gets a row. It should be changed to result_array() will get all the columns and rows needed.

public function get_news_comments($slug)
{
$this->db->order_by("id", "asc"); 
$query = $this->db->get_where('news_comments', array('news' => $slug));
return $query->result_array();
}

and of course, echo using $row in "$comments as $row"

foreach ($comments as $row) {
echo '<h4>'.$row['name'].'</h4>';
echo $row['text'];