How to effectively replace (mysql_result(mysql_query()) in PDO? - php

As my process is almost complete for rewriting web with PDO instead of mysql_* commands I am now testing my changed functions. And It seems that my changed function for mysql_result(mysql_query() always returns true, why is that? Lets see original and changed code:
if (mysql_result(mysql_query("SELECT COUNT(*) FROM account WHERE id='".$_SESSION["user_id"]."' AND online=1"), 0)>0)
{
return true;
}
else
return false;
And changed code here:
$stmt = $db_login->prepare("SELECT COUNT(*) FROM account WHERE id=:id AND online=1");
$stmt->bindValue(':id', $_SESSION["user_id"], PDO::PARAM_INT);
$stmt->execute();
$results_login = $stmt->fetch(PDO::FETCH_ASSOC);
$rows = count($results_login);
if ($rows > 0)
{
return true;
}
else
return false;
So what is wrong with is why it always returns true even when column has online=0? Thank you

$stmt->fetch fetches one row from the result set. What you get out of that is an array containing all the selected columns, looking something like this:
array(
'COUNT(*)' => 42
)
A count() on that array will always result in 1.
You need to check the contents of the fetched row:
if ($result_login['COUNT(*)'] > 0)
It's best to alias this column to a nicer name:
SELECT COUNT(*) AS `count` ...
Then:
if ($result_login['count'] > 0)

Related

How to check for existence of specific date in MySQL 'date' column?

Using the code below, I'm having trouble checking whether a specified date exists in a MySQL 'date' column.
$data = array(1367971200);
$s=$dbh->prepare("
SELECT DISTINCT
`date`
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?
");
if ($s->execute($data)) {
if ($s['date'] == null) {
return false;
}
return true;
}
It's returning false, despite the fact that I can see the date '2013-05-08' displayed in phpMyAdmin.
The table itself contains 70+ entries for that date. It always will do, if it contains any at all, but I just want to know whether it exists or not at this stage.
The date field is a MySQL 'date' type. I'm suspecting that the bug is in my structuring of the PDO calling of the query.
UPDATE
Updated $r['date'] to `$s['date']. I suspect that I still have an issue with the structure of that, but probably need to fix the query so that it gives us results before focusing on this.
Also tried running the query against the database directly and got an empty resultset, despite being able to see that the target date exists. Still baffled!
Try this
$data = array(1367971200);
$s=$dbh->prepare("
SELECT COUNT(`date`) as c_date
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?");
if ($s->execute($data)) {
$result = $s->fetch(PDO::FETCH_ASSOC);
if ($result['c_date'] > 0) {
return false;
}
return true;
}
You can't select a whole day with UNIX timestamps because of their more accurate nature (i.e. seconds), you would need the textual version:
$data = array(date('Y-m-d', 1367971200));
$stmt = $dbh->prepare("SELECT COUNT(*)
FROM `report_coa_bal_hist`
WHERE `date` = ?
");
$stmt->execute($data);
$count = current($stmt->fetchAll(PDO::FETCH_COLUMN, 0));
return $count > 0;
Take note of any timezone differences between the server that runs your script and the database server itself.
there are many flaws with your code, not one:
format of the value you are checking
way you are checking in SQL
the way you are getting result
So, the code have to be
$data = array('2013-05-07');
$sql = "SELECT 1 FROM report_coa_bal_hist WHERE `date` = ? LIMIT 1";
$stm = $dbh->prepare($sql);
$stm->execute($data);
return $stm->fetchColumn();

Enumerating over several cells in MySQL DB using PHP

Problem: I have several rows of results, for a single survey. Each survey can have any number of rows in the "Results" Table. There's a column called key_value. It's either 0 or -1. What is the fastest way in PHP to enumerate over several rows in a MySQL database, access each object, and flag a Boolean in PHP to tell me whether or not this particular survey has any rows with a key_value of 0?
something like this, except not brute forcing it...
for (i = 0; i < mysqlrows.length; i++){
if (mysqlrow.key_value == 0)
flag = true;
else
flag = false;
}
To operate on all matching (key_value = 0) Results:
$query = <<<EOD
SELECT result_id
FROM Results
WHERE key_value = 0
EOD;
$pdo = new PDO(....);
$stmt = $pdo->prepare($query);
if ($stmt->execute()) {
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
$result_id = $result['result_id'];
//do something with this result?
}
}
But if you only wanted the number of Results with key_value = 0, use some SQL like:
SELECT COUNT(*) as num_with_zero FROM Results WHERE key_value = 0

Grabbing rows with PDO

I'm attempting at seeing if there is already a row in a table in my database. If there is a row then the php will redirect to a different page. If there isn't a row, it will stay there. Here is the code that I have:
$sched_ex = $db->prepare("SELECT COUNT(1) FROM sched WHERE uid = '$uid'");
$sched_ex->execute();
if($sched_ex == 0) { ... } else { redirect }
I'm new to PDO, not sure what I need to do for it to work properly.
Edit:
$sched_ex = $db->prepare("SELECT COUNT(1) FROM sched WHERE uid = :uid");
$sched_ex->execute(array(':uid' => $uid));
if($sched_ex->fetchColumn() == 0) { a lot of html }
else {
?>
<script langauge="javascript">
window.location="../"
</script>
<?php
}
Header wasn't working, so I used JavaScript. I doubt that's the issue, though.
Firstly, use bound parameters to protect your self against injection attacks:
$sched_ex = $db->prepare("SELECT COUNT(1) FROM sched WHERE uid = :uid");
$sched_ex->execute(array(':uid' => $uid));
Secondly, as for your question:
if($sched_ex->fetchColumn() == 0) { ... } else { redirect }
(See: http://www.php.net/manual/en/pdostatement.fetchcolumn.php)
You can use the rowcount function to find out how many rows there are (if the query returned anything), then you will need to actually fetch he data.
But on that note, from the docs:
For most databases, PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement. Instead, use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned. Your application can then perform the correct action.
You need to fetch the rows after the execute:
$dbh = new PDO($this->mySQLAccessData->hostname, $this->mySQLAccessData->username, $this->mySQLAccessData->password);
$stmt = $dbh->query($sql);
$stmt->setFetchMode(PDO::FETCH_INTO, new kpiData);
$dataCount=0;
foreach($stmt as $kpiData)
{
$arrKPIData[$dataCount]['year']=$kpiData->year;
$arrKPIData[$dataCount]['month']=$kpiData->month;
$dataCount++;
unset($stmt);
}

MySQL & php PDO how to fetch: SELECT EXISTS (SELECT 1 FROM x WHERE y = :value)

I'm using this syntax instead of count (*) because it's supposed to be faster but I dont know how to fetch the resulting output
$alreadyMember = $dataBase->prepare('SELECT EXISTS ( SELECT 1
FROM TheCommunityReachLinkingTable
WHERE communityKey = :communityKey
AND userID = :userID)');
$alreadyMember->bindParam(':communityKey', $_POST['communityKey'], PDO::PARAM_STR);
$alreadyMember->bindParam(':userID', $_POST['userID'], PDO::PARAM_INT);
$alreadyMember->execute();
if($alreadyMember->fetch()) {do code here}
But it doesn't seems to return something correct, any idea?
The use of EXISTS seems wrong here. Just execute this query instead:
SELECT 1
FROM TheCommunityReachLinkingTable
WHERE communityKey = :communityKey
AND userID = :userID
The proper usage is just like normal, capture the return value of fetch()
$row = $alreadyMember->fetch();
print_r($row); // you may have numeric or string indices depending on the FETCH_MODE you set, pick one, consider a column alias and associative
//or the easy way
$alreadyMember->execute();
if ($alreadyMember-fetchColumn()) {
//column 0 contained a truthy value
}

So what IS the best way to check if a row exists? EXISTS, COUNT or num_rows?

If your only goal is to check if a row exists in php (true or false), what is the best way to do it?
Option 1?
$result = mysql_query("SELECT * FROM users WHERE id = '1'");
$num_rows = mysql_num_rows($result);
if ($num_rows == 1)
// one user, like it should be.
else
// do something else
Option 2?
$query = mysql_query("select count(1) from users where id = 1")
if (mysql_result($query, 0) == 1)
// one user, like it should be.
else
// do something else
Option 3?
$query = mysql_query("something like SELECT EXISTS( SELECT */1/COUNT(*)/etc. ...)")
if (mysql_result($query, 0) == 1)
// one user, like it should be.
else
// do something else
Beter option 4?
you name it.
Subquestions
COUNT(*), COUNT(1) or COUNT(id)?
Option 3 is the fastest way to check if a row exists if you are using MySQL:
$query = mysql_query("SELECT EXISTS(SELECT 1 FROM users WHERE id = 1)")
if (mysql_result($query, 0) == 1)
// one user, like it should be.
else
// do something else
I think the question refers more the code itself then the time involved, so using his query:
$result = mysql_query("SELECT * FROM users WHERE id = '1'");
//if result not returned(false) from Mysql return False Else True
//This is just example and you can do anything you need in side the if()
if(!$result) {
//or return some error or redirect to another piece of code
return FALSE;
} else {
//or do some other php/mysql magic
//if there is a result you have the row to work with of needed
return TRUE;
}
mysql_query
...excerpt from PHP manual Return Values
For SELECT, SHOW, DESCRIBE, EXPLAIN and other statements returning
resultset, mysql_query() returns a resource on success, or FALSE on
error.
For other type of SQL statements, INSERT, UPDATE, DELETE, DROP, etc,
mysql_query() returns TRUE on success or FALSE on error.
The EXISTS is faster then SELECT COUNT(*) because the subquery will stop searching when it finds one row. It won't have to find them all and count them. It will return either 0 or 1:
SELECT EXISTS
( SELECT * FROM ... )

Categories