Related
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 3 years ago.
I’m having some problems with my database.
MySQL database is organized as:
——————————————————————
userId | value
——————————————————————
63 | {"pro":true}
The GET requests are working just fine but not the POST requests.
POST requests return me just nothing, when it should return a JSON with a success index.
This is my index.php code:
<?php
$database = "";
$username = "";
$password = "";
$servename = "localhost";
$connection = new mysqli($servername, $username, $password, $database);
if ($connection->connect_error) {
die("Connection failure: ".$connection->$connection_error);
}
header("Content-type: application/json");
if ($_SERVER["REQUEST_METHOD"] == "GET") {
if ($_GET["userId"]) {
$result = $connection->query("SELECT value FROM main_table WHERE userId = ".$_GET["userId"]);
if ($result->num_rows > 0) {
echo $result;
}
else {
echo json_encode(array());
}
}
}
elseif ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($_POST["userId"] && $_POST["value"]) {
$result = $connection->query("INSERT INTO main_table (userId, value) VALUES ('".$_POST["userId"]."', '".$_POST["value"]."')");
if ($result) {
echo json_encode(array("success" => TRUE));
}
else {
echo json_encode(array("success" => FALSE));
}
}
}
$connection->close();
?>
Could you guys spot any mistakes in my code?
Thank you in advance!
your code is not secure ,Use this to avoid sql injection
Simple you can should as below code ..also better safety
For select
$query = "
SELECT *
FROM main_table
WHERE userId= ?
";
$stmt = $connection->prepare($query);
$userId=$_GET["userId"];
$stmt->bind_param("i", $userId);
$result = $stmt->get_result();
$rows=[];
while ($data = $result->fetch_assoc())
{
$rows[] = $data;
}
echo json_encode($rows);
Insert for example
$stmt = $connection->prepare("INSERT INTO main_table (value,userId) VALUES (?, ?)");
$stmt->bind_param("ii", $_POST['value'], $_POST['userId']);
if($stmt->execute())
{
echo "insert successful";
}
else
{
echo "couldn't insert successful";
}
$stmt->close();
I am new in PHP development, I get a warning like this when making email confirmation registration:
Registration success, please login using your data
Warning: mysqli::close(): Couldn't fetch
mysqli in
/Applications/XAMPP/xamppfiles/htdocs/Twitter/security/access.php on
line 42
here is the simplified code of access.php
class access {
public $host = null;
public $username = null;
public $password = null;
public $dbname = null;
public $conn = null;
public $result = null;
function __construct($xhost,$xusername,$xpassword,$xdbname) {
$this->host = $xhost;
$this->username = $xusername;
$this->password = $xpassword;
$this->dbname = $xdbname;
}
// connection to database
function connect() {
$this->conn = new mysqli($this->host,$this->username,$this->password,$this->dbname);
if (mysqli_connect_errno()) {
echo "Connection to database failed: ".mysqli_connect_error();
}
// support all languages
$this->conn->set_charset("utf8");
}
public function disconnect() {
if ($this->conn != null) {
$this->conn->close();
}
}
//saving token to the database
function saveTokens ($table, $id, $token) {
$query = "INSERT INTO $table SET id=?, token=?";
$statement = $this->conn->prepare($query);
if (!$statement) {
throw new Exception($statement->error);
}
$statement-> bind_param('is',$id,$token);
$returnValue = $statement ->execute();
return $returnValue;
}
// get userID from given Token
function getIDFromToken($table,$token) {
$returnValue = [];
$query = "SELECT id FROM $table WHERE token='$token'";
$result = $this->conn->query($query);
if ($result != null && (mysqli_num_rows($result)>0)) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if (!empty($row)) {
$returnValue = $row;
}
}
return $returnValue;
}
function updateEmailConfirmationStatus($status,$id) {
$query = "UPDATE users SET emailConfirmed =? WHERE id=?";
$statement = $this->conn->prepare($query);
if (!$statement) {
throw new Exception($statement->error);
}
$statement-> bind_param('ii',$status,$id);
$returnValue = $statement ->execute();
return $returnValue;
}
// delete token when ID is available
function deleteToken($table,$token) {
$query = "DELETE FROM $table WHERE token =?";
$statement = $this->conn->prepare($query);
if (!$statement) {
throw new Exception($statement->error);
}
$statement-> bind_param('s',$token);
$returnValue = $statement ->execute();
return $returnValue;
}
}
and I use access.php in confirmationlink.php
here is the code on confirmationlink.php
<?php
require_once("../security/access.php");
if (empty($_GET["token"])) {
echo "Please follow as per the procedure";
return;
}
$token = htmlentities($_GET["token"]);
// making connection to the database
$file = parse_ini_file("../../../../twitter.ini");
$dbhost = trim($file["host"]);
$dbusername = trim($file["username"]);
$dbpassword = trim($file["password"]);
$dbname = trim($file["dbname"]);
$access = new access($dbhost,$dbusername,$dbpassword,$dbname);
$access->connect();
// get ID from database as per the Token created
$info = $access->GetIDFromToken("emailTokens",$token);
$id = $info["id"];
// change emailConfirmed status to 1 if user has pressed confirmation link
$result = $access -> updateEmailConfirmationStatus(1,$id);
// menghapus token apabila ID sudah terkonfirmasi ada di database
if ($result) {
$access ->deleteToken("emailTokens",$token);
echo "Registration success, please login using your data";
}
// close the connection
$access -> disconnect();
I get the error only on the last line of confirmationlink.php file. the database has been changed successfully on MySQL as I want. I also use disconnect method on other PHP file but i have no issue. but somehow I got the issue now
what went wrong in here ? Thanks in advance :)
You need to close your statements before you return the result in each of the functions:
$statement->close();
I'm trying to make a registration script using PHP with Mysql database. The insertion cannot be done. If I register with an email-id which is already in the database, it is working fine. But, the script fails to insert new entries. It is returning 'bool(false)'.
I've tried the to do the same using PDO. The insertion can't be done. So, I tried mysqli prepared statements instead and even this yields the same result. Here is the code.
<?php
$dbh = new mysqli('localhost', 'user', 'pass', 'db');
if(isset($_POST['register'])){
$ip = $_SERVER['REMOTE_ADDR'];
$name = $_POST['$name'];
$mail = $_POST['mail'];
$passw = $_POST['passw'];
$codeone = $_POST['codeone'];
$descs = $_POST['desc'];
$newstrings = 'specialstring';
$encrypted_pass = crypt( $passw );
$stmt = $dbh->prepare("SELECT mail FROM userrecs WHERE mail=?");
$stmt->bind_param('s',$mail);
if($stmt->execute())
{
$stmt->store_result();
$rows = $stmt->num_rows;
if($rows == 1)
{
session_start();
$_SESSION['notification_one'] = 'bla';
header('location:/someplace');
}
else {
$statement = $db->prepare("INSERT INTO userrecs (ip,name,mail,pass,codeone_one,desc_one,spcstrings) VALUES (?,?,?,?,?,?,?)");
$statement->bind_param('ssssiss',$ip,$name,$mail,$encrypted_pass,$codeone,$descs,$newstrings);
try {
if($statement->execute())
{
session_start();
$_SESSION['noti_two'] = 'bla';
header('location:/someplace');
}
else
{
var_dump($statement->execute());
$statement->errorInfo();
}
}
catch(PDOException $pe) {
echo "S";
echo('Connection error, because: ' .$pe->getMessage());
}
}
}
}
else{
header('location:/someplace');
}
?>
EDIT:
This is the PDO-only code. I was mixing PDO and mysqli in the previous code.
<?php
$dsn = 'mysql:dbname=dbname;host=localhost';
$user = 'user';
$password = 'pass';
$dbh = new PDO($dsn, $user, $password);
if(isset($_POST['regsubmit'])){
$ip = $_SERVER['REMOTE_ADDR'];
$name = $_POST['$name'];
$mail = $_POST['mail'];
$pass = $_POST['passw'];
$codeone = $_POST['codeone'];
$descs = $_POST['desc'];
$newstrings = 'specialstring';
$encrypted_pass = crypt( $passw );
$sql = "SELECT mail FROM userrecs WHERE mail=:mail";
$statement = $dbh->prepare($sql);
$statement->bindValue(':mail',$mail,PDO::PARAM_STR);
if($statement->execute())
{
if($statement->rowCount() == 1)
{
session_start();
$_SESSION['noti_one'] = 'bla';
header('location:/someplace');
}
else {
$sql2 = "INSERT INTO userrecs (ip,name,mail,pass,codeone_one,desc_one,spcstrings) VALUES (:ip,:name,:mail,:encrypted_pass,:codeone,:descs,:newstrings)";
$stmt = $dbh->prepare($sql2);
$stmt->bindParam(':ip',$ip,PDO::PARAM_STR);
$stmt->bindParam(':name',$name,PDO::PARAM_STR);
$stmt->bindValue(':mail',$mail,PDO::PARAM_STR);
$stmt->bindParam(':encrypted_pass',$encrypted_pass,PDO::PARAM_STR);
$stmt->bindParam(':codeone',$codeone,PDO::PARAM_STR);
$stmt->bindParam(':descs',$descs,PDO::PARAM_STR);
$stmt->bindParam(':newstrings',$temstr,PDO::PARAM_STR);
try {
if($stmt->execute())
{
session_start();
$_SESSION['noti_two'] = 'bla';
header('location:/someplace');
}
else
{
var_dump($stmt->execute());
$stmt->errorInfo();
}
}
catch(PDOException $pe) {
echo "S";
echo('Connection error, because: ' .$pe->getMessage());
}
}
}
}
else{
header('location:/someplace');
}
?>
Please ignore variable or table names. I edited some of the names here.
You are mixing PDO and mysqli driver in the same script, this is not possible.
Please use either one but not both.
PDO is the prefferred extension.
EDIT:
In your query:
INSERT INTO userrecs (ip,name,mail,pass,codeone_one,desc_one,spcstrings) VALUES (...)
NAME is a mysql reserved keyword, you escape it by using backticks:
INSERT INTO userrecs (ip,`name`,mail,pass,codeone_one,desc_one,spcstrings) VALUES (...)
EDIT:
Change
var_dump($statement->execute());
$statement->errorInfo();
to
var_dump($statement->errorInfo());
EDIT:
$dsn = 'mysql:dbname=dbname;host=localhost';
$user = 'user';
$password = 'pass';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (isset($_POST['regsubmit'])) {
try {
$sql = "SELECT mail FROM userrecs WHERE mail=:mail";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':mail', $_POST['mail'], PDO::PARAM_STR);
if ($stmt->execute() && $stmt->rowCount() == 1) {
session_start();
$_SESSION['noti_one'] = 'bla';
header('location:/someplace');
} else {
$sql = "INSERT INTO userrecs (ip,name,mail,pass,codeone_one,desc_one,spcstrings) VALUES (:ip,:name,:mail,:encrypted_pass,:codeone,:descs,:newstrings)";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR);
$stmt->bindValue(':name', $_POST['$name'], PDO::PARAM_STR);
$stmt->bindValue(':mail', $_POST['mail'], PDO::PARAM_STR);
$stmt->bindValue(':encrypted_pass', crypt($_POST['passw']), PDO::PARAM_STR);
$stmt->bindValue(':codeone', $_POST['codeone'], PDO::PARAM_STR);
$stmt->bindValue(':descs', $_POST['desc'], PDO::PARAM_STR);
$stmt->bindValue(':newstrings', 'specialstring', PDO::PARAM_STR);
if ($stmt->execute()) {
session_start();
$_SESSION['noti_two'] = 'bla';
header('location:/someplace');
} else {
var_dump($stmt->errorInfo());
}
}
} catch (PDOException $pe) {
echo "S";
echo('Connection error, because: ' . $pe->getMessage());
}
} else {
header('location:/someplace');
}
I believe you have an error in your logic.
Try this code and see what you get ...
<?php
$dbh = new mysqli('localhost', 'user', 'pass', 'db');
if(isset($_POST['register'])) {
$ip = $_SERVER['REMOTE_ADDR'];
$name = $_POST['$name'];
$mail = $_POST['mail'];
$passw = $_POST['passw'];
$codeone = $_POST['codeone'];
$descs = $_POST['desc'];
$newstrings = 'specialstring';
$encrypted_pass = crypt($passw);
$stmt = $dbh->prepare("SELECT mail FROM userrecs WHERE mail=?");
$stmt->bind_param('s', $mail);
$test = $stmt->execute();
if($test) {
$stmt->store_result();
$rows = $stmt->num_rows;
if($rows == 1) {
session_start();
$_SESSION['notification_one'] = 'bla';
header('location:/someplace');
} else {
$statement = $db->prepare("INSERT INTO userrecs (ip,name,mail,pass,codeone_one,desc_one,spcstrings) VALUES (?,?,?,?,?,?,?)");
$statement->bind_param('ssssiss', $ip, $name, $mail, $encrypted_pass, $codeone, $descs, $newstrings);
try {
if($statement->execute()) {
session_start();
$_SESSION['noti_two'] = 'bla';
header('location:/someplace');
} else {
var_dump($statement->execute());
$statement->errorInfo();
}
} catch (PDOException $pe) {
echo "S";
echo('Connection error, because: ' . $pe->getMessage());
}
}
}else{
echo "test is not ok";
var_dump($test);
}
} else {
header('location:/someplace');
}
I am making a game for class and I have decided to include an admin area where settings may be modified. Currently this is how I have established a database connection:
db_config.php:
<?php
defined('DB_SERVER') ? null : define('DB_SERVER', 'localhost');
defined('DB_USER') ? null : define('DB_USER', 'root');
defined('DB_PASS') ? null : define('DB_PASS', 'root');
defined('DB_NAME') ? null : define('DB_NAME', 'game');
?>
database.php:
<?php
require_once('db_config.php');
class DatabaseConnect {
public function __construct($db_server, $db_user, $db_pass, $db_name) {
if (!#$this->Connect($db_server, $db_user, $db_pass, $db_name)) {
echo 'Connection failed.';
} else if ($this->Connect($db_server, $db_user, $db_pass, $db_name)){
}
}
public function Connect($db_server, $db_user, $db_pass, $db_name) {
if (!mysqli_connect($db_server, $db_user, $db_pass, $db_name)) {
return false;
} else {
return true;
}
}
}
$connection = new DatabaseConnect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
?>
Up to this point I have used mysql_real_escape_string in my queries and I know that I shouldn't be manually escaping. I am still learning PHP so some things take me a while to grasp. I have had a look at the php.net prepared statement manual but I am not sure whether I need to change the way I have connected to the database.
So basically what I am asking is if I had this query (or any query for that matter):
if (isset($_POST['submit'])) {
// Process the form
$id = $current_page["id"];
$menu_name = mysql_prep($_POST["menu_name"]);
$position = (int) $_POST["position"];
$visible = (int) $_POST["visible"];
$content = mysql_prep($_POST["content"]);
// validations
$required_fields = array("menu_name", "position", "visible", "content");
validate_presences($required_fields);
$fields_with_max_lengths = array("menu_name" => 30);
validate_max_lengths($fields_with_max_lengths);
if (empty($errors)) {
// Perform Update
$query = "UPDATE pages SET ";
$query .= "menu_name = '{$menu_name}', ";
$query .= "position = {$position}, ";
$query .= "visible = {$visible}, ";
$query .= "content = '{$content}' ";
$query .= "WHERE id = {$id} ";
$query .= "LIMIT 1";
$result = mysqli_query($connection, $query);
if ($result && mysqli_affected_rows($connection) == 1) {
// Success
$_SESSION["message"] = "Page updated.";
redirect_to("manage_content.php?page={$id}");
} else {
// Failure
$_SESSION["message"] = "Page update failed.";
}
}
} else {
// This is probably a GET request
} // end: if (isset($_POST['submit']))
?>
How would it be changed into a prepared statement?
For the SQL portion, try this >>
$records_found = 0;
$record = false;
$cn = mysqli_connect($host, $user, $pass, $data);
$query = "UPDATE pages SET menu_name=?, position=?, visible=?, content=? WHERE id=? LIMIT 1"
$stmt = mysqli_prepare($cn, $query);
$stmt->bind_param("s", $menu_name);
$stmt->bind_param("s", $position);
$stmt->bind_param("s", $visible);
$stmt->bind_param("s", $content);
$stmt->bind_param("d", $id);
$result = $stmt->execute();
if($result) {
$result = $stmt->get_result();
if($result) {
while($row = $result->fetch_assoc()) {
if($records_found == 1) {
break;
}
$record = $row;
$records_found++;
}
mysqli_free_result($result);
}
}
mysqli_close($cn);
// Output the record found if any
if($record) {
var_export($record);
} else {
echo 'No records found';
}
Also, read the docs on it here >> mysqli.prepare << as there are some really good examples.
**NOTE: The above solution provides complete code from connecting to the db, to closing the connection and freeing the memory consumed, with a condition block after to allow you to work with the resulting row if any found. Basically, all trapping is complete aside from or die(mysqli_error($cn)); stuff.
This is how you create a prepared statement.
$query = "UPDATE pages SET menu_name=?, position = ?,
visible=?, content=? WHERE id=? LIMIT 1";
$stmt = mysqli_prepare($connection, $query);
$result = false;
if($stmt){
mysqli_stmt_bind_param( $stmt, "ssdsd", $menu_name,
$position, $visible, $content,$id );
$result = mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
}
if($result){
//Successful
}
else{
//Unsuccessful
}
I made some assumptions regarding the type of the fields in the database but the notation is in mysqli_stmt_bind_param , 's' stands for string and 'd' stands for integer.
I'm getting a Call to a member function prepare() on a non-object error in my PHP when using PDO to select data that was sent via an AJAX call.
Searching around on StackOverflow I've found many answers to this error, but none work to fix my problem.
The weird part is that the other PHP files use the same PDO calls and work successfully, but this one is giving me the non-object error only.
To note, the PDO connection is identical to the other pages where it works, so I know that's not causing the problem.
Also, I have tested that the AJAX data sent is being received, and that is working too.
PHP Code
$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
$dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$username = $_POST['username'];
$inPword = $_POST['password'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
$loggedin = "";
$password_hash = "";
$loggedinstatus = "";
$pts = "";
function getLoginInfo()
{
$sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
while($row = $sth->fetch(PDO::FETCH_ASSOC))
{
echo $row['pword'];
echo $row['loggedin'];
echo $row['points'];
}
$password_hash = $fetch['pword'];
$loggedinstatus = $fetch['loggedin'];
$pts = $fetch["points"];
if($password_hash === null || $loggedinstatus === null || $pts === null)
{
die(json_encode(array("message" => "none")));
}
else
{
return "more";
}
}
function checkLoginCreds()
{
if(crypt($inPword, $password_hash) === $password_hash)
{
switch($loggedinstatus)
{
case "no":
$sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
$sel->execute(array($username));
return "AllGood";
break;
defaut:
return "alreadyin";
break;
}
}
else
{
return "BadLogin";
}
}
if(getLoginInfo() === "more")
{
echo json_encode(array("message" => checkLoginCreds()));
}
getLoginInfo();
}
catch(PDOException $e)
{
echo $e->getMessage();
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
Finally, here's the output when I var_dump() the PDO connection.
object(PDO)#1 (0) {}
For this to work, you need to use the global variable scope, explained here: http://php.net/manual/en/language.variables.scope.php
$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
$dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$username = $_POST['username'];
$inPword = $_POST['password'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
$loggedin = "";
$password_hash = "";
$loggedinstatus = "";
$pts = "";
function getLoginInfo()
{
global $dbh, $username, $password_hash, $loggedinstatus, $pts;
$sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
while($row = $sth->fetch(PDO::FETCH_ASSOC))
{
echo $row['pword'];
echo $row['loggedin'];
echo $row['points'];
}
$password_hash = $fetch['pword'];
$loggedinstatus = $fetch['loggedin'];
$pts = $fetch["points"];
if($password_hash === null || $loggedinstatus === null || $pts === null)
{
die(json_encode(array("message" => "none")));
}
else
{
return "more";
}
}
function checkLoginCreds()
{
global $dbh, $inPword, $password_hash, $loggedinstatus, $username;
if(crypt($inPword, $password_hash) === $password_hash)
{
switch($loggedinstatus)
{
case "no":
$sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
$sel->execute(array($username));
return "AllGood";
break;
defaut:
return "alreadyin";
break;
}
}
else
{
return "BadLogin";
}
}
if(getLoginInfo() === "more")
{
echo json_encode(array("message" => checkLoginCreds()));
}
getLoginInfo();
}
catch(PDOException $e)
{
echo $e->getMessage();
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
But this can get messy very quickly.
I suggest you put the variables in an array or using OOP for a more robust solution: http://php.net/manual/en/language.oop5.php
This is how you can define it in a class..
class someClass {
private $db;
public function __construct(){
$this->dbconnect();
}
private function dbconnect() {
try { //try connection
$dbh = new PDO('mysql:host=localhost;dbname=somenane', 'usernane', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh = $dbh;
} catch (Exception $e) { //connection failed
die("Oh no! It seems we took too long to respond");
}
}
public function getLoginInfo() {
$sth = $this->dbh->prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
//cont the code
}
}
Not sure if it's good enough..but it will work..