I am running 2 queries, the first one goes through correctly and returns the desired value, but the second one returns false.
I have set $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); so I should be getting an exception over false, so I am guessing that my $stmt->execute(); is the culprit here.
As that's the only function that can return false now that I've set the error attribute.
I have also tried setting $stmt->closeCursor();, $stmt = null;, and unset($stmt); with no avail.
This executes two queries (both "darkrp" and "pointshop" in the fetch_wallet() function.
if($this->pdo) {
foreach($this->methods as $method => $bool) {
if($bool) { $array[$method] = $this->fetch_wallet($method); }
}
}
This is the fetch_wallet() function:
public function fetch_wallet($type) {
if($type == "darkrp") {
$query = "SELECT `wallet` FROM `darkrp_player` WHERE uid=:uid LIMIT 1";
}
elseif ($type == "pointshop") {
$query = "SELECT `points` FROM `pointshop_data` WHERE uniqueid=:uid LIMIT 1";
}
try {
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(":uid" => $this->uniqueid));
$result = $stmt->fetchColumn();
return $result;
}
catch (PDOException $e) {
return $e->getMessage();
}
}
When I run var_dump($stmt->errorInfo()); I get this, which means that both queries runs fine, although the last one returns false when it should return 440. No exception is thrown.
array(3) {
[0]=> string(5) "00000"
[1]=> NULL
[2]=> NULL
}
array(3) {
[0]=> string(5) "00000"
[1]=> NULL
[2]=> NULL
}
Printed screen of the pointshop_data table in phpMyAdmin (I want the 440 value there):
Value returned from var_dump($this->uniqueid); is 3266928646
I have debugged everything, and I get no errors whatsoever, just a false.
PHP Version: 5.3.10
MySQL Version: 5.5.38
OS: Ubuntu 12.04 LTS
I think there must be some other error in your class that makes this code does not work.
I've imported your tables structure and created the following testing code:
<?php
class A
{
private $pdo;
private $uniqueid;
private $methods = ['darkrp' => true, 'pointshop' => true];
public function __construct($pdo, $uniqueid)
{
$this->pdo = $pdo;
$this->uniqueid = $uniqueid;
}
public function fetch_wallet($type)
{
if ($type == "darkrp") {
$query = "SELECT `wallet` FROM `darkrp_player` WHERE uid=:uid LIMIT 1";
} elseif ($type == "pointshop") {
$query = "SELECT `points` FROM `pointshop_data` WHERE uniqueid=:uid LIMIT 1";
}
try {
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(":uid" => $this->uniqueid));
$result = $stmt->fetchColumn();
return $result;
} catch (PDOException $e) {
return $e->getMessage();
}
}
public function run()
{
if ($this->pdo) {
foreach ($this->methods as $method => $bool) {
if ($bool) {
$array[$method] = $this->fetch_wallet($method);
var_dump($array[$method]);
}
}
}
}
}
$pdo = new PDO('mysql:host=localhost;dbname=tests', 'root', '');
$a = new A($pdo, 3266928646);
$a->run();
The result I get for this is:
string(4) "2075" string(3) "440"
So it is working as it should.
Please try this code (that's the whole file - of course you need to change your db name, user and password) and check if it gets you the same results. If yes, probably you have other errors in your class.
Change
$stmt->execute(array(":uid" => $this->uniqueid));
to
$stmt->bindValue(':uid', $this->uniqueid);
$stmt->execute();
Related
This is a snapshot of the code I am struggling with in php. I have a database object, an activity class and a booking form. From the booking form I pass three variables to the check availability method which queries the database. The var dump is returning:
object(DB)#3 (6) { ["_pdo":"DB":private]=> object(PDO)#4 (0) { } ["_query":"DB":private]=>
object(PDOStatement)#6 (1) { ["queryString"]=> string(99) "SELECT * FROM `activity` WHERE name =
'Archery' AND act_date = '05/01/2015' AND time_from = '10.00'" } ["_error":"DB":private]=>
bool(false) ["_results":"DB":private]=> array(0) { } ["_count":"DB":private]=> int(0)
["_data":"DB":private]=> NULL }
This makes me think that the query is not returning something yet the query does return records in MySQL. Any help would be greatly appreciated.
1. Calling method to check availability:
if($activity->checkDateTimeAvailability($act_name, $date, $time) === false)){
// Do something here
}
//Method to check if the activity is available at the requested date and time:
public function checkDateTimeAvailability($name, $date, $time) {
$result = $this->_db->query("SELECT * FROM `activity` WHERE name =
'$name' AND act_date = '$date' AND time_from = '$time'");
if(!empty($result)){
echo "query successful";
var_dump($result);
return true;
} else {
return false;
}
}
//Generic query method:
public function query($sql, $params = array()) {
// reset to ensure an error from a previous query is not returned.
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
First of all, NEVER use variables in a SQL query, use prepare statements.
To you question. The PDO::query method returns a PDOStatement object. With this object you can fetch the result from the database server.
Just call $this->_db->query('Your SQL query')->fetchAll() and you get your rows.
Hi all I think I designed my pdo mysql class rather badly, as I'm not able to put a query inside a while loop of another query because the new query inside the loop wipes out the old one, is there an easy way to fix this?
I'm too used to the really old style of php/mysql where you make a query, then assign that query inside the fetch($query) which you don't do with PDO. This has me in a muddle and it's been bugging me for too long.
My Code cut to the relevant parts
class mysql
{
// the query counter
public $counter = 0;
// the database connection
public $database;
// statement handler
public $STH;
// store all the queries for debugging
public $queries = '';
public function __construct($database_host, $database_username, $database_password, $database_db)
{
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$this->database = new PDO("mysql:host=$database_host;dbname=$database_db", $database_username, $database_password, $options);
$this->database->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
// A plain query
public function pquery($sql, $page = NULL)
{
global $core;
try
{
$this->STH = $this->database->prepare($sql);
$this->counter++;
$this->queries .= "<br />$sql";
return $this->STH->execute();
}
catch (Exception $e)
{
$core->message("Something went wrong. The admin will be notified and punished muhahaha for I am an evil overlord...I'm sure I will be fixed soon.", NULL, 1);
$this->pdo_error($e->getMessage(), $page, $sql);
}
}
// the main sql query function
public function sqlquery($sql, $objects = array(), $page = NULL, $referrer = NULL)
{
global $core;
try
{
$this->STH = $this->database->prepare($sql);
foreach($objects as $k=>$p)
{
// +1 is needed as arrays start at 0 where as ? placeholders start at 1 in PDO
if(is_numeric($p))
{
// we need to do this or else decimals always seem to end up 'x.00', pdo has no decimal check, odd
if ($this->contains_decimal($p) == true)
{
$this->STH->bindValue($k+1, $p, PDO::PARAM_STR);
}
else
{
$this->STH->bindValue($k+1, (int)$p, PDO::PARAM_INT);
}
}
else
{
$this->STH->bindValue($k+1, $p, PDO::PARAM_STR);
}
}
$this->counter++;
$this->queries .= "<br />$sql";
return $this->STH->execute();
}
catch (Exception $e)
{
$core->message("Something went wrong. The admin will be notified and punished muhahaha for I am an evil overlord...I'm sure I will be fixed soon.", NULL, 1);
$this->pdo_error($e->getMessage(), $page, $sql, $referrer);
}
}
public function fetch()
{
$this->STH->setFetchMode(PDO::FETCH_ASSOC);
return $this->STH->fetch();
}
I'm newbie in PHP and WordPress. This approach was working fine for me in ASP.NET but here both queries are not working. When I comment the first one, the second one(Insertion) is working fine.
$dbhostname="111.1.11.111";
$dbusername="db_userName";
$dbpassword="mypassword";
$con=mysqli_connect($dbhostname,$dbusername,$dbpassword,"db_name");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
Check wether the email exists or not ?
$sql="CALL Select_ConfirmEmailExistance('abc#abc.com')";
$containsResult=0;
if ($result=mysqli_query($con,$sql))
{
// Get field information for all fields
while ($fieldinfo=mysqli_fetch_assoc($result))
{
if (isset($fieldinfo)) {
$containsResult=1;// Email Exists
}
}
mysqli_free_result($result);
if ($containsResult==0) { // In case email does not exists enter it.
$sql="CALL insert_Userinfo('abc','def','abc#abc.com','mnop')";
if ($result=mysqli_query($con,$sql))
{
$data;
while ($fieldinfo=mysqli_fetch_assoc($result))
{
$data[]=$fieldinfo;
}
}
}
print_r($data);
}
mysqli_close($con);
First Store Procdure
BEGIN
SELECT 1 as emailstatus FROM userinfo WHERE email= p_email;
END
Second Stored Procedure
INSERT INTO `userinfo` (
`first_name`,
`last_name`,
`email`,
`password`
)
VALUES
(
`FName`,
`LName`,
`Email`,
`Pass`
);
SELECT
user_id
FROM
userinfo
ORDER BY
user_id DESC
LIMIT 1;
Here is what I was talking about when I said create a query class to fetch data. This is just a simple one, but it works pretty effectively and you can build it out to be pretty powerful.
class DBEngine
{
public $con;
public function __construct($host="111.1.11.111",$db = "dbname",$user="db_userName",$pass="mypassword")
{
try {
$this->con = new PDO("mysql:host=$host;dbname=$db",$user,$pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
}
catch (Exception $e) {
return 0;
}
}
// Simple fetch and return method
public function Fetch($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
if($query->rowCount() > 0) {
while($rows = $query->fetch(PDO::FETCH_ASSOC)) {
$array[] = $rows;
}
}
return (isset($array) && $array !== 0 && !empty($array))? $array: 0;
}
// Simple write to db method
public function Write($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
}
}
// Create an instance of the engine
$query = new DBEngine();
// Query 1 will return an array or false (0)
$call1 = $query->Fetch("CALL Select_ConfirmEmailExistance('abc#abc.com')");
// Assign your true/false
$containsResult = ($call1 !== 0)? 1:0;
// Run second query and return array or false (0)
if($containsResult == 0)
$data = $query->Fetch("CALL insert_Userinfo('abc','def','abc#abc.com','mnop')");
// Display returned result
print_r($data);
It is quite simple. Your code is fine but you only have to create two separete functions and simply call those functions instead of the code directly.
I have a class which works fine with php 5.3 (XAMPP 1.7.3, windows 7) but doesn't work in my server(php 5.2.17 - Safe mode On):
<?php
class MYSQL_DB {
var $connection;
function MYSQL_DB() {
$this->connection = mysql_connect(S, U, P) or die('Can\'t connect to MySQL server.');
mysql_select_db(DB, $this->connection) or die(mysql_error());
}
function getJobs($wid) {
$q = "SELECT * FROM " . TB_PREFIX . "joblist where owner = {$wid} order by ID ASC";
$result = mysql_query($q, $this->connection);
$ret = $this->mysql_fetch_all($result);
mysql_free_result($result);
return $ret;
}
function mysql_fetch_all($result) {
$all = array();
if ($result) {
while ($row = mysql_fetch_assoc($result)) {
$all[] = $row;
}
return $all;
}
}
}
$db=new MYSQL_DB();
?>
And in another file, I used getjobs function:
<?php
$tempbJobs=$db->getJobs(1368);
var_dump($tempbJobs);
?>
when I use var_dump right before return $ret; in getjobs function, it shows me correct values, but var_dump($tempbJobs); will print NULL.
P.S: I simplified the code, it works on my localhost but not on production server.
P.S: If I change return $ret; to return 'DUMPED'; , returned value would be string(6) "DUMPED"
var_dump($ret ); output:
array(2) {
[0]=>
array(5) {
["id"]=>
string(5) "10755"
["owner"]=>
string(5) "23626"
["field"]=>
string(1) "6"
["type"]=>
string(1) "2"
["expi"]=>
string(10) "1372144648"
}
[1]=>
array(5) {
["id"]=>
string(5) "10756"
["owner"]=>
string(5) "23626"
["field"]=>
string(1) "5"
["type"]=>
string(1) "2"
["expi"]=>
string(10) "1372144654"
}
}
Based on the fact that you only return $all from the function mysql_fetch_all($result) if $result is true I have to assume that the mysql_query() is returning false.
After the call to
$result = mysql_query($q, $this->connection);
Can you add this
$result = mysql_query($q, $this->connection);
if ( ! $result ) {
echo "ErrorNo: " . mysql_errno() . " Error Message: " . mysql_error();
}
This might help identify what the problem actually is as it has to be a database error of some sort.
Could you check that your constants S, U, P, TB_PREFIX are defined() and they have values.
Also modify your function mysql_fetch_all to return response anyway:
function mysql_fetch_all($result) {
$all = array();
if ($result) {
while ($row = mysql_fetch_assoc($result)) {
$all[] = $row;
}
}
return $all;
}
I reviewed all your comments.
In one of your comments you said that return is not working but I think it is working properly because you already said in one of your comments that when you print out the result before return $ret it gives you the correct result.
fact : mysql_fetch_all($result) also returning result.
checkout the sql code : $q = "SELECT * FROM " . TB_PREFIX . "joblist where owner = {$wid} order by ID ASC"; I do not know {$wid} what it is.
Test it
$q = "SELECT * FROM " . TB_PREFIX . "joblist where owner = '$wid' order by ID ASC";
try after defining array for $ret in the function getjobs()
$ret=array(); //try
I know this is a little bit rusty question but yet still interesting. Are you able to found solution on that ?
If same code doesn't work on different server i would have suspected in that case memory limit. Try to increase php memory limit.
And it could be wise to check phpinfo(); on both servers to compare differences.
I seem to have problem getting affected_rows when I INSERT and SELECT, it just returns -1 for some reason? I'm using a database class which I use all the time for my projects which uses MYSQLI prepare statements to avoid SQL injections.
Does anyone know why it returns -1 all the time? From what I have read it should be able to return affected rows on both INSERT and SELECT.
Database class
class database {
protected $_mysqli;
protected $_debug;
public function __construct($host, $username, $password, $database, $debug) {
$this->_mysqli = new mysqli($host, $username, $password, $database);
$this->_debug = (bool) $debug;
if (mysqli_connect_errno()) {
if ($this->_debug) {
echo mysqli_connect_error();
debug_print_backtrace();
}
return false;
}
return true;
}
public function q($query) {
if ($query = $this->_mysqli->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_merge(array(func_get_arg(1)),
array_slice($x, 2));
$args_ref = array();
foreach($args as $k => &$arg) {
$args_ref[$k] = &$arg;
}
call_user_func_array(array($query, 'bind_param'), $args_ref);
}
$query->execute();
if ($query->errno) {
if ($this->_debug) {
echo mysqli_error($this->_mysqli);
debug_print_backtrace();
}
return false;
}
if ($query->affected_rows > -1) {
return $query->affected_rows;
}
$params = array();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($query, 'bind_result'), $params);
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
} else {
if ($this->_debug) {
echo $this->_mysqli->error;
debug_print_backtrace();
}
return false;
}
}
public function handle() {
return $this->_mysqli;
}
public function last_insert_id()
{
return $this->_mysqli->insert_id;
}
public function found_rowss()
{
return $this->_mysqli->affected_rows;
}
}
for Select-statements created with prepare you should use $query->num_rows() or mysqli_stmt_num_rows($query).
The Insert-Statement may give you supressed errors when you do a "INSERT IGNORE" which may lead to the -1 in $query->affected_rows().
A comment on php.net (second link) suggests you use $query->sqlstate=="00000" to check for errors.
see php.net (manual/en/mysqli-stmt.affected-rows):
"This function only works with queries which update a table. In order to get the number of rows from a SELECT query, use mysqli_stmt_num_rows() instead."
and php.net (manual/en/mysqli.affected-rows):
"Checking if mysqli->affected_rows will equal -1 or not is not a good method of determining success of "INSERT IGNORE" statements. Example: Ignoring duplicate key errors while inserting some rows containing data provided by user only if they will match specified unique constraint causes returning of -1 value by mysqli->affected_rows even if rows were inserted. (checked on MySQL 5.0.85 linux and php 5.2.9-2 windows). However mysqli->sqlstate returns no error if statement was executed successfully."