i have one php class
class veh extends dbClass
{
function smo($id)
{
$query="select moname from mod where id=".$id;
$data=$this->query($query,1);
return $data[0];
}
}
i am calling that function like this
$objCms=new veh();
<?=$objCms->smo(1);?>
the value i got from this is showing array, but i need to get value of moname
Thanks
Your method don't returns anything, you should use return $this->lastQuery; or something like that
You are selecting, but ot fetching results. Try using MySQL Fetch Array or MySQL Fetch Row.
Example code:
class veh extends dbClass
{
function smo($id)
{
$query="select moname from mod where id=".$id;
$this->query($query,1);
return $this->fetchArray();
}
}
Where:
$this->fetchArray returns result of mysql_fetch_xxx of last query result.
May be the method query return an array as a result, can you give a link to veh class or put query method implementation from veh class.
You would use something like this, depending on how the ->query() method returns it's results. We really need to see ->query()'s body.
function smo($id)
{
$query = "select moname from mod where id=" . $id;
$data = $this->query($query,1);
return $data[0]['moname'];
}
The return statement could be 1 of the following 3 things: $data[0][0], $data[0]['moname'] or $data[0]->moname. You can find out by using var_dump to see how you're able to access the moname column's value.
Related
This should return a list of about five locations. It returns nothing with no errors. I've tested the sql using mysql workbench. It returns the data just fine. Right now I'm writing the back end so I'm not concerned with using views or the dataprovider. I'm just making sure my back end functions work. So with that in mind, how would you return the data retrieved by findAllBySql?
class CashLogic
{
public function AllLocations()
{
$model = new Locations;
$allLocations = $model->findAllBySql("SELECT name from locations");
return $allLocations;
}
}
class SiteController extends Controller
{
public function actionIndex()
{
$model = new CashLogic;
$data = $model->AllLocations();
return $data;
}
}
The findAllBySql() method returns an array of models. From your code it seems you only want the names of locations. An alternative method is
$AllLocations=CHtml::listData(Locations::model()->findAll(),'name','name');
This will return an array of the form array('name'=>'name','name'=>'name'). A better solution would be to replace the first name with the primary key of your locations table.
i'm new to zend framework, in this simple function i want to get a single 'post' and then i want to find all the comments in the related table
public function getPost($idPost)
{
$db= Zend_Registry::get('db');
$select=$db->select()
->from($this->_name, '*')
->where("idPost= ".$db->quote($idPost, 'INTEGER'));
$stmt=$select->query();
$rowset=$stmt->fetchAll();
$post=$rowset->current();
//ora devo aggiungerci i commenti che questo post ha ricevuto
$comm=$post->findDependentRowset('commenti');
$ris=array($post, $comm);
return $ris;
}
in my index controller i i simply call this function, but i get this error:
Call to a member function current() on a non-object in C:\xampp\htdocs\...
where's the mistake?
I think you have a few misconceptions about how you're using Zend_Db.
1. You're not using the ORM, just the PDO wrapper
Which means, your queries won't return Zend rowsets and rows and therefore you can't use the methods of you can use on those.
2. The default fetch mode
The default fetch mode of the Zend_Db_Statement fetchAll() method is array, if you want it to return an object (stdClass), change the fetch mode before fetching the data:
$stmt->setFetchMode(Zend_Db::FETCH_OBJ);
3. Using fetchAll() when you actually want one row
If you just want one row, then don't fetch a whole table! With Zend_Db_Statement, use for example:
$row = $stmt->fetch();
or
$rowObj = $stmt->fetchObject();
... again, that's not a zend row object, just a stdClass instance, but you can do:
$rowObj->some_field;
on it.
On the other hand, if this is a method in your Post model, it should look something like:
public function getPost($idPost)
{
return $this->getRow($idPost);
}
This will return the post, then, if you've setup the table relationships correctly, you can also query for the dependent data or just get all comments with that id separately.
The problem is that unless you define a table class as was previously mentioned you can't uuse the dependent or parent rowsets.
To make your current function work would be best done with two functions, and keep it simple:
public function getPost($idPost)
{
$db= new Zend_Db_Table($this->_name);
$select=$db->select()
->where("idPost= ?", $idPost);
/*Fetch just the row you want, or use fetchAll() if you need to match return types*/
$row = $db->fetchRow($select);
return $row;
}
public function getComments($table='comments', $id) {
$db = new Zend_Db_table($table);
$select = $db->select()->where('post_id = ?', $id)->order('date ASC');
$rowset = $db->fetchAll($select);
return $rowset/* or you could return an array ->$rowset->toArray() */
}
Zend_Db_Table is going to attempt to use the current database adapter, so all you need to do is pass in the tablename.
One more note: you don't need to use any of the quote() function when using select() it's taken care of.
But it is really important, that if you are going to use Zend_Db, you need to learn about "Defining table classes". At least enough to use them in your own classes.
I hope this helps!
To get a rowset and dependent rowset you have to use Zend_Db_Table.
You only use the Zend_Db_Adapter with Zend_Db_Select.
Read from here.
So you have to define a class which extends from Zend_Db_Table_Abstract.
Example:
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
protected $_primary = 'bug_id';
}
To get the Zend_Db_Table_Rowset object use:
$bugs = new Bugs();
$rowset = $bugs->fetchAll("bug_status = 'NEW'");
To find dependent rowsets you have to define the relation in your table class. Look here how to define relationships.
I have a query which is returning a sum, so naturally it returns one row.
I need to count the number of records in the DB which made that sum.
Here's a sample of the type of query I am talking about (MySQL):
SELECT
i.id,
i.vendor_quote_id,
i.product_id_requested,
SUM(i.quantity_on_hand) AS qty,
COUNT(i.quantity_on_hand) AS count
FROM vendor_quote_item AS i
JOIN vendor_quote_container AS c
ON i.vendor_quote_id = c.id
LEFT JOIN company_types ON company_types.company_id = c.company_id
WHERE company_types.company_type = 'f'
AND i.product_id_requested = 12345678
I have found and am now using the select_min(), select_max(), and select_sum() functions, but my COUNT() is still hard-coded in.
The main problem is that I am having to specify the table name in a tightly coupled manner with something like $this->$db->select( 'COUNT(myDbPrefix_vendor_quote_item.quantity_on_hand) AS count' ) which kills portability and makes switching environments a PIA.
How can/should I get my the count values I am after with CI in an uncoupled way??
If you want a completely decoupled way of dealing with this, just run the query to get all the rows you'd add with SUM() and then add them together in PHP.
$sum = 0;
foreach($query->result() as $row)
{
$sum += $row->quantity_on_hand;
}
Or something like that.
What about defining your table in a var or const and then doing the query like so:
define('VENDOR_QUOTE_ITEM', 'vendor_quote_item');
$this->$db->select( 'COUNT(' . VENDOR_QUOTE_ITEM . '.quantity_on_hand) AS count' );
This should be faster than $query->num_rows() as that would retrieve results and have PHP count them. The above code cuts to the chase and just asks the DB for the count without returning anything else (because it uses mysql's COUNT())
As for why $query->num_rows(); isn't working.. Make sure that var you call num_rows on a CI query result object. You should have something like this:
$your_query = $this->db->query("YOUR QUERY");
$your_query->num_rows()
if you would like to use any MySQL function inside $this->db->select() function pass the second parameter as FALSE.
So it should be $this->$db->select( 'COUNT(myDbPrefix_vendor_quote_item.quantity_on_hand) AS count' , FALSE)
Well ... while it's a different direction than I initially envisioned, I ended up simply extending CI via the directions found HERE.
I added a select_count() method to match the existing select_min(), select_max(), and select_sum() methods.
This addition only applies to MySQL at this time, but it's a solid solution.
In case someone encounters a similar problem in the future, here's what I did:
I dropped Simons "MY_Loader" directly into my "application/core"
directory (didn't need to change a thing).
Then I created a "MY_DB_mysql_driver" in the "application/core" directory,
as per his instructions ... and made it looke like this: (sans comments for brevity)
.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class My_DB_mysql_driver extends CI_DB_mysql_driver {
final public function __construct($params) {
parent::__construct($params);
log_message('debug', 'Extended DB driver class instantiated!');
} /* method: __CONSTRUCT */
final public function select_count($select = '', $alias = ''){
if ( !is_string($select) OR $select == ''){
$this->display_error('db_invalid_query');
}
if ($alias == ''){
$alias = $this->_create_alias_from_table(trim($select));
}
$sql = 'COUNT('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
$this->ar_select[] = $sql;
if ($this->ar_caching === TRUE){
$this->ar_cache_select[] = $sql;
$this->ar_cache_exists[] = 'select';
}
return $this;
} /* method: SELECT_COUNT */
}
Hope it helps.
Using CodeIgniter, I find the following code in all the models that gathers data from a database:
// .. taken from function get_user_data($user_id)
// Select data
$user_data = $this->db->from('users')->where('id', $user_id)->get()->row();
// Check if we got any matches
if(isset($user_data->id)) {
// Indeed we did, return the data found
return $user_data
} else {
// Nope, no data found
return FALSE;
}
The interesting part is where I check if the query actually returned any data. I'm doing that for EVERY query, which adds up to quite a bit repetitive code.
Is there any way to, perhaps override the CodeIgniter functions, making them return FALSE if no data was found?
I'm probably missing something, as I can't see why CodeIgniter isn't handling this already.
There isn't much in the way of built in shortcuts. Even the manual suggests checking your results:
If you run queries that might not produce a result, you are encouraged to test the result first:
$query = $this->db->query("YOUR QUERY");
if ($query->num_rows() > 0)
{
// found results
}
You could always use a class extension:
class MY_Model extends CI_Model {
protected function _get_row($result)
{
return $result->num_rows() ? $result->row() : FALSE;
}
}
Usage in a model:
function get_user_data($user_id)
{
$user_data = $this->db->from('users')->where('id', $user_id)->get();
return $this->_get_row($user_data);
}
You'd just have to extends MY_Model for the models you want to have access to the function.
Another option would be to return the result of $this->db->get() instead, and do the check in your controller (which you would probably have to do anyways).
I agree with wesley murch option but i think creating a entire class for an individual function isn't good practice. My opinion is to use helpers. You can try this:
In Helper File:
function get_db_data($result)
{
return ( $result->num_rows() > 0 ) ? $result->result_array() : false;
}
You can call this function in any of your model with
$this->load->helper('helper_file_name');
$dbData = get_db_data(result_object);
I have a question relating to properties for a specific instance of a CI model. For example:
There is a model called project_model. In the model it has a method calle Get_Projects:
$total_projects = $this->project_model->Get_Projects($options);
When this is called it creates a property in the model like so:
$query = $this->db->get('projects');//query
$this->num_rows = $query->num_rows();
return $query->result();
So after the method has been called and in the controller, I need to access num_rows:
$num_rows = $total_projects->num_rows;
(I know some of you may question the reason behind using num rows in the controller. It's to do with setting the pagination. There may be better ways of doing it but there is no time in this particular project.)
My problem is that this creates a syntax error:
Severity: Notice
Message: Trying to get property of non-object
Filename: controllers/projects.php
Line Number: 110 ($num_rows = $total_projects->num_rows;)
Firstly why is this? I was thinking of using this: $this->project_model::num_rows instead? But then the num_rows won't be specific to the $total_rows object will it? So it will just be for the entire model.
BTW: I read the CI guide on models but there wasn't any information on creating instances of models at all.
EDITED: I need the result of num_rows property to be object-specific. So for example:
$a=$this->project_model->Get_Projects($options);
$b=$this->project_model->Get_Projects($options);
$num_rows = $this->project_model->num_rows;
The final line will get the result of $b num_rows and not $a. So How do I call it so that I can make it object-specific? (Obviously I could store it before the second call in a variable.)
This happens because your variable $total_projects doesn't have an instance of the class. It just contains the results from the Get_Projects() function.
You should try, after doing everything, $num_rows = $this->project_model->num_rows (untested)
You could just instantiate a the model each time you need it.
$object_one = new $this->project_model;
$foo = $object_one->Get_Projects($options);
var_dump($foo);
echo $object_one->num_rows;
$object_two = new $this->project_model;
$bar = $object_two->Get_Projects($options);
var_dump($bar);
echo $object_two->num_rows;
This way you can get/set any attributes of each model instance seperatly.
Better way is to make two queries.
One for the num rows and other for the result.
You are returning the result only, not the num rows. So it won't return the value.
Make each query in different function. And then call from that function.
I am not sure about performance side though.
****** Model ****
class Project_model extends .... {
private $num_rows = 0;
public function Get_Projects($options){
.....
$query = $this->db->get('projects');//query
$this->num_rows = $query->num_rows();
return $query->result();
}
public get_num_rows(){
return $this->num_rows;
}
}
**** Controller ****
class Project extends .... {
function project(){
...
$total_projects = $this->project_model->Get_Projects($options);
$num_rows = $this->project_model->get_num_rows();
...
}
}
Not a perfect exaple of encapsulation but....