I have a query that works in phpmyadmin however does not work in my code! I have tried various variable dumps to see if I have been loosing data before the query is executed, all seems ok, the same variables contents I have used in the successful query in phpmyadmin
To test I replaced:
$account_id = $account->getAccountId(); //output below
string(2) "59" string(4) "main" NULL NULL array(2) { ["id"]=> NULL["name"]=>NULL}
With
$account_id = 59; //output below
int(59) string(4) "main" NULL NULL array(2) { ["id"]=> NULL ["name"]=> NULL }
below is the code extract and I am using mysqli:
$account = $Add_Profile_Image->getUserAccount();
$account_id = $account->getAccountId();
$status = $account->getType();
var_dump($account_id);
var_dump($status);
$conn = $this->create_connection('read');
$stmt = $conn->prepare('SELECT add_profile_images.image_id, image_name FROM add_profile_images, users_profile_images WHERE users_profile_images.account_id=? AND users_profile_images.status=?');
$stmt->bind_param('is',$account_id,$status);
$stmt->bind_result($id,$imageName);
$stmt->execute();
var_dump($id);
var_dump($imageName);
$result['id'] = $id;
$result['name'] = $imageName;
I have replaced
image_name //in the query
To
add_profile_images.image_name //in the query
but the result is still NULL?
So I have tried the following examples in this post: PHP Prepared Statement Returns -1
When I dump the mysqli object it does return -1 however when I implement the below no errors
are shown!
if($conn->connect_error) {
printf('connect error (%d) %s', $conn->connect_errno, htmlspecialchars($conn->connect_error));
die;
}
$stmt = $conn->prepare('SELECT add_profile_images.image_id, add_profile_images.image_name FROM add_profile_images, users_profile_images WHERE users_profile_images.account_id=? AND users_profile_images.status=?');
if ( false===$stmt ) {
printf('prepare failed: %s', htmlspecialchars($conn->error));
die;
}
$rc = $stmt->bind_param('is',$account_id,$status);
if ( false===$rc ) {
printf('bind_param failed: %s', htmlspecialchars($stmt->error));
die;
}
$rc= $stmt->execute();
if ( false===$rc ) {
printf('execute failed: %s', htmlspecialchars($stmt->error));
die;
}
$rc = $stmt->bind_result($id,$imageName);
if ( false===$rc ) {
printf('bind_result failed: %s', htmlspecialchars($stmt->error));
die;
}
Where am I going wrong?
Hope someone can help!
Thanks
You need to state $stmt->bind_result() AFTER $stmt->execute()
(see: http://php.net/manual/en/mysqli-stmt.bind-result.php)
I Had the same problem the reason for that is closing the connection when using the statement prepare. make sure, in your flow there is no such closing of the connection
Related
I am using json_decode() to decode an Ajax result which returns the below array (shortened example).
Now I want to loop through this area and to update the rId for each vId as per the values from the array but this part does not work.
Can someone show me how to do the loop part correctly here (the query itself should be ok) ?
My array:
array(3) {
[0]=>
array(2) {
["vId"]=>
string(8) "04567901"
["rId"]=>
string(6) "DE-003"
}
[1]=>
array(2) {
["vId"]=>
string(8) "04567902"
["rId"]=>
string(6) "DE-008"
}
[2]=>
array(2) {
["vId"]=>
string(8) "04567903"
["rId"]=>
string(6) "DE-009"
}
}
My PHP / MySQLi:
$postData = $_POST;
$transferData = $_POST['transferData'];
$json = json_decode($transferData, true);
$conn = new mysqli($host, $username, $password, $database);
if($conn->connect_error) {
die("Connection Error: " . $conn->connect_error);
}
$stmt = $conn->prepare("UPDATE locations l SET l.rId = ? WHERE l.vId = ?");
foreach($json as $vId => $rId) {
$stmt->bind_param('ss', $rId, $vId);
$stmt->execute();
}
$stmt->close();
$conn->close();
In your foreach, the key refers to the index of the array rather than what you consider the key to be. The keys in your case are actually 0, 1, 2, [...].
You return an array of arrays, so get the parts you want as follows:
foreach($json as $key => $value) {
$stmt->bind_param('ss', $value['rId'], $value['vId']);
$stmt->execute();
}
function update_review($link, $user_id, $game_id, $rating, $title, $review) {
$sql = "UPDATE reviews SET rating = ?, title = ?, review = ? WHERE user_id = ? AND game_id = ?";
$stmt = $link->prepare($sql);
if ( !$stmt ) {
die("could not prepare statement: " . $link->errno . ", error: " . $link->error);
}
$stmt->bind_param("sssii", $rating, $title, $review, $user_id, $game_id);
if ( !$stmt ) {
die("could not bind params: " . $stmt->error);
}
if ( !$stmt->execute() ) {
die("couldn't execute statement");
}
}
function update_review2($link) {
$sql = "update reviews set rating = \"43\", title = \"test\", review = \"blah\" where user_id = \"5\" and game_id = \"1\"";
$stmt = $link->prepare($sql);
if ( !$stmt ) {
die("could not prepare statement: " . $link->errno . ", error: " . $link->error);
}
if ( !$stmt->execute() ) {
die("couldn't execute statement");
}
}
var_dump($review_data);
// output = array(5) { ["user_id"]=> int(5) ["game_id"]=> int(1) ["rating"]=> string(2) "43" ["title"]=> string(4) "test" ["review"]=> string(4) "blah" }
update_review($link, $review_data['rating'], $review_data['title'], $review_data['review'], $review_data['user_id'], $review_data['game_id']);
Going to be honest, done the usual uni student thing and left the assignment to last min and regretting it again...
Anyways been trying to figure this out for a few hours now and i've come to a loss, ive made it work by not using prepared statements as you can see above in the update_review2 function however when using the prepared statements version update_review it does not affect any rows in the db. If anyone can offer a bit of help it will be greatly appreciated especially because the deadline is in 6 hours!
Based on your above code the function call to update_review() has variables in one order while the function itself is declared with variables in another order.
Because of that, you might be passing a string when the statement is expecting an int.
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();
I want to make a the following thing happen in PHP PDO OOP
$conn = mysqli_connect("localhost", "root", "blogger.g", "test");
$query = mysqli_query($conn, "SELECT * FROM users WHERE username='sandeep'");
$row = mysqli_fetch_assoc($query);
echo $row['password'];
The code which I use in the OOP way is as follows
class getResults{
public $results;
public function start(){
try {
$DTH = new PDO("mysql:host=127.0.0.1;dbname=test", "root", "blogger.g");
$STH = $DTH->query("SELECT * FROM users WHERE username='sandeep'");
$results = $STH->fetchAll(PDO::FETCH_OBJ);
return $results;
} catch (PDOException $e){
return $e->getMessage();
}
}
}
var_dump(getResults::start());
I got the following output
array(1) { [0]=> object(stdClass)#3 (3) { ["id"]=> string(1) "1" ["username"]=> string(7) "sandeep" ["password"]=> string(8) "password" } }
And How Should I access each of the properties ??
You can access each row if you loop through the object with a while()-loop, for example.
while($row = getResults::start()) {
echo $row->id;
}
One last tip: If you're already using PDO, use Prepared Statements. For your safety.
Since your query yields a single row, don't use fetchAll:
$results = $STH->fetch(PDO::FETCH_OBJ);
would suffice. Now, store the returned value inside a variable:
$x = getResults::start();
Since, $x is a class object, you can access its members by -> operator:
echo $x->username . "\n" . $x->password;
Alternatively, you can use PDO::FETCH_ASSOC:
$results = $STH->fetch(PDO::FETCH_ASSOC);
$x = getResults::start();
echo $x['username'] . "\n" . $x['password'];
I am trying to understand the difference between mysqli's query() and prepare(). I have code like below, and I would like to get the same results from both. However the prepare() does not work as expected. why?
// this works
if ($query = $this->db->query("SELECT html FROM static_pages WHERE page = 'cities'")) {
$result = $query->fetch_row();
echo $result[0];
$query->close();
}
//this does not work
//result is empty
$cities = 'cities';
$stmt = $this->db->prepare("SELECT html FROM static_pages WHERE page = ?");
$stmt -> bind_param("s", $cities);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
echo $result;
$stmt->close();
$this->db->close();
these are my server configs as requested:
OS
Vista 64bit / PHP Version 5.2.9
mysqli
MysqlI Support enabled
Client API library version 5.0.51a
Client API header version 5.0.51a
MYSQLI_SOCKET /tmp/mysql.sock
Directive Local Value Master Value
mysqli.default_host no value no value
mysqli.default_port 3306 3306
mysqli.default_pw no value no value
mysqli.default_socket no value no value
mysqli.default_user no value no value
mysqli.max_links Unlimited Unlimited
mysqli.reconnect Off Off
Can you try $stmt->store_result(); between $stmt->execute(); and $stmt->bind_result($result); ?
Any of the mysqli_* functions can fail. In this case the return value is false and the error/errno properties of the mysqli or mysqli_stmt object contains more information about the error. The script has to test each and every return value and react appropriately on error condition (e.g. it doesn't make sense to prepare the statement if the connection failed).
<?php
$foo = new Foo;
$foo->init();
$foo->bar();
class Foo {
public function bar() {
$cities = 'cities';
$stmt = $this->db->prepare("SELECT html FROM soTest WHERE page = ?");
if ( !$stmt ) {
echo "prepare failed\n";
echo "error: ", $this->db->error, "\n";
return;
}
$rc = $stmt->bind_param("s", $cities);
if ( !$rc ) {
echo "bind_param failed\n";
echo "error: ", $stmt->error, "\n";
return;
}
$rc=$stmt->execute();
if ( !$rc ) {
echo "execute failed\n";
echo "error: ", $stmt->error, "\n";
return;
}
$rc = $stmt->bind_result($result);
if ( !$rc ) {
echo "bind_result failed\n";
echo "error: ", $stmt->error, "\n";
return;
}
$rc = $stmt->fetch();
if ( !$rc ) {
echo "no such record\n";
}
else {
echo 'result: ', $result, "\n";
}
$stmt->close();
}
public function init() {
$this->db = new mysqli('localhost', 'localonly', 'localonly', 'test');
if ($this->db->connect_error) {
die('connection failed: ' . $this->db->connect_error);
}
$rc = $this->db->query('CREATE TEMPORARY TABLE
soTest (id int auto_increment, html varchar(16), page varchar(16),primary key(id))'
);
if ( !$rc ) { die('error: '.$this->db->error); }
$rc = $this->db->query("INSERT INTO soTest (html,page) VALUES ('htmlFoo','foo'),('htmlCities','cities')");
if ( !$rc ) { die('error: '.$this->db->error); }
}
}
Keep CWE-209: Information Exposure Through an Error Message in mind. Printing the actual error message in my example script is only for testing. And you might use a slightly more sophisticated error handling than just die().
Should be echo $result; not echo $results;