如何在codeigniter中处理空数组?

So these are my codes.

model

function read() {
     $sql= "SELECT * from table WHERE name = 'rabin'";
     $query = $this->db->query($sql);
     $res = $query->result_array();
     return $res;
 }

controller

function show() {
    $this->load->model("db");
    $array['data'] = $this->db->read();
    $this->load->view("page", $array);
 }

view

foreach($data as $val) {
   "<p>" . echo $val['name']; . "</p>"
   "<p>" . echo $val['address']; . "</p>"
}

Here, when there are no records in the database satisfying the WHERE clause in the query, the model returns null and I get error saying $data expects parameter 1 to be array, null given. There are several methods to deal with this situation. But, what would be the best possible way to handle this situation ?

In your model try out this

function read() {
    $this->db->select()->from('table')->where('name', 'rabin');
    $sql_stmt = $this->db->get();
    return $sql_stmt->result();
}

and then to check you are getting the result - in your controller,

function show() {
     $this->load->model("db");
     $array= array( 'data' => $this->db->read());
     $this->load->view("page", $array);
 }

To view the result in your view file do print_r($data);

And then let me know what you get / result

The problem is the foreach needs data provided by the database, but you didn't give them anyone.

So I will do this instead:

Model

function read() {

    $this->db->where('name', 'rabin');  
    $res = $this->db->get('table');

    return ($res->num_rows() > 0) ? $query->result_array() : false;

}

Controller

function show() {

    // $this->(model_name)->(function);
    $result = $this->db_model->read();

    if ( $result ) {
        // if there has data returns, load view

        $array['data'] = $result;
        $this->load->view('page', $array);      
    }
    else {
        // otherwise, show errors.
        // you can handle by yourself
        echo "no result!";
    }
}
  1. Use the Query Builder always to prevent from SQL Injection.
  2. The Model returns the result_array, or false, so that you can handle the result.
  3. Use $res->row_array() instead if your query result returns only one row. (like the certain one member).
  4. You should rename your model from db to (example)db_model or other. The db will conflict with the system method.
  5. The way to load function from model is $this->model_name->function_name for example, it should be $this->db_model->read().
  6. You should load the model (if it is db_model) like $this->load->model('db_model') in public function __construct() { }.

In your view put if than else block with foreach loop in it. Smething like:

<?php if ($data != FALSE): ?>
<?php
    foreach($data as $val)
    {
       "<p>" . echo $val['name']; . "</p>"
       "<p>" . echo $val['address']; . "</p>"
    }
?>
<?php else: ?>
<?php echo "There is no demanded data."; ?>
<?php endif; ?>

This is much like Benyi's answer with a little twist.

Probably you will eventually want the model to be able to look for names other than 'rabin'. So this shows how to accomplish that by passing a value to the model. Also, this model method always returns something useful to the controller.

function read($name)
{
    $noRecords[] = array('name' => "No Results!", 'address' => "");

    if(empty($name))
    {
        return $noRecords;
    }

    //Such a simple query does not require Query Builder which adds a 
    //lot of extra processing to get to the same place as this query statement
    $sql = "SELECT * from table WHERE name = ?";
    //This is a "bound" query that will escape the input to guard against injection attacks 
    $query = $this->db->query($sql, array($name));
    $res = $query->result_array();

    if($res->num_rows() > 0)
    {
        return $query->result_array();
    }
    else
    {
        // send the controller an array containing a little something to explain what happened
        return $noRecords;
    }
    //the above if/else could also be expressed with this ternary
    // return $res->num_rows() > 0 ? $query->result_array() : $noRecords;   
}

The controller is now very light-weight.

function show()
{
    $name = 'rabin'; //some data for the model
    $array['data'] = $this->db_model->read($name);
    $this->load->view('page', $array);
}

Your view is also greatly simplified

<?php foreach($data as $val): ?>
    <p><?php echo $val['name']; ?>"</p>"
    <p><?php echo $val['address']; ?>"</p>"
<?php endforeach; ?>