RalphLeMouf Posted July 9, 2012 Share Posted July 9, 2012 Hello - I am fairly new to codeigniter, and it's been about a week now being stuck with this error. I have watched video tutorials, read copious amounts of related questions on other forums, and tried about 10 different methods and continue to get this error. I have hit a wall and really need help. I've tried loading the my database manually and with the auto-helper as well as trouble shooting my config files and such. please help! Here is my current MVC set up for trying to login a user: MODEL: <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class User_model extends CI_Model { function __construct(){ parent::__construct(); } public function validate(){ // grab user input $email = $this->security->xss_clean($this->input->post('email')); $password = $this->security->xss_clean($this->input->post('password')); // Prep the query $this->db->where('email', $email); $this->db->where('password', $password); // Run the query $query = $this->db->get('users'); // Let's check if there are any results if($query->num_rows == 1) { // If there is a user, then create session data $row = $query->row(); $data = array( 'id' => $row->id, 'first_name' => $row->first_name, 'last_name' => $row->last_name, 'validated' => true ); $this->session->set_userdata($data); return true; } // If the previous process did not validate // then return false. return false; } } ?> VIEW: <title>Login</title> <!--MAKE SURE SIGNED OUT HEADER IS IMPLEMENTED FOR ALL SIGNED OUT PAGES INCLUDING THIS ONE--> <div class="structure clearfix"> <h1 class="title_header"> Sign In </h1> <div id="signin_form"> <?php echo validation_errors(); echo form_open('auth/process'); echo "<div class='form_text_signin'>"; echo "Email"; echo "</div>"; echo form_input('email'); echo "<div class='form_text_signin'>"; echo "Password"; echo "</div>"; echo form_input('password'); echo form_submit('submit', 'Submit'); echo form_close(); ?> </div> </div> CONTROLLER: <?php class Auth extends CI_Controller { // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page public function index($msg = NULL) { $data['msg'] = $msg; $this->login(); } function __construct() { parent::__construct(); } public function login() { $data['main_content'] = 'auth/login'; $this->load->view('includes/templates/main_page_template', $data); } public function process(){ // Load the model $this->load->model('user_model'); // Validate the user can login $result = $this->user_model->validate(); // Now we verify the result if(! $result){ // If user did not validate, then show them login page again $this->index(); }else{ // If user did validate, // Send them to members area redirect('account/dashboard'); } } } thanks so much in advance Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/ Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 [*] You don't need to use $this->security->xss_clean() in your models, you should enable it by default in config/config.php under $config['global_xss_filtering']. While you're in your config, set logging to 4 and refresh your page. If you check your logs/ folder, you should have a debug dump that explains what gets loaded and what fails. If you do not have this file, make sure it's writable by the apache server. Be sure to put it back to 0 when you're done, or you'll have a helluva mess in your logs dir. [*] You're setting your session object as a 2d array. This is likely what's causing the error. The correct way to set session data is $this->session->set_userdata('item', 'value'); where it can be retrieve / compared with like thus: echo $this->session->userdata('item'); [*] You are calling a CI method before you are instanciating the class. Move your public function index() below the function __construct() [*] Your view is poorly written more coherency could be applied to your fieldset <?php echo form_open('auth/process'); echo form_label('Email Address', 'email', array('class'=>'form_text_signin')); $data = array( 'name' => 'email', 'class' => 'input', 'size' => 30 ); echo form_input($data, set_value('email')); echo br(); ... $data = array('name' => 'login', 'class' => 'submit', 'value' => 'Log In'); echo form_close(); Obviously, this has nothing to do with your error. It just makes my skin crawl to see needless echos for HTML. Make some adjustments and let us know what you get back. If the CI logs don't give you anything to lead you, check your apache error logs. Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360434 Share on other sites More sharing options...
trq Posted July 10, 2012 Share Posted July 10, 2012 You are calling a CI method before you are instanciating the class. Move your public function index() below the function __construct() The order in which methods are added to a class is irrelevant. Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360464 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 Ok - I went ahead and simplified my approach back to the original way I had it based off of a code igniter tutorial video I watched. I have set the log threshhold to 4 and have scoured through all the different ways to view the error logs and am not seeing any relavent clues. Here is what the log is telling me: Please note that I reload the page and after trying to submit the form and the same results keep coming up in the log. Nothing new. [Mon Jul 09 08:36:11 2012] [notice] Digest: generating secret for digest authentication ... [Mon Jul 09 08:36:11 2012] [notice] Digest: done [Mon Jul 09 08:36:11 2012] [notice] Apache configured -- resuming normal operations ( note that these are from yesterday and not this morning ) Here is the simplified MVC I've reverted back to. I will go through the view later and simplify the html, as I have to work it to my styles and am more concerned with resolving the major issue at hand first. MODEL: <?php class User_model extends CI_Model { function validate () { $query = $this->db->where('email', $this->input->post('email')); $query = $this->db->where('password', sha1($this->input->post('password'))); $query = $this->db->get('users'); if($query->num_rows == 1) { return true; } } } VIEW: <title>Login</title> <!--MAKE SURE SIGNED OUT HEADER IS IMPLEMENTED FOR ALL SIGNED OUT PAGES INCLUDING THIS ONE--> <div class="structure clearfix"> <h1 class="title_header"> Sign In </h1> <div id="signin_form"> <?php echo validation_errors(); echo form_open('auth/validate_credentials'); echo "<div class='form_text_signin'>"; echo "Email"; echo "</div>"; echo form_input('email'); echo "<div class='form_text_signin'>"; echo "Password"; echo "</div>"; echo form_input('password'); echo form_submit('submit', 'Submit'); echo form_close(); ?> </div> </div> CONTROLLER: <?php class Auth extends CI_Controller { // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page public function index() { $this->login(); } public function login() { $data['main_content'] = 'auth/login'; $this->load->view('includes/templates/main_page_template', $data); } function validate_credentials () { $this->load->model('user_model'); $this->user_model->validate(); if($query) { $data = array( 'email' => $this->input->post('email'), 'password' => $this->input->post('password'), 'is_logged_in' => true ); $this->session->set_userdata($data); redirect('account/dashboard'); } else { $this->index(); } } } Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360540 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 *edit* in my model I got rid of $query = before $this->db->where('email', $this->input->post('email'));$this->db->where('password', sha1($this->input->post('password'))); Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360548 Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 *edit* in my model I got rid of $query = before $this->db->where('email', $this->input->post('email'));$this->db->where('password', sha1($this->input->post('password'))); Makes sense. You can further simplify your queries without needing to recall the object like so: controller <?php $data = array( 'email' => $this->input->post('email'), 'password' => sha1($this->input->post('password'), ); $this->model_name->login($data); model <?php function login($data = array()) { // validate data if( !empty($data) ) return FALSE; // retrieve query $query = $this->db ->from('users') ->where($data) ->get(); // Check if query row exists if($query->row()) { // Query row exists, return query row return $query->row(); } else { // Query row doesn't exist, return FALSE return FALSE; } Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360551 Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 quick update to last post: function login($data = array()) Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360558 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 thanks for the help. This is the error I got from your suggestions Call to undefined method User_model::validate() in /Users/michaelsanger/Sites/CodeIgniter/application/controllers/auth.php on line 20 Here is how the whole package looks according to your adjustments: MODEL: <?php class User_model extends CI_Model { function login($data = array()) { // validate data if( !empty($data) ) return FALSE; // retrieve query $query = $this->db ->from('users') ->where($data) ->get(); // Check if query row exists if($query->row()) { return true; } } } CONTROLLER: <?php class Auth extends CI_Controller { // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page public function index() { $this->login(); } public function login() { $data['main_content'] = 'auth/login'; $this->load->view('includes/templates/main_page_template', $data); } function validate_credentials () { $this->load->model('user_model'); $query = $this->user_model->validate(); if($query) { $data = array( 'email' => $this->input->post('email'), 'password' => $this->input->post('password'), ); $this->user_model->login($data); redirect('account/dashboard'); } else { $this->index(); } } } Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360563 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 also more information from my error logs: mysql portion ( apache portion listed above) 120709 08:35:59 mysqld_safe Starting mysqld daemon with databases from /Library/Application Support/appsolute/MAMP PRO/db/mysql 120709 8:35:59 [Warning] The syntax '--skip-locking' is deprecated and will be removed in a future release. Please use --skip-external-locking instead. 120709 8:35:59 [Warning] Setting lower_case_table_names=2 because file system for /Library/Application Support/appsolute/MAMP PRO/db/mysql/ is case insensitive 120709 8:35:59 [Note] Plugin 'FEDERATED' is disabled. 120709 8:35:59 [Note] Plugin 'ndbcluster' is disabled. 120709 8:36:03 InnoDB: Started; log sequence number 0 44273 120709 8:36:03 [Note] Event Scheduler: Loaded 0 events 120709 8:36:03 [Note] /Applications/MAMP/Library/libexec/mysqld: ready for connections. Version: '5.1.44' socket: '/Applications/MAMP/tmp/mysql/mysql.sock' port: 3306 Source distribution Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360570 Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 The error is telling you your model does not have that function ( validate() ). CI calls methods the functions inside your classes. You're not actually accomplishing anything at all with your code. [*]Your view has two fields: email and password. [*]Your controller receives the submission and preps the data - then passes it to the model. [*] Based off of the returned data you go forth with your intentions. If you look at my last post, I described exactly how to take the form input and submit it to the model Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360576 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 ok so to be clear here: your saying I should get rid of the validate_credentials() function currently in my controller and put : <?php $data = array( 'email' => $this->input->post('email'), 'password' => sha1($this->input->post('password'), ); $this->model_name->login($data); inside the login () function with what is already existing? With that being said. This is what I currently have trying to adapt it to your suggestions. MODEL: <?php class User_model extends CI_Model { function login($data = array()) { // validate data if( !empty($data) ) return FALSE; // retrieve query $query = $this->db ->from('users') ->where($data) ->get(); // Check if query row exists if($query->row()) { // Query row exists, return query row return $query->row(); } else { // Query row doesn't exist, return FALSE return FALSE; } CONTROLLER: <?php class Auth extends CI_Controller { // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page public function index() { $this->login(); } public function login() { $data['main_content'] = 'auth/login'; $this->load->view('includes/templates/main_page_template', $data); } function validate_credentials () { $this->load->model('user_model'); $this->user_model->validate(); if($query) { $data = array( 'email' => $this->input->post('email'), 'password' => $this->input->post('password'), 'is_logged_in' => true ); $this->session->set_userdata($data); redirect('account/dashboard'); } else { $this->index(); } } } Sorry this is so difficult. I am just very new at this MVC framework. Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360597 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 Making progress! With what I currently have, I've avoided the error! It just reloads the form with "/validate_credentials" tacked on to the end of the url. It looks like it's doing it's job by reloading the page if the info the user put in is not validated. Now it seems like a database issue. Here is what I have. Model: <?php class User_model extends CI_Model { function login($data = array()) { // validate data if( !empty($data) ) return FALSE; // retrieve query $query = $this->db ->from('users') ->where($data) ->get(); // Check if query row exists if($query->row()) { // Query row exists, return query row return $query->row(); } else { // Query row doesn't exist, return FALSE return FALSE; } } } View: <title>Login</title> <!--MAKE SURE SIGNED OUT HEADER IS IMPLEMENTED FOR ALL SIGNED OUT PAGES INCLUDING THIS ONE--> <div class="structure clearfix"> <h1 class="title_header"> Sign In </h1> <div id="signin_form"> <?php echo validation_errors(); echo form_open('auth/validate_credentials'); echo "<div class='form_text_signin'>"; echo "Email"; echo "</div>"; echo form_input('email'); echo "<div class='form_text_signin'>"; echo "Password"; echo "</div>"; echo form_input('password'); echo form_submit('submit', 'Submit'); echo form_close(); ?> </div> </div> Controller: <?php class Auth extends CI_Controller { // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page public function index() { $this->login(); } public function login() { $data['main_content'] = 'auth/login'; $this->load->view('includes/templates/main_page_template', $data); } function validate_credentials () { $query = $this->load->model('user_model'); if($query) { $data = array( 'email' => $this->input->post('email'), 'password' => $this->input->post('password'), 'is_logged_in' => true ); $this->session->set_userdata($data); redirect('account/dashboard'); } else { $this->index(); } } } Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360636 Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 You are almost there. Let's start from the beginning and explain how we are getting there. Your users need a place to log in, enter the first controller controller( account ) <?php class Account extends CI_Controller { /** * Constructor */ function __construct() { // Call the Controller constructor parent::__construct(); // Load controller global models, libraries, helpers, and hooks } ... function login() { // determine if the user is signed in with their session data // user is signed in, redirect to account dashboard // user is not signed in, load the view } Now build the login page views/login.php <title>Login</title> <div class="structure clearfix"> <h1 class="title_header"> Sign In </h1> <div id="signin_form"> <?php // set the path for the form to process to echo form_open('auth/process'); // create a label, dataset, and the input for email address echo form_label('Email Address', 'email', array('class'=>'form_text_signin')); $data = array( 'name' => 'email', 'class' => 'input', 'size' => 30 ); echo form_input($data, set_value('email')); // create a label, dataset, and the input for the password echo form_label('Password', 'password', array('class'=>'form_text_signin')); $data = array( 'name' => 'password', 'class' => 'input', 'size' => 30 ); echo form_password($data, set_value('password')); // now create the dataset for the submit button $data = array('name' => 'login', 'class' => 'submit', 'value' => 'Log In'); echo form_submit( $data ); // close the form echo form_close(); ?> </div> </div> CI lets you build all your form datas through their form_helper which I find extremely useful. Also, when you create the form through the helper a hidden CSRF field is added for extra security. Anyway, off to the auth controller. controller (auth) <?php class Auth extends CI_Controller { /** * Constructor */ function __construct() { // Call the Controller constructor parent::__construct(); // Load controller global models, libraries, helpers, and hooks } // this is automatically called if no other function is called // it simply turns around and calls the login() function to show the login page function index() { // There is no real need to classify this controller as public $this->login(); } function login() { // catch the form submitted from login $login = $this->input->post('login'); // if the login form was submitted, let's play with the data if( $login ) { // you will want to set some validation data for the inputs // let's just call it required for now, you can read up on this stuff later $this->form_validation->set_rules('email', 'Email', 'trim|required'); $this->form_validation->set_rules('pass', 'Password', 'trim|required'); // Form validation passed, so continue if ( !$this->form_validation->run() == FALSE ) { // now you can create your dataset $data = array( 'email' => $this->input->post('email'), 'password' => sha1($this->input->post('password')), ); // now take that array and pass it to the model // since we don't need the data on this page, we're going to // either refresh the page, or redirect to the homepage / account dashboard // we do this by determining if our handshake was successful or not if( !$this->user_model->login($data) ) { // login failed, alert user we can fail validation directly so that the form // repopulates with their previous data using set_value('field_name') $this->form_validation->set_message('login_failed', 'Invalid credentials'); } else { // user logged succesfully redirect('dashboard'); } } } So we did many things there, most importantly we sent the form data to the model which will now process the information and determine the fate of the form model (user_model) <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Users_model extends CI_Model { /** * Constructor */ function __construct() { // Call the Model constructor parent::__construct(); } function login( $data = array() ); { // check for data. if the form is empty, the login req's are not met if( empty($data) ) return FALSE; // retrieve query $query = $this->db ->from('users') ->where($data) ->get(); // Check if query row exists. The existence is enough to validate our query // which means the user logged succesfully. Now we can set our session data if($query->row()) { // Now we have access to the user's table data and can set our session $this->session->set_userdata('id', $query->row()->id); $this->session->set_userdata('first_name', $query->row()->first_name); ... // now return TRUE for the controller to know what to do return TRUE; } else { // Query row doesn't exist, return FALSE return FALSE; } } That's how I ensure the separation of powers between the MVC, and it's worked well for me. Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360642 Share on other sites More sharing options...
Mahngiel Posted July 10, 2012 Share Posted July 10, 2012 Now it seems like a database issue. The DB issue is because you're never passing the data to the model Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360644 Share on other sites More sharing options...
RalphLeMouf Posted July 10, 2012 Author Share Posted July 10, 2012 Is this impossible to do with just the 3 pages I have? It seems like I should be able to without adding that additional first controller you mocked up Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360672 Share on other sites More sharing options...
Mahngiel Posted July 11, 2012 Share Posted July 11, 2012 Is this impossible to do with just the 3 pages I have? It seems like I should be able to without adding that additional first controller you mocked up Of course, i was only simulating based off of how i read your auth controller - it didn't appear to serve the login page. Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360740 Share on other sites More sharing options...
RalphLeMouf Posted July 11, 2012 Author Share Posted July 11, 2012 I've done some trouble shooting using $this->output->enable_profiler(TRUE); That being said. The post data is correct but under the query section I'm getting Database driver is not currently loaded . It appears that I'm passing and picking up the data correctly. Just having an issue with my database Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360794 Share on other sites More sharing options...
Mahngiel Posted July 11, 2012 Share Posted July 11, 2012 In your config/autoload.php you need to add 'database' to $autoload['libraries'] Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360800 Share on other sites More sharing options...
RalphLeMouf Posted July 11, 2012 Author Share Posted July 11, 2012 have it. have had it. $autoload['libraries'] = array('database', 'session'); Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360803 Share on other sites More sharing options...
Mahngiel Posted July 11, 2012 Share Posted July 11, 2012 Then you're not in the $CI object scope. from your auth controller run [ic]print_r($this)[ic] through some <pre> tags Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360840 Share on other sites More sharing options...
RalphLeMouf Posted July 11, 2012 Author Share Posted July 11, 2012 Ok - it's a lot so I put a link to it on https://gist.github.com/c349378691b7da7f2a99 I'm not really sure what I'm looking for. I didn't see any database stuff on there Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360863 Share on other sites More sharing options...
Mahngiel Posted July 11, 2012 Share Posted July 11, 2012 the very last line of your paste shows exactly the issue: (line 678) [db] => Have you set up your config/database.php ? Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360944 Share on other sites More sharing options...
RalphLeMouf Posted July 11, 2012 Author Share Posted July 11, 2012 I thought it was correct. I guess I thought wrong: $active_group = 'default'; $active_record = TRUE; $db['default']['hostname'] = 'localhost'; $db['default']['username'] = 'root'; $db['default']['password'] = 'root'; $db['default']['database'] = 'cysticlife_CI'; $db['default']['dbdriver'] = 'mysql'; $db['default']['dbprefix'] = ''; $db['default']['pconnect'] = TRUE; $db['default']['db_debug'] = TRUE; $db['default']['cache_on'] = FALSE; $db['default']['cachedir'] = ''; $db['default']['char_set'] = 'utf8'; $db['default']['dbcollat'] = 'utf8_general_ci'; $db['default']['swap_pre'] = ''; $db['default']['autoinit'] = TRUE; $db['default']['stricton'] = FALSE; Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360946 Share on other sites More sharing options...
Mahngiel Posted July 12, 2012 Share Posted July 12, 2012 i cannot replicate your issue. i've even tried an empty CI install and the db object loads properly. i'm at a loss to why your object is being created by no properties set. are you using a current CI version? do you have access to apache logs? Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1360955 Share on other sites More sharing options...
RalphLeMouf Posted July 12, 2012 Author Share Posted July 12, 2012 I'm using 2.0.3 I guess I'll just download a new one and transfer all my stuff over Quote Link to comment https://forums.phpfreaks.com/topic/265436-fatal-error-call-to-a-member-function-where-on-a-non-object/#findComment-1361095 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.