views:

149

answers:

4

I am very new to codeigniter but understand OOP and MVC as I do a lot of Rails development. One thing I haven't figured out yet is how to write a class level method in codeigniter and access it in a controller. For example, I have

<?php
class User_model extends Model {
    function user_model()
    {
        parent::Model();
    }

    public static function get_total_users_count(){
     $results = $this->db->query("SELECT * FROM bhr_users GROUP BY userid");
     if($results){
      return $results->num_rows();
     }
     return 0;
    }
}
?>

I think what I have done here is established a class level method for my model that I should be able to call with User_model::get_total_users_count() Now in my controller which a previous programmer called "Welcome" I have something like:

<?php

class Welcome extends Controller {

    function Welcome()
    {
     parent::Controller(); 
     $this->load->model('bhr_model');
            $this->load->model('user_model');
    }

    function index()
    {

     $invite =    $this->uri->segment(3);
     if($invite == 'invitefriends') {
      $pagedata['invitefriends'] = $invite;
     } else {
      $pagedata['invitefriends'] = '';
     }

     $pagedata['numberofpeople'] = User_model::get_total_users_count();
     $this->load->view('default_page', $pagedata);
    }
}

The above method call to get_total_users_count does not work because it says because I am using the db method on a class level function in get_total_users_count. In other words $this has no db method when I reference a class.

So now my question is a bit more theoretical. I always thought that instance methods should only be used when a method is acting on a specific instance of an class. Makes sense, right? However, get_total_users_count is acting on all "users" and counting them. It just seems like that should be a class level method. Do you agree? If do, do you know how I can access the database from withing the framework inside a class level function?

Thanks!

A: 
 $pagedata['numberofpeople'] = $this->user_model->get_total_users_count();

That's the CI way.

Thorpe Obazee
that doesn't really address the theoretical question at hand. a function to get total users is not operating on an instance of user so it should probably be a class level method
Tony
The best way then is to create an instance of the CI super object
Thorpe Obazee
+1  A: 

get_total_user_count is more of a function for a user table gateway.

User model should have things like getUsername and getLastLogin.

User Table Gateway should have things like findUserById, createNewUser, and getTotalUserCount

Galen
are you suggesting that I add a gateway class for every table. i feel like using your methodology I would eventually need to. I am not disagreeing with it, just seems like overkill
Tony
yes, that is what im suggesting. It makes things a lot cleaner, and it makes more sense, since you're right that the function doesnt act on a specific user instance.http://martinfowler.com/eaaCatalog/tableDataGateway.html
Galen
interesting point, i will consider doing this. however, I could argue that all class level methods are gateway and all instance level methods are not...and there is no need to create two separate classes
Tony
A: 

Since you are not instantiating User_model, you must get the CI instance, then use that for your db queries.

Inside get_total_users_count():

$ci_ins =& get_instance();
$ci_ins->db->query();
mives
Why the downvote? This answers the question "how I can access the database from withing the framework inside a class level function"
mives
+2  A: 

CodeIgnighter works is by instantiating your models as you load them. What Thorpe Obazee said is the correct codeIgnighter way to use your Model.

What you are asking is if you can use a static method as you'd expect in most circumstances, which just isn't how CI works.

To accomplish what you're after, mives points out get_instance() which is the correct way to get at the main CI object. I use that way myself to do what you're doing.

Jessedc