I am reading a book on PHP, MYSQL, JAVASCRIPT and JQUERY. While reading, I do type the code and see how it worked. I have the following script which I ran to create a table named: "users', and subsequently update the table with two users. When I ran the script in my browser, it only created the new table but failed to update it with the new users. I do not receive any error. Below is the entire script.
<?php // setup_users.php
require_once 'login.php';
$connection = new mysqli($hn, $un, $pw, $db);
if ($connection->connect_error) die($connection->connect_error);
$query = "CREATE TABLE users (
forename VARCHAR(32) NOT NULL,
surname VARCHAR(32) NOT NULL,
username VARCHAR(32) NOT NULL UNIQUE,
password VARCHAR(32) NOT NULL
)";
$result = $connection->query($query);
if (!$result) die($connection->error);
$salt1 = "qm&g";
$salt2 = "ph!#";
$forename = 'Baban';
$surname = 'Sadik';
$username = 'bsadik';
$password = 'babansadik1';
$token = hash('ripemd128', "$salt1$password$salt2");
add_user($connection, $forename, $surname, $username, $token);
$forename = 'Abdullah';
$surname = 'Abubakar';
$username = 'aabubakar';
$password = 'abakar1';
$token = hash('ripemd128', "$salt1$password$salt2");
add_user($connection, $forename, $surname, $username, $token);
function add_user($connection, $fn, $sn, $un, $pw) {
$query = "INSERT INTO users VALUES('$forename', '$surname', '$username', '$token')";
$result = $connection->query($query);
if (!$result) die($connection->error);
}
?>
Where did go wrong please?
You just missed to put column names in the insertion query in add_user function and you are passing undefined variables
Do like this
$query = "INSERT INTO users(forename, surname, username, password)
VALUES('$fn', '$sn', '$un', '$pw')";
Your add_user function has parameters different to what you are trying to use in the query itself.
Change the query to the following:
INSERT INTO users VALUES('$fn', '$sn', '$un', '$pw')
Note that you should use prepared statements instead, as currently the code is susceptible to SQL Injection attacks. If the book you're using doesn't contain information on using prepared statements, scrap the book and find one that does instead.
Related
I'm creating a signup form and am onto the confirmation email part. I want to find all values associated with one other value in a database.
Ex. I get the "key" that is in the URL, then want to find all the values associated with it. In my database there are 4 columns: STR (the key), USERNAME, PASSWORD, and EMAIL. If I get STR I want to get the username, password, and email that are in the same row as the key and then insert it into another table in the same database.
verify.php:
<?php
$username = $_GET['username'];
$password = $_GET['password'];
$email = $_GET['email'];
$servername = "localhost";
$user = 'usernamelol';
$pass = 'passwordlol';
$dbname = 'vibemcform';
$str = $_GET['str'];
$conn = new mysqli($servername, $user, $pass, $dbname);
/* The variable query gets the "key" from the dont database. I want to compare that value with the other values associated with it. Ex. the variables in the same row as the key. */
$query = mysqli_query($conn, "SELECT * FROM `dont` WHERE STR='".$key."'");
/* Below is my attempt. Feel free to change whatever you want. */
$sql = "SELECT USERNAME, PASSWORD, EMAIL FROM dont";
$result = $conn->query($sql);
if (!$query) {
die('Error: ' . mysqli_error($con));
}
if (mysqli_num_rows($query) > 0) {
if ($result -> num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$sqltwo = "INSERT INTO data (USERNAME, PASSWORD, EMAIL) VALUES ($row["USERNAME"], $row["PASSWORD"], $row["EMAIL"])";
}
}
}
echo 'Successfully verified your email!'; exit;
?>
Why not simpy use the insert ... select syntax?
insert into data(username, password, email)
select username, password, email from dont where str = :key
You can run this query right ahead, and then check how many rows were affected:
If no row was affected, then it means that the select did not bring a row back: so the :key was not found in the database
If a row was affected, then the key was found and the executed row was inserted
Note that you should use parametrized queries so your code is safe from SQL injection (and more efficient as well); recommended reading How can I prevent SQL injection in PHP??
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.
My php code for registration does not insert values to the database. I tried different ways but it is still not working. Here is the code:
Database connection:
<?php $link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
My registration form PHP code:
<?php
include "connection.php"; ?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
mysqli_query($link, "insert into member_registration values('', '$firstname', '$lastname'
, '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");
?>
Welcome to StackOverflow.
First of all, your code is vulnerable to SQL Injection. This is a major flaw but thankfully, one that's easily fixed. It is important that you do not leave this open to SQL Injection, even if this is something just for you to use. It'll keep your data safe in the event that someone else manages to access it and also gets you in to good habits.
Secondly, your code isn't working because you haven't specified what columns you want to insert into.
Using your example as a basis, here's a working version.
DO NOT USE THIS, IT IS VULNERABLE CODE
<?php
$link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
<?php
include "connection.php";
?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
//If someone passes 2019'); drop table member_registration; -- for example as the year parameter, MySQL interprets the query string as two separate queries. One to insert a record and the second to drop the table and will execute both
mysqli_query($link, "insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values( '$firstname', '$lastname', '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");;
}
?>
A MORE SECURE VARIANT
I have a couple of SQL convenience functions based on PDO I use on a regular basis.
They pick up their credentials from an ini file stored outside of the publicly accessible folder structure.
The GetData procedure returns the results in the form of an associative array
UpdateData returns the amount of rows affected.
Ini file example
host=localhost
dbname=dataadventurers
username=user
password=pass
Convenience Functions
/*Put credential ini file path here*/
$credentialFile = "...";
function GetData($sql, $params = null, $paramtypes = null){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
if(is_null($params)){ //If no parameters supplied, execute the query as is
$stmt = $db->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
else{
if(count($params) <> count($paramtypes)){ //Check that the parameter count and type count are the same
throw new InvalidArgumentException;
}
$stmt = $db->prepare($sql); //Prepare the statement
for($i=0; $i<count($params); $i++){ //Bind the parameters
$stmt->bindValue($i+1, $params[$i], $paramtypes[$i]);
}
$stmt->execute(); //Execute query
$results = $stmt->fetchAll(PDO::FETCH_ASSOC); //Return the results as an associative array
}
return $results;
}
function UpdateData($sql, $params){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
try{
$stmt = $db->prepare($sql); //Prepare the statement
is_null($params){ //If there aren't any parameters to bind...
$stmt->execute(); //...execute statement as is
}
else{
$stmt->execute($params); //otherwise execute with the supplied parameters
}
$results = $stmt->rowCount(); //Return the rowcount
return $results;
}
catch(PDOException $ex){ //Catch any PDO Exceptions
return $ex->getMessage(); //Return the exception message
}
}
Usage
The usage is simple. When selecting data, pass a SQL string, an array containing any parameters and an array containing the parameter types. These arrays must be of the same length.
When updating/inserting/deleting data, pass a SQL string and an array containing the parameters. There is no parameter type requirement for UpdateData.
//GetData with no parameters
$results = GetData('select * from member_registration', [], []);
//GetData with one parameter of type String.
$results2 = GetData('select * from member_registration where firstname = ?', ['David'], [PDO::PARAM_STR]);
//Your insert example
$parameters = [
$firstname,
$lastname,
$middle,
$idnum,
$email,
$pass,
$bday,
$course,
$year
];
$rowsAffected = UpdateData('insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values(?, ?, ?, ?, ?, ?, ?, ?, ?)', $parameters);
Final Thoughts
You'll need to substitute the column names for the fields you have in your database. If any are auto-generated, such as an auto-incrementing ID field, omit that field so it works correctly.
One of your parameters is called $pass. If you're storing passwords in a database, ALWAYS store them in an encrypted form, preferably using bCrypt. This StackOverflow answer explains why/how.
This is my code, we have database called "our_new_database".
The connection is fine, as well as the HTML Form and credentials and I still cannot insert information into the database.
Table is created, I can see the columns and lines in XAMPP / phpMyAdmin.
The only error I'm getting is the last echo of the If/Else Statement - "Could not register".
Tried everything I can and still cannot make this insertion to work normally.
Can someone advise me something?
<?php
include "app".DIRECTORY_SEPARATOR."config.php";
include "app".DIRECTORY_SEPARATOR."db-connection.php";
include "app".DIRECTORY_SEPARATOR."form.php";
$foo_connection = db_connect($host, $user_name, $user_password, $dbname);
$sql = "CREATE TABLE user_info(
user_name_one VARCHAR(30) NOT NULL,
user_name_two VARCHAR(30) NOT NULL,
user_email VARCHAR(70) NOT NULL UNIQUE
)";
if(mysqli_query($foo_connection, $sql)){
echo "Table created successfully";
}
else {
echo "Error creating table - table already exist.".mysqli_connect_error($foo_connection);
}
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$user_name_one = $_POST["userOne"];
$user_name_two = $_POST["userTwo"];
$user_email = $_POST["userEmail"];
$sql = "INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('".$_POST['userOne']."',('".$_POST['userTwo']."',('".$_POST['userEmail']."')";
if(mysqli_query($foo_connection,$sql))
{
echo "Successfully Registered";
}
else
{
echo "Could not register";
}
}
$foo_connection->close();
You should avoid the direct use of variables in SQL statements, instead, you should use parameterized queries.
This also should avoid the need to string concatenation and manipulation problems.
$stmt = $foo_connection->prepare("INSERT INTO user_info
(user_name_one,user_name_two,user_email))
VALUES(?,?,?)");
$stmt->bind_param('sss', $user_name_one, $user_name_two, $user_email );
$stmt->execute();
You need to change
$sql = "INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('".$_POST['userOne']."',('".$_POST['userTwo']."',('".$_POST['userEmail']."')";
To
$sql = "INSERT INTO `user_info`(`user_name_one`,`user_name_two`,`user_emai`l) VALUES ('$user_name_one','$user_name_two','$user_email')";
remember you should use prepared query
$sql= $foo_connection->prepare("INSERT INTO user_info
(user_name_one,user_name_two,user_email))
VALUES(?,?,?)");
$sql->bind_param('sss', $user_name_one, $user_name_two, $user_email );
$sql->execute();
$sql = "INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('".$_POST['userOne']."','".$_POST['userTwo']."','".$_POST['userEmail']."')";
I reckon your parentheses on this line:
$sql = "INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('".$_POST['userOne']."',('".$_POST['userTwo']."',('".$_POST['userEmail']."')";
Do not match, it should look like something like this:
$sql = "INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('".$_POST['userOne']."','".$_POST['userTwo']."','".$_POST['userEmail']."')";
Cause for know your query is:
"INSERT INTO user_info (userOne,userTwo,userEmail) VALUES('value',('value1',('value2')"
As said above you might use:
echo $foo_connection->error
To see some errors displayed
I have a problem with producing a Register using my MySQLI Code. The tables/connection variable is matching up, and the correct variables being passed through the query is populated with expected strings, when running a query or prepare & execute when performing any type of query, I get returned with the following:
Fatal error: Call to a member function query() on a non-object in
/var/www/New/API/FormValidations.php on line 40
My code is as followed:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username='$Username'");
$Query->execute();
$Number = $Query->num_rows;
if ($Number !== 0)
{
echo "Username Already In Use";
}
else
{
$Insert_User = $STD->prepare("INSERT INTO Users ('Username', 'Password') VALUES ('$Username', '$Password)");
$Insert_User->execute();
echo "Account Created!";
}
Here is My Connection Script:
$STD = new mysqli('localhost', 'root', 'xxxxx', 'SLMS');
$AccessCon = new mysqli('localhost', 'root', 'xxxxx', 'DBAccess');
if ($AccessCon->connect_error) {
die("Access Has Been Revoked. Please Contact Administration");
}
if ($STD->connect_error) {
die("Standard Access Has Been Revoked. Please Contact Administration");
}
and my SQL Table for Users:
CREATE TABLE IF NOT EXISTS `Users` (
`ID` int(255) NOT NULL AUTO_INCREMENT,
`Username` varchar(255) NOT NULL,
`Password` text NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
I have tried commenting out all my query code, and running
$Query = $STD->query("SHOW TABLES");
$Results = $STD->fetch_array(MYSQLI_ASSOC);
this still returned an error, on my $Query variable.
I have also tried modifying my code to search for something that is already present in the database:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username='Test'");
and tried to enclose my $Username As followed:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username='{$Username}'");
This has performed No Success. I was wondering if someone could shed some light on this situation?
Edit:
Commenting out the entire script and just running:
$Query = $STD->query("SHOW TABLES");
$test = $Query->fetch_array(MYSQLI_ASSOC);
print_r($test);
Returns a result.
UPDATE:
I have modified my code to:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username=?");
$Query->bind_param("s", $Username);
$Query->execute();
Final Update:
Fatal error: Call to a member function bind_param() on a non-object
in /var/www/New/Register.php on line 45
This is the new Error.
The offending lines:
$Insert_User = $STD->prepare("INSERT INTO Users ('Username', 'Password') VALUES (?, ?)");
$Insert_User->bind_param("ss", $Username, $Password);
$Insert_User->execute();
When using prepare you have to bind the varables that hold your values.
Example:
$city = "Amersfoort";
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $city);
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($district);
/* fetch value */
$stmt->fetch();
printf("%s is in district %s\n", $city, $district);
/* close statement */
$stmt->close();
}
here is link to prepared statements
Update
this:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username=s");
should be:
$Query = $STD->prepare("SELECT * FROM Users WHERE Username=?");
this:
$Insert_User = $STD->prepare("INSERT INTO Users ('Username', 'Password') VALUES ('U', 'P)");
should be:
$Insert_User = $STD->prepare("INSERT INTO Users ('Username', 'Password') VALUES (?, ?)");
this :
$Insert_User->bind_param('U', $Username);
$Insert_User->bind_param('P', $Password);
should be this:
$Insert_User->bind_param('ss', $Username,$Password);
I have this code to select all the fields from the 'jobseeker' table and with it it's supposed to update the 'user' table by setting the userType to 'admin' where the userID = $userID (this userID is of a user in my database). The statement is then supposed to INSERT these values form the 'jobseeker' table into the 'admin' table and then delete that user from the 'jobseeker table. The sql tables are fine and my statements are changing the userType to admin and taking the user from the 'jobseeker' table...however, when I go into the database (via phpmyadmin) the admin has been added by none of the details have. Please can anyone shed any light onto this to why the $userData is not passing the user's details from 'jobseeker' table and inserting them into 'admin' table?
Here is the code:
<?php
include ('../database_conn.php');
$userID = $_GET['userID'];
$query = "SELECT * FROM jobseeker WHERE userID = '$userID'";
$result = mysql_query($query);
$userData = mysql_fetch_array ($result, MYSQL_ASSOC);
$forename = $userData ['forename'];
$surname = $userData ['surname'];
$salt = $userData ['salt'];
$password = $userData ['password'];
$profilePicture = $userData ['profilePicture'];
$sQuery = "UPDATE user SET userType = 'admin' WHERE userID = '$userID'";
$rQuery = "INSERT INTO admin (userID, forename, surname, salt, password, profilePicture) VALUES ('$userID', '$forename', '$surname', '$salt', '$password', '$profilePicture')";
$pQuery = "DELETE FROM jobseeker WHERE userID = '$userID'";
mysql_query($sQuery) or die (mysql_error());
$queryresult = mysql_query($sQuery) or die(mysql_error());
mysql_query($rQuery) or die (mysql_error());
$queryresult = mysql_query($rQuery) or die(mysql_error());
mysql_query($pQuery) or die (mysql_error());
$queryresult = mysql_query($pQuery) or die(mysql_error());
mysql_close($conn);
header ('location: http://www.numyspace.co.uk/~unn_v002018/webCaseProject/index.php');
?>
Firstly, never use SELECT * in some code: it will bite you (or whoever has to maintain this application) if the table structure changes (never say never).
You could consider using an INSERT that takes its values from a SELECT directly:
"INSERT INTO admin(userID, forename, ..., `password`, ...)
SELECT userID, forename, ..., `password`, ...
FROM jobseeker WHERE userID = ..."
You don't have to go via PHP to do this.
(Apologies for using an example above that relied on mysql_real_escape_string in an earlier version of this answer. Using mysql_real_escape_string is not a good idea, although it's probably marginally better than putting the parameter directly into the query string.)
I'm not sure which MySQL engine you're using, but your should consider doing those statements within a single transaction too (you would need InnoDB instead of MyISAM).
In addition, I would suggest using mysqli and prepared statements to be able to bind parameters: this is a much cleaner way not to have to escape the input values (so as to avoid SQL injection attacks).
EDIT 2:
(You might want to turn off the magic quotes if they're on.)
$userID = $_GET['userID'];
// Put the right connection parameters
$mysqli = new mysqli("localhost", "user", "password", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
// Use InnoDB for your MySQL DB for this, not MyISAM.
$mysqli->autocommit(FALSE);
$query = "INSERT INTO admin(`userID`, `forename`, `surname`, `salt`, `password`, `profilePicture`)"
." SELECT `userID`, `forename`, `surname`, `salt`, `password`, `profilePicture` "
." FROM jobseeker WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$query = "UPDATE user SET userType = 'admin' WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$query = "DELETE FROM jobseeker WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$mysqli->commit();
$mysqli->close();
EDIT 3: I hadn't realised your userID was an int (but that's probably what it is since you've said it's auto-incremented in a comment): cast it to an int and/or don't use it as a string (i.e. with quotes) in WHERE userID = '$userID' (but again, don't ever insert your variable directly in a query, whether read from the DB or a request parameter).
There's nothing obviously wrong with your code (apart from it being insecure with using non-escaped values directly from $_GET).
I'd suggest you try the following in order to debug:
var_dump $userData to check that the values are as you expect
var_dump $rQuery and copy and paste it into phpMyAdmin to see if your query is not as you expect
If you don't find your problem then please post back your findings along with the structure of the tables you're dealing with