0

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 ?

5
  • The same way you would check in PHP: if(is_array($data) && $data){foreach($data...... Commented Sep 8, 2016 at 18:05
  • Well, that would be the basic method to handle the error. But is that the best way ? Commented Sep 8, 2016 at 18:52
  • Yes, it is. Your view only needs to make sure it is supplied with the exact data type which it needs to act upon. If you start messing around with crap like if($data != FALSE){} then your code will become increasingly fragile. Imagine what would happen if $this->db->read(); started returning a string as part of the varying output or a null, then you would have to back and re-factor your if(){} blocks. However, if you structure your view to only act when it has received the expected data type then it will continue to do so. Continued below.... Commented Sep 8, 2016 at 19:08
  • The only caveat is that if something fails up the line then it might make debugging the root cause a little trickier but at least your users are not bombarded with errors or blank screens and such. Commented Sep 8, 2016 at 19:10
  • ps. In view, you can use if ($data) foreach ($data as $val) handle if there has result or not. Commented Sep 9, 2016 at 2:13

4 Answers 4

2

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() { }.
Sign up to request clarification or add additional context in comments.

1 Comment

ps. In view, you can use if ($data) foreach ($data as $val) handle if there has result or not.
1

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

2 Comments

Thanks for your comment but the problem is not with the code. It returns all the data, if the name field has 'rabin' and returns null if there is no 'rabin' in the name field. The problem is how do I handle the error in the best possible way.
@RabinLama changed the controller in the answer. after that do print_r($data); in your view
1

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; ?>

Comments

1

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; ?>

3 Comments

That would work for simple array. But what if I have nested array ? Or what if I have lots of field in the array ? Do I insert data statically to each one of them ?
My answer is based on the criteria of your question. So, I'm not exactly sure what you are asking. Howerver. The rows from a database query will not contain nested arrays. Such is the nature of SQL. It just does not do that. If you send lots of fields to a view then yes, you have to reference each data member individually. (Is that what you meant by " Do I insert data statically to each one of them ?"?
The first time I heard that simply query doesn't have to use query builder in order to decrease system load. I'll keep in mind! Really helpful tips!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.