CRUD using prepare statement not working. - php

Database connecting is working. The SELECT AND UPDATE FUNCTION in the class is not working at all.It is not even showing errors to help me sort out the problem. I am trying to learn how to use the prepare ,bind-param and execute statement. Please can someone help look at the codes and advise what may be wrong with it. Just spent loads of hours on this and just cant figure where the problems is. please can some help me.I am a novice and writing my very first codes . Many thanks in advance
<?php class connect_dbase{
public $mysqli;
public function connection($host="localhost",$user="root",$password="london",$db_name="users")
{
$this->mysqli=new mysqli($host,$user,$password,$db_name);
if ($this->mysqli->connect_error) {
die('Connect Error: ' . $this->mysqli->connect_error);
}
else{
echo " Database connection successful";
}
}
public function display_all($id){
if($stmt = $this->mysqli->prepare("SELECT * FROM user WHERE id =?")){
/* bind parameters for markers */
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
if($stmt->num_row() >0){
echo 'Total results: ' . $resultrol->num_rows;
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['name'];
echo $row['email'];
echo $row['address'];}
}
else { echo "no result found";}
}
else
{
echo "cant prepare result";
}
}
public function update_post($name, $address,$email,$mob,$id)
{
$up="UPDATE user SET name=?, address =?,email=?,mobile=? WHERE id =?";
if($stmt=$mysqli->prepare($up))
{
$stmt->bind_param("sssii", $name, $address,$email,$mob,$id);
if($stmt->excute()) {
echo " post updated";
header('location:index.php');
}
else
{
echo "post not executed";
}
}else{ echo " cannot prepare statement";}
}
}
$connect_dbase=new connect_dbase();
$connect_dbase->connection();
$connect_dbase->display_all(2);
$connect_dbase-> update_post("john","kkkkk","kkk#yahoo.com",98765,2);
// These 2 functions- $connect_dbase->display_all(2); and
$connect_dbase-> update_post("john","kkkkk","kkk#yahoo.com",98765,2); are not working when called from the class above .
?>

