I am trying to retrieve a specific field from the first row of my query results. The following works just fine...
$result = $db->query($query);
$firstrow = $result->fetch();
$desired_field = $firstrow["field"];
My question is, can i do this in one step without storing the first row of results in a variable? Thanks in advance!
You can use fetchColumn() to return a single column from the next row in the result set. If there is only one column in the result set, do:
$desired_field = $result->fetchColumn();
If there are multiple columns in the result set, specific the numeric index of the one you want:
$desired_field = $result->fetchColumn(1);
Take notice of the warning provided in the fetchColumn() documentation:
There is no way to return another column from the same row if you use PDOStatement::fetchColumn() to retrieve data.
You can use something like $firstrow = $db->query($query)->fetch() but this is not good practice to do with functions that aren't guaranteed to return an object.
The query() function can return FALSE on error, and the dynamic call to fetch() would be a fatal error. You can't call ->fetch() on a scalar FALSE value.
For example, try the following and your script will explode:
$firstrow = $db->query("SELECT * FROM table_that_does_not_exist")->fetch();
PDO does support a mode to throw exceptions instead of returning FALSE, so in that case you are guaranteed either query()->fetch() works, or else query() will throw an exception, so you will never reach the fatal error. But you might not be using PDO's exception mode.
The answer from #GeorgeCummins points out that there's a fetchColumn() method that you can use once you have a PDOStatement object, that's a good way to get a single column. If you only need one column, name that column as the only column in your select-list, and then always use fetchColumn(0):
$oneValue = $db->query("SELECT oneColumn FROM table")->fetchColumn(0);
Otherwise if you use fetch(), this returns an array. PHP 5.4 supports array dereferencing:
$oneValue = $db->query("SELECT oneColumn FROM table")->fetch()[0];
But if you're using PHP 5.3 or earlier this is not supported. And I've never tried it with the array returned by PDOStatement so if it's actually returning an ArrayObject or something this might not work anyway.
This is guarantee to work if and only if your query is correct and there is at least one row data.
$db->query($query)->fetch(PDO::FETCH_OBJ)->field;
Related
I have this function in a linked file:
function getNumberOfHerps() {
$sql = "SELECT COUNT(ID)
FROM HERPES;";
return DBIface::connect()->query($sql);
}
I can call on this function from any other page in the website. What I want to do is to be able to use the result of the COUNT function in my php code on various pages, because I need to know how many herps there are in the database on several occasions in the code.
I tried this:
$result = getNumberOfHerps();
$numberOfHerps = $result['COUNT'];
But it caused a parse error on the second line, saying this:
Cannot use object of type PDOStatement as array.
Please tell me how I can use the result of a Count function in php code. Thanks :D
You are actually facing 2 separate items here that need your attention:
You can't access the COUNT(ID) returned from your query and
You are attempting to access data of a PDOStatement object as an array
So:
You can create an ALIAS for the value returned from the COUNT() function:
$sql = "SELECT COUNT(ID) as COUNT...";
This will provide to your result set a new column named COUNT that you can access your row count from.
Secondly, you need to perform a fetch operation on the PDOStatement in order to access it's data (this is what is causing your parse error). You have several options for accessing the result set in a PDOStatement:
list ($idCount) = $result->fetch();
// $idCount will now have the value of your COUNT column
or
$results = $result->fetch(PDO::FETCH_ASSOC);
// you can then access your COUNT as $results['COUNT'];
or even
$results = $result->fetch(PDO::FETCH_OBJ);
// you can then access your count as $results->COUNT
There are actually several additional FETCH_* styles available to use. The ones I've described though would likely be the most common. You can find more information about fetching PDO result sets at
http://us1.php.net/manual/en/pdostatement.fetch.php
I worked it out for myself, so I'll put my answer up for anyone else who finds this question:
I changed the function to this:
function getNumberOfHerps() {
$sql = "SELECT COUNT(1)
FROM HERPES";
return DBIface::connect()->query($sql)->fetchColumn(0);
}
So what the function now returns is the actual count value (the first column of the query). That means that in the webpage php file, you can access it in this way:
$numberOfHerps = getNumberOfHerps();
Much more simple.
I have the following code in a CI app :
$query = "INSERT INTO user(user_name,user_email) VALUES(?,?)";
$result = $this->db->query($query,array($userName,$email));
if ($result->num_rows()>0)
return $this->db->insert_id();
else
return null;
This yields an error ; Fatal error: Call to a member function num_rows() on a non-object in C:\xampp\htdocs\cmdline\application\models\mlogin.php on line 38
line 38 is the condition for number of rows is greater than 0 .
Now I don't get what is happening - I am using CI's documentation to check whether number of rows is greater than 0 , why does this fail ?
It's because you're doing an INSERT query. Queries that modify data return TRUE in all cases, so what you're really attempting is TRUE->num_rows(), which doesn't make any sense, causing an error.
What you actually want to check is $this->db->affected_rows(), which will tell you how many rows were inserted into the database.
Although you're not doing it in this case, it's worth noting that affected_rows() will only return the count of rows that actually changed during the query, so UPDATE queries that don't actually modify data (i.e. if the field already has the value the query is trying to set it to), then that row won't be reflected in the affected_rows() value.
From CodeIgniter's documentation.
The query() function returns a database result object when "read" type queries are run, which you can use to show your results. When "write" type queries are run it simply returns TRUE or FALSE depending on success or failure. When retrieving data you will typically assign the query to your own variable, like this:
Your query, because it's an INSERT will simply return TRUE or FALSE.
I am trying to figure out the proper way to get file location data (for display/editing) from MySQL with PHP. So far I've got these three parts. $resfile is a resource getting the actual array. Would I then test with an if statement, or would I have to use a while loop to iterate over the array (which, as far as I know, should only have ONE value)
First part:
$resfile = mysql_query('SELECT file_loc WHERE org_id = '.$org);
Do I use this?
if (!$resfile) {
}
Or this?
while ($filerow = mysql_fetch_array($resfile)) {
}
Or both?
The mySQL library has a function for counting the rows of a result set:
if (mysql_num_rows($resfile) > 0) .......
You need to use both. If the query returns false, then there was an error executing your query. If there is no data returned in the query, (it will still return true) then you need to use fetch_array to get the data.
example:
$query = $mydb->query('PRAGMA table_info("mytable")');
//variable query has now type of PDOStatement Object
print_r($query->fetchAll(PDO::FETCH_COLUMN,1)); // this result is ok
print_r($query->fetchAll(PDO::FETCH_COLUMN,2)); // but this result gives empty array
so is there any way to reuse statement object ?
A PDOStatement Object returns false when there are no more rows available. The call to fetchAll covers all rows which would then always return false on any following attempt to fetch. This limits the reuse of the statement object. You can use the PDOStatement::bindColumn to achieve what it looks as if you are attempting in your example.
$query = $mydb->query('PRAGMA table_info("mytable")');
// Variables passed to be bound are passed by reference.
// Columns are based on a *1* index or can be referenced by name.
$query->bindColumn(1, $bound_column1);
$query->bindColumn(2, $bound_column2);
$query->fetchAll();
print_r($bound_column1);
print_r($bound_column2);
Sure, you can re-use the statement object.
But think about this for a moment: If you already have fetched all PHP Manual, why do you expect that the second fetch all statement can still return something?
print_r($query->fetchAll(PDO::FETCH_COLUMN,1)); // this result is ok
print_r($query->fetchAll(PDO::FETCH_COLUMN,2)); // but this result gives empty array
PDO has a cursor that advances. Once at the end, there is nothing you can do but close the cursor PHP Manual and execute again.
You can re-use the statement object for that.
But I don't think you want/need to actually do that for your code. Instead, fetch all columns and then access them in the returned data by their index:
print_r($query->fetchAll(PDO::FETCH_NUM)); // this result is ok
You will see in the output that you now have 0-indexed column numbers per each row, so you can access the columns within the return data by their column-index - row per row.
$array = $query->fetchAll( args );
Then use the $array how you want.
Say I have a random zend_db_select object.
How can I perform a count on that object, so I know the amount of items that meet the query.
I tried the following:
$data->TotalRecords = $select->columns(new Zend_Db_Expr('COUNT(*)'))->query()->fetch();
But this gives me the following error:
Message: No table has been specifiedfor the FROM clause
The query by itself works fine and returns a resultset.
There's a couple of ways of specifying the columns to fetch in a Zend_Db_Select. The following two product the same SQL
$select = $db->select()
->from('myTable', array())
->columns(array('TotalRecords' => new Zend_Db_Expr('COUNT(*)')));
$select = $db->select()
->from('myTable', array('TotalRecords' => new Zend_Db_Expr('COUNT(*)')));
The from method takes a first argument, the table name, and a second argument, an array of columns to fetch. If you're using an expression, you can specify a 'key' => Expr.
It's really easy to convert a Zend_Db_Select into a SQL string for debugging or use with other functions.
echo $select; // prints SELECT COUNT(*) AS `TotalRecords` FROM `myTable`
This uses a toString method, which is called automatically by Zend_Db fetch methods:
$total = $db->fetchOne($select);
echo $total; //prints the number of rows matching the query
Where $db is an instance of Zend_Db.
Use $select->__toString() method to output your generated query and see what is wrong with it.
If u dont have a from clause in your query add From() method to your select object.
If you use Zend_Db_Select, you have to call the from method to set the table name. With a Zend_Db_Table_Select, the table is passed in the constructor, so you don't need to call from.
$select = $db->select();
$select->from(
'table_name',
array('cnt' => 'count(1)')
);
I just encountered the same issue and found out what is going wrong
the Zend_Db_Select::columns functions expects an Array instead of a Object or String (when the first parameter is an String or Object it'll probably use this as main table for the columns you give but Im not sure about that.).
Changing your code to
$data->TotalRecords = $select->columns(array(new Zend_Db_Expr('COUNT(*)')))->query()->fetch();
Will fix your issue