Yii : how to count records in a model? - php

I have following code to fetch data from a model.
$notifyModel = Notification::model()->findByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
Now I want to count the number of rows fetched.
Neither $notifyModel->count() work nor count($notifyModel).
It is very simple but googling did not help.

$notifyModels = Notification::model()->findAllByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
$count = count($notifyModels);
Or
$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));

the right usage of count():
$userid = Yii::app()->user->uid;
$count = Notification::model()->count( 'user_id=:userid', array(':userid' => $userid));
Please see http://www.yiiframework.com/doc/api/1.1/CActiveRecord#count-detail

try this:
$userid = Yii::app()->user->uid;
$notifyModel = Notification::model()->count(
array('condition' => 'user_id=:userid',
'params'=>array(':userid' => $userid)
));

$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));

Since the questions title is about calling the count function in a model I'll add some for those beginners reading this :)
A function inside a model could look like this:
/**
* Count the number of rows which match the user ID
* #param int $uid The user ID
* #return int The number of found rows
*/
public function getCountByUserID($uid)
{
$count = $this->count(array(
'condition'=>'user_id = :uid',
'params'=>array(
':uid'=>$uid,
),
));
return $count;
}

simple ways:
$model = News::model()->findAll(); //returns AR objects
$count = count($model);

I think it is much faster than others
$userTable=User::model()->tableName();
$userid = Yii::app()->user->uid;
$criteria=new CDbCriteria();
$criteria->select=count(id);
$criteria->compare('user_id',$userid);
$count=Yii::app()->db->commandBuilder->createFindCommand($userTable,$criteria)->queryScalar();

That method is wrong!
You trying to get by selecting all rows from database, you load the server, but that's wrong way!
All you need to do :
$sql = "SELECT COUNT(*) FROM {{...table_name...}}";
$count = intval(Yii::app()->db
->createCommand($sql)
->queryScalar());
Or you can create function in your model:
Class User extends CActiveRecord
{
private $_total;
public function getTotalItems()
{
if( empty( $this->_total )) {
$this->_total = intval(Yii::app()->db
->createCommand($sql)->queryScalar());
}
return $this->_total;
}
}
then you can use this functions like this:
$totalItems = User::model()->totalItems;
or :
$model = User::model()->findByPk( $uid );
$totalItems = $model->totalItems;
or :
$model = new User;
$totalItems = $model->totalItems;

This is the most simple way to do that:
$count = Table::Model()
->count("field=:field", array("field" => $fildID));
echo $count;

I strongly recommend you to find count with SQL query else it will degrade your system performance.
There are three way to find out count with the SQL query itself in Yii 1 CActiveRecord, those are:
1. count() method
Finds the number of rows satisfying the specified query condition.
Example :
$count = Notification::model()->count('user_id'=> Yii::app()->user->uid);
2. countByAttributes() method (available since v1.1.4)
Finds the number of rows that have the specified attribute values.
Example :
$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
3. countBySql() method
Finds the number of rows using the given SQL statement. This is equivalent to calling CDbCommand::queryScalar with the specified SQL statement and the parameters.
Example:
$count = Notification::model()
->countBySql("select *from notification where user_id=:userId",
array(':userId'=>Yii::app()->user->uid)
);
Don't use the following code, which will reduce system performance:
$notifyModels = Notification::model()->findAllByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
$count = count($notifyModels);
Because, there are two function call to find the count

In my research, The easiest and Best Practice is like below.
$notifyModel = Notification::model()->count(array('user_id'=> Yii::app()->user->uid));

Related

Doctrine 2 - Get total when using limit via repository

I'm new to Doctrine, and I just could not find a way to get the total number of results when using limit with Criteria (via setMaxResults function) in the EntityRepository::matching method.
In my repository (not an extend of EntityRepository), I'm using the following (I know this is not the optimal code, it is used just to learn Doctrine):
public function getAll($query = null) {
if ($query instanceof Criteria) {
$users = $this->em->getRepository('App\Entities\User')->matching($query)->toArray();
} else {
$users = $this->em->getRepository('App\Entities\User')->findAll();
}
return $users;
}
Now lets say that the Criteria is defined like so:
$query = Criteria::create();
$query->where(Criteria::expr()->contains('username', 'ron'));
$query->setMaxResults(10);
And there are actually more than 10 users that match that.
How can I get the total number of the users that match the criteria?
If you set maxResults to 10, you get 10 results ;).
Why don't you call getAll() to get all results and apply the MaxResults later?
//search for Ron's
$query = Criteria::create();
$query->where(Criteria::expr()->contains('username', 'ron'));
//check how many Ron's your database can find
$count = $repo->getAll($query)->count();
//get the first 10 records
$query->setMaxResults(10);
$users = $repo->getAll($query);

Yii 1.x, query in query DB selection

