This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 6 years ago.
I am trying to select data from mySQL database,
I execute the following code:
<?php $_SESSION["dog_park"] = $_GET['keyword'] ?>
<div class="review"> <!-- Creating a div with the class 'review -->
<!-- but POST varibale in here for dog park name -->
<h1><?php echo $_SESSION["dog_park"]; ?></h1>
<table border="1" cellspacing="5" cellpadding="5" width="100%">
<thead>
<tr>
<th>Park Name</th>
<th>Street</th>
<th>Suburb</th>
<th>Dog Park Area (m2)</th>
</tr>
</thead>
<tbody>
<?php
$result = $conn->prepare("SELECT * FROM dog_parks.items where suburb = '$_SESSION[dog_park]'");
$result->execute();
for($i=0; $row = $result->fetch(); $i++){
?>
<tr>
<td><label><?php echo $row['Park_Name']; ?></label></td>
<td><label><?php echo $row['Street']; ?></label></td>
<td><label><?php echo $row['Suburb']; ?></label></td>
<td><label><?php echo $row['Dog_Park_Area_(m2)']; ?></label></td>
</tr>
<?php } ?>
</tbody>
</table>
When that script executes it displays the following error:
It has something to do with the session variable, if i enter a static value for the mySQL query it will display table data correctly, but fail when the $_SESSION variable is present.
That string contains quotes, that breaks your SQL string encapsulation. Use the prepared statements as they are meant to be, parameterized, and the issue will be gone.
$result = $conn->prepare("SELECT * FROM dog_parks.items where suburb = ?");
$result->execute(array($_SESSION[dog_park]));
You can read more:
http://php.net/manual/en/pdo.prepared-statements.php
How can I prevent SQL injection in PHP?
As is your query was running as:
SELECT * FROM dog_parks.items where suburb = ''Tramway''
(roughly, if you'd included text of error message, not image I could supply real query)
Which is invalid because '' is what you are comparing. The Tramway'' it doesn't know what to do with. This coincidentally is how SQL injections occur.
Related
I'm having some trouble generating output from an sql query via php. When I execute the query "SELECT * from projectdb WHERE name = 'Crys' or ID = 14142" on phpmyadmin it returns valid results, but attempting to do so by passing a post value yields an empty table. See code below:
<html>
<title>Search result</title>
<body>
<table border="1px">
<tr>
<td>name</td>
<td>ID</td>
<td>position</td>
<td>job scope</td>
<td>contact_no</td>
<td>days_off</td>
<td>wages</td>
</tr>
<?php
if (isset($_POST['value']))
{
$ID=$_POST['staff ID'];
$name=$_POST['staff name'];
$admincon =mysqli_connect("localhost","root","","projectdb");
/* Query I need to execute and print in table*/
$sqlsrch2 =mysqli_query($admincon, "select * from staff where name='".$name."' or ID='".$ID."'");
while($result=mysqli_fetch_assoc($sqlsrch2)){
?>
/* table where results needs to be printed */
<tr>
<td><?php echo $result['name'];?></td>
<td><?php echo $result['ID'];?></td>
<td><?php echo $result['position'];?></td>
<td><?php echo $result['job_scope'];?></td>
<td><?php echo $result['contact_no'];?></td>
<td><?php echo $result['days_off'];?></td>
<td><?php echo $result['wages'];?></td>
</tr>
<?php
}
}
?>
</table>
</body>
</html>
A few points to note:
I'm just a beginner in PHP and SQL; I'm just looking for a simple answer.
Security is not at all a concern here; this is just a rough demo.
If this is marked as duplicate, do help redirect me to a link where I can get the solution. Thanks!
I am making posts of computer builds. I have a completely separate MYSQL database that I track computer components, assigned to each build. For instance, BuildID = 4 will have "Asus Rampage VI Extreme Motherboard x299", Core i9 7980xe Extreme LGA 2066" as values that come from the following query:
"SELECT BCats.Cat, BParts.ItemName, BParts.ItemSKU, BParts.ItemURL, BParts.ItemPrice, BParts.Qty, BParts.ItemPrice*BParts.Qty AS Price
FROM BParts
INNER JOIN BCats ON BCats.CatNo = BParts.ItemCat
WHERE BParts.BuildNo = 4 AND BParts.SystemNo = 1
ORDER BY BCats.CatNo ASC"
I need to take "BParts.BuildNo = 4" and turn it into a variable, such as "BParts.BuildNo = $buildNo". Then, for each customer that builds one of my desks, I can a photo gallery and just insert the shortcode [build] posts the table for all of the parts belonging to build number 4 (see it work at https://badvolf.com/en/declassified-systems-build/
Forgive me, but I am stumped at how to do it. I have searched everywhere, but nothing seems to fit what I am looking for, but I know that it can be done somehow. Here is what I have so far, and it generates the table that you see on the above link:
function wp_build_shortcode(){
$query = "SELECT BCats.Cat, BParts.ItemName, BParts.ItemSKU, BParts.ItemURL, BParts.ItemPrice, BParts.Qty, BParts.ItemPrice*BParts.Qty AS Price
FROM BParts
INNER JOIN BCats ON BCats.CatNo = BParts.ItemCat
WHERE BParts.BuildNo = 4 AND BParts.SystemNo = 1
ORDER BY BCats.CatNo ASC";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Build Name</title>
</style>
</head>
<body>
<table id="example" class="display" cellspacing="0" width="100%">
<col width="15%">
<col width="85%">
<col width="20%">
<thead>
<tr>
<th></th>
<th>Item</th>
<th>Qty</th>
<th>Total Price</th>
</tr>
</thead>
<tbody>
<?php
if ($result = mysqli_query($GLOBALS['link'], $query)) {
while ($row = $result->fetch_assoc()) { ?>
<tr>
<td><?php echo $row["Cat"]; ?></td>
<td><?php echo $row["ItemName"]; ?></td>
<td><?php echo $row["Qty"]; ?></td>
<td><?php echo $row["Price"]; ?></td>
</tr><?php }
} ?>
</tbody>
</table>
<?php
}
add_shortcode('build', 'wp_build_shortcode');
?>
So, how can I do something like [build="4"] and pass that value on to the query? Thank you in advance!
You need to give your function at least one parameter. For Example wp_build_shortcode($attributes). $attributes will be an array with the parsed shortcode parameters. In your case ['build' => '4']. Then you can assign it to any local variable:$buildNo = issest($attributes['build']) ?
intval($attributes['build']) : 0;`. You can find more information here.
In WP shortcodes are accessible for very low privileged users (subscribers). Therefore you should treat the parameters as untrusted user input, and protect yourself from SQL injections and other exploits. In your case the intval in the above code should be enough, but prepared statements are a better practice.
I am having an issue with MySQL data not being displayed via PHP
Below is the code which the data should be outputted into:
THIS IS individual_item_page.php
<?php
if (isset($_GET['suburb']))
{
$_SESSION["dog_park"] = $_GET['suburb'];
}
elseif (isset($_GET['keyword']))
{
$_SESSION["dog_park"] = $_GET['keyword'];
}
else
{
$_SESSION["dog_park"] = $_GET['rating'] ;
}
?>
<h1><?php echo $_SESSION["dog_park"]; ?></h1>
<table border="1" cellspacing="5" cellpadding="5" width="100%">
<thead>
<tr>
<th>Park Name</th>
<th>Street</th>
<th>Suburb</th>
<th>Dog Park Area (m2)</th>
</tr>
</thead>
<tbody>
<?php
$result = $conn->prepare("SELECT * FROM dog_parks.items where suburb = ?");
$result->execute(array($_SESSION['dog_park']));
for($i=0; $row = $result->fetch(); $i++){
?>
<tr>
<td><label><?php echo $row['Park_Name']; ?></label></td>
<td><label><?php echo $row['Street']; ?></label></td>
<td><label><?php echo $row['Suburb']; ?></label></td>
<td><label><?php echo $row['Dog_Park_Area_(m2)']; ?></label></td>
</tr>
<?php } ?>
</tbody>
</table>
Below is the output page after the code has been executed:
(No data)
A basic overview of how the page is meant to work is,
I have 3 search types via
keyword
suburb
rating
If I want to search for a dog park by suburb I would select a suburb from the drop down box. (Code at bottom of page)
A table would then display the dog parks in that suburb/area which I would then click on one of those parks displayed (Hyperlinked),
which will take me to the page I am having issues with, 'individual_item_page.php'
Below is the code for the suburb search page which then has a hyperlink to the 'individual_item_page.php' where the issue is..
THIS IS SUBURB SEARCH PAGE
<table class="center"> <!-- Creating a table with the class of 'center' -->
<!-- DROP DOWN BOX -->
<?php
$SUBURB = $_POST['suburb'];
$stmt = $conn->prepare("SELECT dog_park_name from items where suburb='$SUBURB'");
$stmt->execute();
for($i=0; $row = $stmt->fetch(); ){
$_SESSION["dog_park".$i] = $row[0];
?>
<!-- DISPLAY RESULTS -->
<tr> <!-- Adding the first table row -->
<th>Dog Park</th> <!-- Adding the second table header -->
</tr>
<tr> <!-- Adding the second table row -->
<td><a href="individual_item_page.php?suburb='<?php echo $row[$i] ?>' " ><?php echo $row[$i] ?></a></td> <!-- Add the second cell on the second row -->
</tr>
<?php }
?>
</table>
This issue has baffled me for many hours now, any help would be appreciated.
On individual_item_page.php, you have a couple of things going on:
You test for the presence of the first 2 GET variables you may be setting $_SESSION["dog_park"] to, but you fail to test for the third GET variable, $_GET['rating'].
Your SQL statement on that page is searching for a suburb, assuming that $_SESSION["dog_park"] was set to a suburb, despite the fact it may be set to $_GET['keyword'] or $_GET['rating']. Also, I'm not sure why you are binding $_SESSION['dog park'] as an array parameter in your $result->execute() statement.
On the suburb search page you are searching the table items but on the individual search page you are searching dog_parks.items. Was this intentional?
Important Note: On your suburb search page, you use a prepared statement but manually add a user entered variable instead of binding it, which defeats the protection supplied by binding parameters, which is to prevent user-entered data from being directly added to SQL statements.
This is my first posting in SO, my apologize if I opened an existing question. As I couldn't find the result in Google. Sorry to said but I'm still fresh in PHP PDO and in learning stage.
Back to my question, currently I'm building a customer visit logs from my wife but I'm stuck with the result. I have two table which one stores the customer information and another table store the visit details. I uploaded the test table at here: SQL Fiddle
And below is my current coding and I'm using PHP PDO while
<?php
require_once 'dbconnect.php';
$p_id = $_GET['name'];
try {
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$sql = "SELECT customer.fname, customer.lname, customer.gender, services.treatment, services.date
FROM customer LEFT JOIN services
ON customer.id = services.customer_id
WHERE customer.slug LIKE :id";
$q = $conn->prepare($sql);
$q->execute(array('id' => $p_id));
$q->setFetchMode(PDO::FETCH_ASSOC);
} catch (PDOException $pe) {
die("Could not connect to the database $dbname :" . $pe->getMessage());
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<div id="container">
<h1>Customer Record</h1>
Name: <br />
Gender: <br />
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th>Customer Name</th>
<th>Customer Gender</th>
<th>Treatment</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php while ($r = $q->fetch()): ?>
<tr>
<td><?php echo htmlspecialchars($r['fname']), ' ', htmlspecialchars($r['lname'])?></td>
<td><?php echo htmlspecialchars($r['gender']); ?></td>
<td><?php echo htmlspecialchars($r['treatment']); ?></td>
<td><?php echo htmlspecialchars($r['date']); ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
Seach Again
</body>
</div>
</html>
And I achieve as what SQL Fiddle result, but what I wanted is, the name and gender is not keep repeating.
I attached together with the screenshot:
Screenshot
What I want is as per the screenshot image, Name: John Doe and Gender: Male, should be on top and not keep on repeating while the table below show all the visit details. I tried to modified the code but it seems it don't really work out.
Please advise me as I'm really out of idea how to achieve what I want.
Thank you so much.
Since you do a LEFT JOIN in your SQL query, you know ahead of time that all of the fname, lname and gender values returned by $q->fetch() are going to be for the same customer.slug, right? So you can count on that.
My suggestion would be to instead use the fetchAll() function to get an array of all records for customer.slug, and then render that in your view. For example (haven't tested this) you could add the following after $q->setFetchMode(PDO::FETCH_ASSOC); ...
$cs = $q->fetchAll(); // customer services join
Then, in your <html> view, you could do something like the following:
<h1>Customer Record</h1>
Name: <?php echo htmlspecialchars($cs[0]['fname'].' '.$cs[0]['lname']); ?> <br />
Gender: <?php echo htmlspecialchars($cs[0]['gender']); ?> <br />
<table>
<thead>
<tr>
<th>Treatment</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php foreach($cs as $r): ?>
<tr>
<td><?php echo htmlspecialchars($r['treatment']); ?></td>
<td><?php echo htmlspecialchars($r['date']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
Of course, it might also be a good idea to check to see that any records were returned by your query and display a "not found" message if not. After all, $cs[0] might be empty, giving you a PHP error.
A user chooses a value from a select box which is then passed via a form to another page which should show the mysql record of that selection. This is not showing any results, however the value is definitely being passed as it can be echoed out.
<?php
include("top.php");
$db = getConnection();
$eventID = $_POST['eventID'];
echo $eventID;
$queryEvent = $db->query("SELECT * FROM projectEvent WHERE eventID = '$eventID'");
$queryEvent->setFetchMode(PDO::FETCH_ASSOC);
$record = $queryEvent->fetchALL();
?>
<form name="form1" id="form1" method="post" action="deleteOpen.php">
<p> are you sure you want to delete the following Open Day? </p>
<table width="200" cellpadding="0" cellspacing="0">
<tr>
<th scope="row">eventID</th>
<td><?php echo $record -> eventID; ?></td>
</tr>
<tr>
<th scope="row">propertyID</th>
<td><?php echo $record -> propertyID; ?></td>
</tr>
<tr>
<th scope="row">eventDate</th>
<td><?php echo $record -> eventDate; ?></td>
</tr>
<tr>
<th scope="row">eventTime</th>
<td><?php echo $record -> eventTime; ?></td>
</tr>
<tr>
<th scope="row">eventDescription</th>
<td><?php echo $record -> eventDescription; ?></td>
</tr>
</table>
Can anyone suggest why the values are not shown in the table?
Thanks
to show data you shouldn't use POST method but GET instead.
either escape your values with PDO::quote or use prepared statements with prepare/execute instead of query()
if you are using ASSOC mode - why you are accessing them as a object properties?
Moreover, you actually have a nested array, but accessing it as a single object. if you don't need an array - don't use fetchAll() then
ALWAYS have error_reporting(E_ALL); in your scripts to see these silly mistakes.
You can concatenate the variable separately like this :
$queryEvent = $db->query("SELECT * FROM projectEvent WHERE eventID = ".$eventID.")";
Normally I do a little bit different of a method. It may not point out the problem but I think it will solve it. I usually dont use variables inside of quotes, but try below.
$sql = sprintf("SELECT * FROM projectEvent WHERE eventID = '%s'", $eventID);
$queryEvent = $db->query($sql);