Codeigniter model error - php

I created a new model class as my_model.php inside /models folder, and a function inside it to load all elements:
function get_all(){
$query = $this->db->get('test'); //test is my table
return $query->result();
}
In the controller, I instantiated the class and called the method;
$this->load->model('my_model');
$res = $this->my_model->get_all();
But, this throws me error saying:
Fatal error: Call to a member function get() on a non-object in /var/www/testapp/application/models/my_model.php on line 7
This line 7 points to the portion of the code where I have used $this->db. I tried to see the value of $db but I think it is magic accessor __get and __set, so I could not see the value of this property before calling that method.
I tried googling for several other cases but none of them match my scenarios and rather none of them could solve my problem.

You have to load the Database first
$this->load->database();
So, all code:
function get_all(){
$this->load->database();
$query = $this->db->get('test'); //test is my table
return $query->result();
}
Or, load database in your __construct method.
Or, IMO, It's better to autoload database by changing application/config/autoload.php, example is below.
$autoload['libraries'] = array('database','form_validation'); //form_validation is for example only

In CodeIgniter, you should load database model before you use it.
Use $this->load->database(); to load database model.

Your error is actually quite simple:
return $query->result;
Should be:
return $query->result();
Sometimes the line number reported by a PHP error isn't exactly the one you think it is, the parser is just doing it's best and reporting where it found an error.
There's one more issue:
$res = $this->my_model->getAll();
Should be:
$res = $this->my_model->get_all();
You have called your own function by the wrong name.

Related

how to call two functions from inside a third one

I have created a page called User.php, I created inside it three public functions:
public function createUser() {
// to insert the data of the user into a database
}
public function AddRole() {
// to insert the role of the new created user into the same database but of course another table
}
public function register(){ //to call the first two function
$conn = getConn();
createUser();
AddRole();
}
then I called the function register() from another page called registerCtrl.php
$id = $thisUser->register() ;
I am getting this error:
Fatal error: Call to undefined function createUser() in C:\wamp\www\imp\models\User.php on line 114
I think that the problem is in the way I am calling the two functions inside the third one, of course this is only my opinion.
NB: I am new in coding and this is my first software.
thank you guys.
When calling a member function of a class, you need to link it to an instance of that class, in the above case you want to call it on the instance your currently working with, which is this. So the call should be...
$this->createUser() ;
$this->AddRole() ;
Also if $conn is meant to be an instance variable, you also need to prefix it with $this->...
$this->conn = $this->getConn();
(Also depends on where getConn() is defined)
I think the problem is, that you don't have a class. In PHP you can create functions without a class Then you try to acces to the function with an Object.
Try to include the file User.php. require('User.php') or include('User.php') in the registerCtrl.php-File at top. Then just use register();
Fatal error: Call to undefined function createUser() in C:\wamp\www\imp\models\User.php on line 114 -> this means that the Interpreter cant find the function.

Database error on calling a function in another model through its controller from a controller

In my CakePHP 2.3, I'm trying to call a function from User Controller to a City Controller, which in-turn calls a function from City Model.
Function in User Controller:
function get_cities(){
$list_cities = $this->City->get_all_cities();
}
Function in City Controller:
function get_all_cities(){
return $get_cities = $this->City->get_all_active_cities();
}
Function in City Model
public function get_all_active_cities(){
$cities=$this->find('all',array('conditions'=>array('City.status'=>1)));
return $cities;
}
But I'm getting a Database Error.
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near
'get_all_active_cities' at line 1
How can I fix this issue? TIA.
Quick hint, you can register your model within any controller you don't need to call the controller if you are only interested in calling the model function.
e.g. you can register the model using within your User controller
$this->City = ClassRegistry::init('City');
then call
$this->City->get_all_active_cities()
http://api.cakephp.org/2.3/class-ClassRegistry.html#_init
On the contrary you can also use var $uses = array('User','City'); within your Users controller to achieve the same
Also check the sql query generated from the sql log generated by CakePHP the issue points more towards the query generated by the framework. You can verify with Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual
Hope that helps,
Cheers.
You can also load City Model in your users/get_cities method.
Like this below code
function get_cities(){
$this->loadModel('City');
$list_cities = $this->City->get_all_cities();
}
for the right syntax to use near 'get_all_active_cities' at line 1
This error message means this code was executed:
$modelClass->get_all_active_cities();
However the model class does not have that method, and is instead passed to mysql as a query because that's how unhandled methods are implemented.
Either there is a typo in the method name, or $modelClass is not the class you think it is
If you change your controller code like so:
function get_cities(){
debug(get_class($this->City)); //
die;
}
And see "AppModel" then your model class is not being used at all - typical reasons for that are:
The model file name is not correct
The model file is in the wrong folder
That's not a normal way to write model code
Having a method named get_all_active_cities that is just a simple find isn't really helpful. It's not encapsulating complexity, or making it clearer what the code does, arguably it makes the code harder to read since it's hiding something so simple. Consider simply using equivalent find:
function get_cities(){
$params = [
'conditions'=>[
'City.status'=>1
]
];
$list_cities = $this->City->find('all',$params);
...
}
Another alternative is to create a finder method so that the find logic is available in exactly the same way as the standard finders i.e.
function get_cities(){
$list_cities = $this->City->find('allActive');
...
}
With:
class Article extends AppModel {
public $findMethods = array('allAcctive' => true);
protected function _findAllActive($state, $query, $results = array()) {
if ($state === 'before') {
$query['conditions'][$this->alias . '.status'] = 1;
return $query;
}
return $results;
}
}
The benefit here is that the above finder is used in exactly the same way as the other finder methods.
If this is a condition to be applied to all finds, also consider using a behavior with a beforeFind callback to always apply that condition for you.
$this->loadModel('City');
You can use the data from city directly where ever its required. Hopes this helps you