I have such sql query
SELECT * FROM tbl_role WHERE
tbl_role.id NOT IN (
SELECT tbl_user_role.roleID FROM tbl_user_role
WHERE tbl_user_role.userID = 35
)
AND
tbl_role.id NOT IN (
SELECT tbl_user_role_request.roleID FROM tbl_user_role_request
WHERE tbl_user_role_request.userID = 35 AND tbl_user_role_request.dateEnd IS NULL)
What is the best solution to make it in Yii-like code. How can i do this query using Yii 1.x ?
Assumptions:
tbl_role has a model named Role
tbl_user_role has a model named UserRole
tbl_user_role_request has a model named UserRoleRequest
Note that this will do 3 seperate queries but I believe this is the closest you can get without creating a total mess.
<?php
$userId = 35;
$roles = UserRole::findAllByCondition(array('userId' => $userId));
$roleIds = array_values(CHtml::listData($roles, 'roleId', 'roleId');
$roleRequests = UserRoleRequest::findAllByCondition(array('userId'=>$userId, 'dateEnd'=>null));
$roleRequestIds = array_values(CHtml::listData($roleRequest, 'roleId', 'roleId'));
$criteria = new CDbCriteria();
$criteria->addNotInCondition('id', $roleIds);
$criteria->addNotInCondition('id', $roleRequestIds);
$roles = Role::findAll($criteria);
I would use CDbCommand: http://www.yiiframework.com/doc/api/1.1/CDbCommand#queryAll-detail
Use the following code to fetch the data
$data = Yii::app()->db->createCommand('sql query')->queryAll;
And then you can use this dataset to create the dropDownList
$list = CHtml::listData($data, 'value field', 'text field');
echo $form->dropDownList($model, 'attribute', $list);

Zend_Db -> update() increments my values twice

Here is my code:
$update_data = array('post_browe_count'=>new Zend_Db_Expr('post_browe_count+1'));
$rowaffected = $contentmodel->update_post('posts',$update_data,$id);
my class extend directly from Zend_Db_Table_Abstract,how can I solve it
Here i am giving you an example using products and incrementing a quantity field:
$table = 'products';
$data = array('prd_qnty' => new Zend_Db_Expr('product_qnty + 1'));
$where[] = $db->quoteInto('product_id = ?', $this->pr_id);
$db->update($table, $data, $where);
just try to do your query as above. so it will sure work for you.
let me know if i can help you more.

Codeigniter count_all for pagination

I'm trying to create pagination in codeigniter and I have it working, but I have a small issue. It seems to be loading all the entries in my database and not the selected ones I want.
public function original_count() {
$this->db->where('type', 'Original');
return $this->db->count_all("story_tbl");
}
I know that whats happening is that the last line is overrighting my previous statements. I can't seem to find a way around it though. I tried just a staight sql statement and then returning it, but I could not get that to work either.
this was my statement...
SELECT COUNT(*) FROM story_tbl where type = 'Original';
Some help would much appreciated! :)
CI has inbuilt count method
count_all_results()
Permits you to determine the number of rows in a particular Active Record query. Queries will accept Active Record restrictors such as where(), or_where(), like(), or_like(), etc. Example:
https://www.codeigniter.com/userguide2/database/active_record.html
$total_count = $this->db->count_all_results('story_tbl', array('type' =>'Original'));
You could also use the built-in num_rows() function...
$query = $this->db->where('type', 'original')->get('story_tbl');
return $query->num_rows();
First Try this one.
$query = $this->db->where('tbl_field', 'value')
->get('your_table');
return $query->num_rows();
Besides this Codeigniter has it own function like the following.
$this->db->where('tbl_field', 'value')
->get('your_table');
return $this->db->count_all_results();
Or use this.
return $this->db->count_all('your_table');
Where wont work on count_all condition.. you can use below method to find out total number of rows..
public function count_all() {
$this->db->select ( 'COUNT(*) AS `numrows`' );
$this->db->where ( array (
'type' => 'Original'
) );
$query = $this->db->get ( 'story_tbl' );
return $query->row ()->numrows;
}

How to pass variables into a filter on a recordset or collection

So I have a variable and a recordset:
$firstRecordID = 1;
$records = Recordset::all();
I want to filter the recordset:
$filteredRecords = $records->find(function($record){
if($record->id == $firstRecordID)
return true;
else
return false;
});
Unfortunately, the closure has no clue what $firstRecordID is.
How do I pass in the ID?
You can bind the $firstRecordID to the closure:
$firstRecordID = 1;
$records = Recordset::all();
$filterFunction = function ($record) use ($firstRecordID) {
return ($record->id == $firstRecordID);
};
$filteredRecords = $records->find($filterFunction);
I also simplified your lambda into a single line.
It is maybe a stupid question, but why are you getting everything to filter afterwards manually when the ODM can do that directly?
$records = Recordset::all(array(
'conditions' => array(
'id' => array('<>' => $firstRecordID)
)
));
Even if the result isn't much smaller that doing all() it looks much cleaner using the right tool for the right purpose.

Categories