I agree with #MikeBrant's comments. You should make the connection happen in the constructor if you want to be assured that the connection is successful before you try to call it.
Here's another tip:
if($stmt->num_row() >0){
Note that num_rows() doesn't return anything useful until after the client has fetched the rows. So calling it right after execute() is pretty much guaranteed to make it return the wrong number.
You need to use mysqli::store_result() to transfer the result set from the server to the client, and then num_rows() will work. But be careful if the result set is very large, it could use too much memory.

Taking into account the input from Mike and Bill I have modified your code to make it functional. It could use some more work but it should give you a starting point at the very least. I created a test database with three fields, id, name and email but you should be able to plug in your own database and fields and have it still work.
<?php
class connect_dbase {
public $mysqli;
public function connection($host="localhost",$user="root",$password="",$db_name="test")
{
$this->mysqli=new mysqli($host,$user,$password,$db_name);
if ($this->mysqli->connect_error) {
die('Connect Error: ' . $this->mysqli->connect_error);
} else {
// return a true value here if successful, that way you can check
// if your connection was established
return true;
}
}
public function display_all($id){
if($stmt = $this->mysqli->prepare("SELECT * FROM test WHERE id =?")) {
// some minor changes to the bind and execute statments. I
// wrapped them in an if just to make sure there were no errors
// if i had more time i might make these more elegant rather than just
// echoing them out
/* bind parameters for markers */
if(!($stmt->bind_param('i',$id))) {
echo $stmt->error;
}
/* execute query */
if(!($stmt->execute())) {
echo $stmt->error;
}
// You could also bind the results to specific variables here and return those
//$stmt->bind_result($id,$name,$email);
//$stmt->fetch();
//$result = $name;
//assign the results to a variable and then return that variable
//rather than processing the results here
$result = $stmt->get_result();
return $result;
} else {
// if an error occurs return the error, once again another place for
// improvement but at the very least will show you an error
echo $this->mysqli->error;
}
}
public function update_post($name, $email, $id)
{
$up="UPDATE test SET name=?, email=? WHERE id =?";
// originally had $mysqli->prepare($up), fixed syntax
if($stmt = $this->mysqli->prepare($up))
{
//$stmt->bind_param("sssii", $name, $address,$email,$mob,$id);
$stmt->bind_param("ssi", $name, $email,$id);
// execute was spelled wrong
if($stmt->execute()) {
return true;
} else {
return $stmt->error;
//return false;
}
} else {
return false;
}
}
}
// set up database connection
$connect_dbase = new connect_dbase();
if($connect_dbase->connection()) {
// if connection was successful, call display_all
// and assign the results to $result
$result = $connect_dbase->display_all(2);
// you could do a foreach here also but since there
// was only one result i just echoed the values
while($row = $result->fetch_array()) {
echo $row['id'] . "<br/>";
echo $row['name'] . "<br/>";
echo $row['email'] . "<br/>";
}
// then call update_post
$update_result = $connect_dbase->update_post("asdf","asdf#yahoo.com",2);
// show a message if the update_post was successful
if($update_result) {
echo "Update successful";
}
}
?>
I commented the areas I switched around so you have an idea of what I did.

Related

Ran into an error when creating a Prepared statement to login PHP

I keep running into the error where PHP says "We're sorry we can't log you in." according to one of my conditions set even if login is correct and hence my Prepared system to avoid SQL injection fails.
So my code goes like this:
global $connected;
$post = filter_var_array($_POST, FILTER_SANITIZE_STRING);
$pwwd = $post['password'];
$usrn = $post['username'];
$usrn = mysqli_real_escape_string($connected, $usrn);
$pwwd = mysqli_real_escape_string($connected, $pwwd);
if (strlen($usrn) != 0 && strlen($pwwd) != 0 && !empty($post)) {
$usrn = stripslashes($usrn);
$pwwd = stripslashes($pwwd);
$hashFormat = '$2ysomenumber$';
$salt = 'somehashobviously';
$hashF_and_salt = $hashFormat.$salt;
$pwwd = crypt($pwwd, $hashF_and_salt);
if (!mysqli_connect_errno()) {
mysqli_select_db($connected, 'someDbname') or die('Database select error');
} else {
die('Failed to connect to PHPMyAdmin').mysqli_connect_error();
}
$query = "SELECT Username, Password FROM users WHERE Username=? AND Password=?";
$stmt = mysqli_stmt_init($connected);
if (mysqli_stmt_prepare($stmt, $query)) {
//Some error in here somewhere
mysqli_stmt_bind_param($stmt, "ss", $usrn, $pwwd);
mysqli_stmt_execute($stmt);
mysqli_stmt_fetch($stmt);
mysqli_stmt_bind_result($stmt, $check_usrn, $check_pwd);
if (strcasecmp($usrn, $check_usrn) == 0) {
if ($pwwd == $check_pwd) {
echo '<h1 class="text-center">Matches</h1>';
print_r($row);
}
} else {
echo "<h1 class=text-center>We're sorry we can't log you in.</h1>";
}
}
} else { //This is for strlen boolean cond
echo "<h1 class='text-center'>Both fields must not be empty. </h1>";
}
I used to use a login page without prepared statements which was working, but I realised I need to do this for better security. My database is working fine so the problem is near where I added the comment "//Some error in here somewhere".
I am a relatively new PHP programmer that is yet a first year student trying daring new things in the holidays! Will openly read all the help I get, thank you!
First i didn't see your connection code for connection to the database which is like this.
$connected = msqli_connect(host,user,password,db_name) ; than you don't need to call mysqli_select_db()function.
Secondly you are checking your connectinon from mysqli_connect_errno() function which return 0 as integer (not boolean) if no error code value for last mysqli_connect() function.
Third there is no need to Initializes prepare statement.
Fourth is mysqli_stmt_bind_reslut() comes before the mysqli_stmt_fetch(). see note point in manual
Use hash_equals() function to match password instead of ===. see the warning section in crypt
$connected = msqli_connect(host,user,password,db_name) ;
if(!$connected)
{
die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
}
echo "Your connection is successful . "
if($stmt = mysqli_prepare($connected,$query))
{
mysqli_stmt_bind_param($stmt, "ss", $usrn, $pwwd);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $check_usrn, $check_pwd);
mysqli_stmt_fetch($stmt);
/* Now do Your Work */
} else
{
/* still prepare statement doesn't work */
} `

Prepared Statement Not working

if have a piece of code that is to hard for me to solve.. And i don't know how i can find the error more than this.
while($this->_pathLus != $this->hoofdMap) { //loop works fine, tested and confirmd
echo $this->_pathLus . 0; //$this->_pathLus = <data4>
if ($stmtToegang = $db->prepare("SELECT <data>, <data2> FROM `<data3>` WHERE <data> = ? LIMIT 5")) {
$stmtToegang->bind_param("s",$this->_pathLus);
$stmtToegang->execute();
$stmtToegang->bind_result($<data>, $<data2>);
while ($stmtToegang->fetch()) {
echo $<data> . 1;
echo $stmtToegang->error . 2;
}
} else { //to be sure if-stmt-prep is FALSE
echo $stmtToegang->error . 3;
}
$this->_pathLus = preg_replace("/(.*)\/(.*)\/(.*)\//", "$1/$2/", $this->_pathLus); // part of Loop and works
}
What i did to find solution:
check if $stmtToegang is correct everywhere
check if the sql-select is correct
Check if _pathLus is correct
add else on if-stmt-prep to make sure is failed
Results:
<data4>03<data4>03<data4>03<data4>03<data4>03
<data4>03<data4>03<data4>03
<data4>03<data4>03<data4>03<data4>03
<data4>03<data4>03
<data4>03
<data4>03<data4>03
Note: <data>, <data2>, <data3> are replacements for this example
Thanks in advance
Edit: Correction
Edit:
mysqli_prepare() returns a statement object or FALSE if an error
occurred.
But how get the error that Happens ?
How i did find the problem:
i altered echo $stmtToegang->error . 3; into echo $db->error . 3;
This way i found the following error:
Commands out of sync; you can't run this command now
Where i found a solution:
Answer here on SO
Problems was that this stmt-query (select type) was a part of another stmt-query (select type) because:
mysqli uses unbuffered queries by default (for prepared statements;)
So my code to debug a nested prepared statement (select-type) is as followed :
if($stmt = $mysqli->prepare($sql)) {
<$stmt->bind_param()->execute()->bind_result() code>
$stmt->store_result(); // store them !important
while ($stmt->fetch()) {
//code
if($stmt2 = $mysqli->prepare($sql)) {
<$stmt2->bind_param()->execute()->bind_result() code>
$stmt2->store_result(); // store them !important
while ($stmt2->fetch()) {
//code
}
$stmt2->free_result(); // free them
$stmt2->close(); // close them
echo $stmt2->error; // report error
} else {
echo $mysqli->error; // report error
}
}
$stmt->free_result(); // free them
$stmt->close(); // close them
echo $stmt->error; // report error
} else {
echo $mysqli->error; // report error
}
//edit: <$stmt->bind_param()->execute()->bind_result() code> for an better view
Hope it can help somone

How to work with data from mysql in php-multidimensional array

I get null values when I run this code
$dataArray = mysql_query ("SELECT * from _$symbol order by date DESC limit 10;");
while ($ArrayData = mysql_fetch_assoc($dataArray)) {
$dayData [] = $ArrayData;
}
$todaysdate = $dayData[0]['date'];
$volPercentAVG = $dayData[0]['volume'] / $dayData[0]['_50dayVol'];
mysql_query ("update _$symbol set volPercentAvg=$volPercentAVG WHERE date=$todaysdate;");
It does not return anything, I am not sure I am approaching the MDarray correctly? I have triple checked the column names.
Anywhere to do with this would be helpfull
Thanks.
#Fred-ii- YOU DID IT! Can I or you make this an answer so I can vote for it? If I can I dont see how. – illcrx
Posting my comment as the answer in order to close the question.
If your date column contains any spaces or dots etc. then change WHERE date=$todaysdate
to/and quoting it WHERE date='$todaysdate'
For example: 2014-10-06 22:59:52
Would explain why you were not getting results.
However, I'm quite surprised/baffled that MySQL did not throw you a syntax error, bizarro.
Don't have time to read your entire bit right now, but I can give you my test method from our standard mysqli execution set:
print_r($Record);
This will allow you to see the structure and possibly where your error lies.
I'll also give you our framework which can be very useful (which is why we have it! LOL). Example framework (two functions) to make it easier to use mysqli in php with two lines for each query. It also allows for CLI or web output and debugging which will dump the query (so you can run it) and shows a print_r function to show results.:
This goes at the top:
define('DEBUG', false);
define('CLIDISPLAY', false);
if (CLIDISPLAY) {
define('PRE', '');
define('PRE_END', '');
} else {
define('PRE', '<pre>');
define('PRE_END', '</pre>');
}
require_once("/etc/dbconnect.php");
$DBLink = new mysqli($VARDB_server, $VARDB_user, $VARDB_pass, $VARDB_database, $VARDB_port);
if ($DBLink->connect_errno) {
printf(PRE . "Connect failed: %s\n" . PRE_END, $DBLink->connect_error);
exit();
}
Be sure you have a normal php file at /etc/dbconnect.php with your credentials in it (do not put these in a web folder in case php fails one day and exposes your passwords! LOL). Note that this file can then be shared and loaded only once. It should invoke
# Sample execution
$Query = "select * from vicidial_users where user='6666' and active='Y' limit 1";
$Records = GetData($DBLink, $Query);
print_r($Records[0]); // Single record return access via [0] to access a field named "id": $Records[0]['id']
// Multiple record return access via array walking
foreach ($Records as $Record) {
print_r($Record);
}
$Query = "update vicidial_users set active='Y' where user='6666' limit 1";
UpdateData($DBLink, $Query);
Functions (can be loaded from the credentials file or within your working file or put in a "functions.php" file and "require_once('functions.php');".
function GetData($DBLink, $Query) {
if (DEBUG) {
echo PRE . "Query: $Query\n" . PRE_END;
}
if ($Result = $DBLink->query($Query)) {
if (DEBUG) {
printf(PRE . "Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
}
while ($Record = $Result->fetch_assoc()) {
$ReturnData[] = $Record;
}
return $ReturnData;
} else {
if (DEBUG) {
printf(PRE . "Errormessage: %s\n", $DBLink->error);
printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
echo "No Records Returned\n" . PRE_END;
}
return false;
}
}
function UpdateData($DBLink, $Query) {
if (DEBUG) {
echo PRE . "Query: $Query\n" . PRE_END;
}
if ($Result = $DBLink->query($Query)) {
if (DEBUG) {
printf(PRE . "%s\n", $DBLink->info);
printf("Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
}
return;
} else {
if (DEBUG) {
printf(PRE . "Errormessage: %s\n", $DBLink->error);
printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
echo "No Records Returned\n" . PRE_END;
}
return;
}
}

Can I improve my PDO method (just started)

I just switched to PDO from mySQLi (from mySQL) and it's so far good and easy, especially regarding prepared statements
This is what I have for a select with prepared statement
Main DB file (included in all pages):
class DBi {
public static $conn;
// this I need to make the connection "global"
}
try {
DBi::$conn = new PDO("mysql:host=$dbhost;dbname=$dbname;charset=utf8", $dbuname, $dbpass);
DBi::$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
DBi::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo '<p class="error">Database error!</p>';
}
And in my page:
try {
$sql = 'SELECT pagetitle, pagecontent FROM mypages WHERE pageid = ? LIMIT 1';
$STH = DBi::$conn->prepare($sql);
$STH->execute(array($thispageid)); // $thispageid is from a GET var
}
catch(PDOException $e) {
echo '<p class="error">Database query error!</p>';
}
if ($STH) { // does this really need an if clause for it self?
$row = $STH->fetch();
if (!empty($row)) { // was there found a row with content?
echo '<h1>'.$row['pagetitle'].'</h1>
<p>'.$row['pagecontent'].'</p>';
}
}
It all works. But am I doing it right? Or can I make it more simple some places?
Is using if (!empty($row)) {} an ok solution to check if there was a result row with content? Can't find other decent way to check for numrows on a prepared narrowed select
catch(PDOException $e) {
echo '<p class="error">Database query error!</p>';
}
I would use the opportunity to log which database query error occurred.
See example here: http://php.net/manual/en/pdostatement.errorinfo.php
Also if you catch an error, you should probably return from the function or the script.
if ($STH) { // does this really need an if clause for it self?
If $STH isn't valid, then it should have generated an exception and been caught previously. And if you had returned from the function in that catch block, then you wouldn't get to this point in the code, so there's no need to test $STH for being non-null again. Just start fetching from it.
$row = $STH->fetch();
if (!empty($row)) { // was there found a row with content?
I would write it this way:
$found_one = false;
while ($row = $STH->fetch()) {
$found_one = true;
. . . do other stuff with data . . .
}
if (!$found_one) {
echo "Sorry! Nothing found. Here's some default info:";
. . . output default info here . . .
}
No need to test if it's empty, because if it were, the loop would exit.

Can anyone tell me if they see an error in the following PHP code?

For some reason, the while loop below never fires.
All of this is inside a class.
$code = $this->get_postal_state_no('Western Cape');
private function get_postal_state_no($psn)
{
$sql = "
SELECT
no
FROM
ct_state
WHERE
name LIKE('".$psn."');";
$stmt = sqlsrv_query($this->conn1, $sql);
// This statement is not false, so the error handling does not happen, this is expected.
if($stmt === FALSE)
{
if(($errors = sqlsrv_errors()) != NULL)
{
foreach($errors as $error)
{
$sqlstate = $error['SQLSTATE'];
$code = $error['code'];
$sqlmessage = $error['message'];
}
}
$msg = 'Error in $stmt in get_postal_state_no() method.';
$this->do_error_log($error_msg, $sqlstate, $code, $sqlmessage, $msg, __LINE__, __FILE__, __FUNCTION__, __CLASS__, __METHOD__);
sqlsrv_free_stmt($stmt);
}
//This loop is never entered. This is not expected.
while($obj = sqlsrv_fetch_object($stmt))
{
echo "I am here now";
break;
if(!empty($obj->no) && $obj->no != '')
{
echo "Hello, I exist";
break;
// This break never happens
return $obj->no;
}
else
{
echo "Hello, I don't exist";
break;
// This break never happens
$code = $this->sp_aa_iud_ct_state($psn);
return $code;
}
sqlsrv_free_stmt($stmt);
}
}
Does anyone have an idea why? I am using the php_sqlserv driver. The SQL server profiler shopws the query for the first part executing.
Thanks
J
Looking at the documentation page for sqlsrv_fetch_object it says this about the return value:
Returns an object on success, NULL if there are no more rows to return, and FALSE if an error occurs or if the specified class does not exist.
I suspect the function is either returning NULL or FALSE, though the reasons are a little unclear. Try adding this above the while loop and see what the output is:
$obj = sqlsrv_fetch_object($stmt)
var_dump($obj);
die;
while($obj = sqlsrv_fetch_object($stmt))
{ // ...
Another helpful debugging trick is to dump out the query and then copy/paste it into your DBMS system and run the query you are executing in code directly against your database to see if any results are actually being returned:
$sql = "
SELECT
no
FROM
ct_state
WHERE
name LIKE('".$psn."');";
var_dump($sql);

Categories