ZF2 - Call to a member function on a non-object error

I am trying to implement a simple roll-a-dice service and use it in a .phtml file. I know my issue has been reported often on SO, but I could not find a solution in other questions.
I get the following error message:
Fatal error: Call to a member function getDiceResult()
on a non-object in rolladice.phtml on line 11
Here is line 11:
<?php
$result = $this->rollADiceService->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
The controller is set-up as following:
class RollADiceController extends AbstractActionController
{
private $rollADiceService;
public function setPluginManager(PluginManager $plugins) {
parent::setPluginManager($plugins);
$this->rollADiceService = $this->getServiceLocator()
->get('RollADiceService');
}
...
In Module.php, I have:
public function getServiceConfig()
{
return array(
'factories'=>array(
'LoginLogoutService' => function() {
return new LoginLogoutService();
},
'RollADiceService' => function() {
return new RollADiceService();
},
),
);
}
I am using the same technique (i.e., setPluginManager) to retrieve instances of my services in other controllers without issues. What am I doing wrong?
P.S.: Using a debugger, I can see that setPluginManager() is called, but that the $this->rollADiceService variable is initialized with null. Why?
Ultimately, there were two issues:
i) I refactored my code to pass the result of the call to rollADiceService->getDiceResult() as a variable which $this can access.
ii) Hijacking setPluginManager() is not a recommended practice. I've implemented factories for my controllers depending on services.
your problem is realy simple I think.
<?php
$result = $this->rollADiceService()->getDiceResult();
echo "<p>Roll-a-dice result: ".$result."</p>";
?>
Add these brackets after rollADiceService should fix your problem. Without brackets, Zend View instance try to access to view variable named rollADiceService, which is obviously NULL.
By adding brackets, you tell to View it should look for rollADiceService in registered view helpers.
I hope it helps :)

Doctrine nestedset delete

I have some models witch are using Doctrine nestedset feature.
I want to add delete functionaly of elements from tree since that is required in my application. I was trying with snippets from documentation but I am getting a very strange error with that code.
YAML is here: http://pastie.org/820978
And I am trying with this code in my Menu class witch extends generated abstract class BaseMenu and BaseMenu extends Doctrine_Record :)
Anyway my code:
public function getMenuItem($id)
{
return Doctrine::getTable('Menu')->find($id);
}
public function delete($id)
{
$item = $this->getMenuItem($id);
//echo get_class($item); will return Menu so object exists !?
$item->getNode()->delete();
}
And I get this an error:
Fatal error: Call to a member function
getNode() on a non-object
And I just noticed that get_class($item) is trowing a warring (so that probabbly is reason for this strange behavior):
Warning: get_class() expects parameter
1 to be object, boolean given in...
However I need a solution for this and all hints are welcome...
getNode() returns a Doctrine_Node, not a Doctrine_Record.
A Doctrine_Record can be deleted, but a Doctrine_Node cannot be deleted -- because it is not persistent anyway.
The correct logic would simply be:
$item = $this->getMenuItem($id)->delete();
Also, don't name a method in your model 'delete'!! This will override Doctrine_Record's delete() method, which will drive you crazy trying to debug it.
I personally don't like using Doctrine::getTable("table_name") because it doesn't make the code very dry. If for some reason "table_name" ever changes, you'll have to change it in alot of places.
I used Doctrine in Zend Framework apps, so my typical pattern of use involves instantiating a protected instance of every model in my module.
Using that pattern, I would just do this in my controller
$this->_Menu
->getTable()
->find($id)
->getNode()
->delete();
If you really want to keep your functions similar, I would use something like this
public function getMenuItem($id)
{
if (empty($id))
{
throw new Exception ("A parameter of id is required to retrieve a menu item".);
}
return $this->getTable()->find($id);
}
public function delete($id)
{
$item = $this->getMenuItem($id);
if ($item instanceof Doctrine_Record == false)
{
throw new Exception("Item is not a valid Menu Record.");
}
$item->getNode()->delete();
}
Answer is in your question: $item is not object (i guess it's value is false, but you can use var_dump($item)), because there is no row with such id in DB (also I guess your $id is null)
Warning: get_class() expects parameter 1 to be object, boolean given in...
Fatal error: Call to a member function getNode() on a non-object

Class methods and instance methods in codeigniter, how can I use them?

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!
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();
You can make your class as a helper so it will not be load as a instance. Only the code will be included so you can just call it as:
$sample = class_name::method();
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.
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
$pagedata['numberofpeople'] = $this->user_model->get_total_users_count();
That's the CI way.

Categories