Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I cannot find any documentation that adequately explains how to use them. How to you retrieve variables from a query and use them and what do the parameters mean to the queries? I want to make my website safe from sql injection and I don't have a clue how to get the following code optimized for safety. I understand how sql injection works, I just don't know how to create the prepared statements or retrieve queries.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
$tempProf = $_POST["professor"];
$tempProfArray = explode("=",$tempProf);
$prof = $tempProfArray[1];
$tempName = $_POST["name"];
$tempNameArray = explode("=",$tempName);
$name = $tempNameArray[1];
$tempNum = $_POST["number"];
$tempNumArray = explode("=",$tempNum);
$num = $tempNumArray[1];
$tempSec = $_POST["section"];
$tempSecArray = explode("=",$tempSec);
$section = $tempSecArray[1];
$tempCat = $_POST["category"];
$tempCatArray = explode("=",$tempCat);
$category = $tempCatArray[1];
$con=mysqli_connect("localhost","root","*******","******");
$result = mysqli_query($con,"SELECT * FROM professors where id='$prof'");
$row = mysqli_fetch_array($result);
if(empty($prof) || empty($name) || empty($num) || empty($section) || empty($category))
{
echo "emptyField";
}
elseif(!is_numeric($num) || !is_numeric($section))
{
echo "NaN";
}
elseif(empty($row))
{
mysqli_query($con,"INSERT INTO classes (className, classNumber, section, classCategory)
VALUES ('$name','$num','$section','$category')");
$classTemp = mysqli_query($con,"SELECT id FROM classes where className='$name' and classNumber='$num' and section ='$section'");
$classTempArray = mysqli_fetch_array($classTemp);
$classId = $classTempArray['id'];
mysqli_query($con,"INSERT INTO professors (name, classes) VALUES ('$prof','$classId')");
$profTemp = mysqli_query($con,"SELECT id FROM professors where name='$prof'");
$profTempArray = mysqli_fetch_array($profTemp);
$profId = $profTempArray['id'];
mysqli_query($con,"UPDATE classes SET professor = '$profId' WHERE id = '$classId'");
echo "success";
}
else
{
$profName = $row['id'];
mysqli_query($con,"INSERT INTO classes (professor, className, classNumber, section, classCategory)
VALUES ('$prof', '$name','$num','$section','$category')");
echo "success";
}
?>
In general, something like this will suffice (note that I use the object orientated way of accessing connections, not procedural like you)
$stmt = $con->prepare( 'INSERT INTO classes (professor, className, classNumber, section, classCategory) VALUES (?, ?, ?, ?, ?)' )
$stmt->bind_param( 'ssiss', $prof, $name, $num, $section, $category );
$stmt->execute();
In this case I am assuming that everything but $num is a string, and $num is an integer.
Here is the relevant doc for binding params: http://www.php.net/manual/en/mysqli-stmt.bind-param.php
$sql="SELECT id FROM classes WEHERE className=? AND classNumber=? AND section =?";
$stmt =$con->prepare($sql);
$stmt->execute(array($name,$num,$ection));
//you can apply this for other queries
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
to explain my question better, i have two files: dbh.inc.php
$dbServername = "localhost";
$dbUsername = "xxxxx";
$dbPassword = "secret";
$dbName = "databasename";
$conn = mysqli_connect($dbServername, $dbUsername, $dbPassword, $dbName);
mysqli_set_charset($conn,"utf8");
if (!$conn) {
die("Connection failed: ".mysqli_connect_error());
}
$table1 = "users";//1
$table2 = "userprofile";//2
$table3 = "twofactorauth";//3
And: database-query.func.php
function selectdb($data, $values, $url) {
include ('dbh.inc.php');
extract($data);
extract($values);
switch ($data['table']) {
case '1':
$table = $table1;
break;
case '2':
$table = $table2;
break;
case '3':
$table = $table3;
break;
}
$sql = "SELECT $rows FROM $table WHERE $where;";
print_r($sql);
die();
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_close($stmt);
mysqli_close($conn);
header("Location: ".$url."?error=sqlerror");
die();
} else {
$amount = str_repeat('s', count($values));
$values = array_values($values);
mysqli_stmt_bind_param($stmt, $amount, ...$values);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$getResult = mysqli_fetch_assoc($result);
mysqli_stmt_close($stmt);
mysqli_close($conn);
$new = array_push($getResult, 'true');
return $getResult;
}
}
So the first holds database connection, and the latter has dynamic querys for insert, update and select for the moment. And i am wondering should i combine the two files, to one. Since every time i need my connect i always use one of my querys and same on the other way around?
Also 2 bonus questions: as you see in my connect file i have my table names and i use numbers in my other files and in the functions connect numbers to names.
Lastly should i use PDO, why?
To answer your question in general - yes, you can put a helper function in the same file where sql connection is made.
However, the code of your actual function is questionable at the very least. Or, to tell you truth, your function selectdb() is a torture for a programmer and shouldn't be stored anywhere. Stick to natural SQL queries written as is. You don't need numbers to represent tables. You don't need $rows variable. Everything could be written right in the SQL string. All you will need is a simple helper function that would reduce the amount of code required to run a query.
Here is an example of such mysqli include file
Once it's included in in your script, you can use it to run any mysql query, to any table, with any list of variables. Check out the following example (you can copy and paste the following code block to your file and run it as is):
<?php
require 'mysqli.php';
#Create a temporary table
$conn->query("CREATE temporary TABLE tmp_mysqli_helper_test
(id int auto_increment primary key, name varchar(9))");
# populate it with sample data
$sql = "INSERT INTO tmp_mysqli_helper_test (name) VALUES (?),(?),(?)";
$stmt = prepared_query($conn, $sql, ['Sam','Bob','Joe']);
echo "Affected rows: $stmt->affected_rows\n";
echo "Last insert id: $conn->insert_id\n";
# Getting rows in a loop
$sql = "SELECT * FROM tmp_mysqli_helper_test WHERE id > ?";
$res = prepared_query($conn, $sql, [1])->get_result();
while ($row = $res->fetch_assoc())
{
echo "{$row['id']}: {$row['name']}\n";
}
# Getting one row
$id = 1;
$sql = "SELECT * FROM tmp_mysqli_helper_test WHERE id=?";
$row = prepared_query($conn, $sql, [$id])->get_result()->fetch_assoc();
echo "{$row['id']}: {$row['name']}\n";
# Update
$id = 1;
$new = 'Sue';
$sql = "UPDATE tmp_mysqli_helper_test SET name=? WHERE id=?";
$affected_rows = prepared_query($conn, $sql, [$new, $id])->affected_rows;
echo "Affected rows: $affected_rows\n";
# Getting an array of rows
$start = 0;
$limit = 10;
$sql = "SELECT * FROM tmp_mysqli_helper_test LIMIT ?,?";
$all = prepared_query($conn, $sql, [$start, $limit])->get_result()->fetch_all(MYSQLI_ASSOC);
foreach ($all as $row)
{
echo "{$row['id']}: {$row['name']}\n";
}
As you can see, a proper helper function can keep all the flexibility and readability of SQL and reduce the amount of code at the same time.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am very new to PDO and I am trying to decode all the rows in my table "test" which contains special entities for instance "('L& eacute;on: The Professional')" instead of "Léon:The Professional".
So, here is what I tried:
<?php
require_once('connection.php');
$stmt = $conn->prepare("SELECT * from test");
$stmt->execute();
while ($results = $stmt->fetch()){
$b = html_entity_decode($stmt);
echo $b;
}
but I have no output printed..
Could someone kindly help me fix it?
prepare() returns a statement object ($stmt in your case)
fetch() returns associative array where the index would be the column name
$sql = "SELECT column1, column2, column3 from test";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = array()
while ($row = $stmt->fetch()){
$resutlt[] = array('column1' => html_entity_decode($row['column1']),
'column2' => html_entity_decode($row['column2']),
'column3' => html_entity_decode($row['column3'])
);
}
var_dump($result);
return $result;
EDIT: to replace the values
//prepare select
$sql = "SELECT id, column1, column2, column3 from test";
$stmt = $conn->prepare($sql);
$stmt->execute();
//prepare update
$update_sql = "UPDATE test SET column1=?,column2=?,column3=? WHERE id = ?;";
$update_stmt = $conn->prepare($update_sql);
while ($row = $stmt->fetch()){
//update
$update_stmt->execute(array(html_entity_decode($row['column1']),
html_entity_decode($row['column2']),
html_entity_decode($row['column3']),
$row['id']
);
}
You did not define $query, thus it has no execute() function. If you wish to execute your prepared statement, you should call $stmt->execute().
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm sure it's a kickself-obvious typo, but I can't see it. I'm trying to INSERT data taken from a HTML form using POST into a MySQL database using PHP. The POST works successfully, but the query fails; I've checked the table to make sure nothing new has been inserted.
Here's the PHP code intended to run the query:
if ($_POST) {
$username = "root";
$password = "root"; //ssh don't tell
$hostname = "localhost";
$dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL");
$dbname = "asoiaf";
$tablename = "charlist";
$id = '3';
$bookIntroduced = $_POST['bookIntroduced'];
$pageIntroduced = $_POST['pageIntroduced'];
$forename = $_POST['forename'];
$surname = $_POST['surname'];
$oldSurname = $_POST['oldSurname'];
$alias = $_POST['alias'];
$title = $_POST['title'];
$pageIntroduced = $_POST['regnalNumber'];
// Below is the query that fails to execute.
$query = "INSERT INTO $tablename (
$id, $bookIntroduced, $pageIntroduced, $title, $forename, $surname, $oldSurname, $alias, $regnalNumber
)";
mysql_query($query) or die("Nah, I don't feel like being helpful.");
mysql_close($dbhandle);
}
And here is the structure of the table given by the DESCRIBE command:
Can anyone help me to identify the problem?
Also, if it wasn't clear, I'm new to PHP and SQL.
Doing a SQL query like this is bad practice in many ways, not least because it's extremely fragile and insecure, but I think it will work if you add VALUES and quote the strings.
$query = "INSERT INTO $tablename VALUES (
'$id', '$bookIntroduced', '$pageIntroduced', '$title', '$forename', '$surname', '$oldSurname', '$alias', '$regnalNumber'
)";
I advise against doing this though, and I'm giving this answer just because it's the shortest path to working code. Always name your table and columns (INSERT INTO mytable (col1, col2) VALUES (:val1, :val2)), and use prepared statements with mysqli.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I can't understand how to create a prepared statement, and all tutorials I have seen was fetching only column.
My normal sql query
$id = $_GET['id'];
$result = mysql_query("SELECT * FROM files WHERE id=$id ") or die(mysql_error());
$row = mysql_fetch_array($result);
$name = $row['name'];
$date = $row['date'];
Please show me how to create a prepared statement and how to fetch more than one column and insert the date into variables.
First of all it's not a good idea to use SELECT * in production. Instead specify needed columns explicitly. Take a look at https://stackoverflow.com/a/65532/1920232.
Now your code might look like
$id = $_GET['id'];
$db = new mysqli('localhost', 'user', 'password', 'dbname');
$sql = 'SELECT name, date FROM files WHERE id = ?'; //specify columns explicitly
if ($stmt = $db->prepare($sql)) { //create a prepared statement
$stmt->bind_param('i', $id); //bind parameters
$stmt->execute(); //execute query
$stmt->bind_result($name, $date); //bind result variables
$stmt->fetch(); //fetch values
}
$db->close();
echo $id, ' ', $name, ' ', $date;
Note: All error handling intentionally skipped for brevity.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have two MySQL query statements that’s need to be convered to PDO using prepare and
BindParam. Any help is appreciated. Thanks.
Here is the problem:
The two non PDO statements are in a for loop and are setup like this:
for ($i = 0; $i < $numItem; $i++)
{
// some codes…, then
$sql = "SELECT pd_name, pd_qty, pd_type
FROM ct_products
WHERE pd_id = ".$productId[$i]."";
$result = dbQuery($sql);
// Some more codes goes here, then.....the 2nd query
$sql = "UPDATE ct_car
SET ct_qty = $newQty
WHERE ct_id = {$carId[$i]}";
dbQuery($sql);
// Some more code, some more codes goes here
// end the for loop
Now, for the new PDO statements, I would like to do something like this to replace the two statements in the for loop above:
// check stock
$sql = "SELECT pd_name, pd_qty, pd_type
FROM ct_products
WHERE pd_id = :productId[$i]";
try
{
// Build the database statement
$stmt = $this->_db->prepare($sql);
$stmt->bindParam(":productId[$i]", $productId[$i], PDO::PARAM_INT);//not sure here
$stmt->execute();
// more code here....
// more codes...
// then the next sql pdo statement:
// update
$sql = "UPDATE ct_car
SET ct_qty = :newQty
WHERE ct_id = {$carId[$i]}";
try
{
// Build the database statement
$stmt = $this->_db->prepare($sql);
$stmt->bindParam(":newQty", $newQty, PDO::PARAM_INT);
$stmt->bindParam(":cartId[$i]", $cartId[$i], PDO::PARAM_INT); // not sure here
$stmt->execute();
$count = $stmt->rowCount();
//more codes....
// code continues....
//end for
Have a look at http://php.net/manual/de/pdostatement.bindparam.php.
The placeholder needs to be a string or a ? sign. (But you cannot mix named placeholders with ? placeholders)
$sql = "SELECT pd_name, pd_qty, pd_type
FROM ct_products
WHERE pd_id = :productId";
$stmt->bindParam(":productId", $productId[$i], PDO::PARAM_INT);
// update
$sql = "UPDATE ct_car
SET ct_qty = :newQty
WHERE ct_id = :cartId";
$stmt->bindParam(":newQty", $newQty, PDO::PARAM_INT);
$stmt->bindParam(":cartId", $cartId[$i], PDO::PARAM_INT);
PDO::PARAM_INT is right if it's really an integer value. The default if you don't set it is PDO::PARAM_STR.
Another thing: you could get into troubles with bindParam because the variable is bound as a reference. In your case it should not matter because you're running execute immediate after the binding. Else have a look at bindValue which you can use in the same way.