SQL and PHP brief explain - php

$id=$_GET['previd'];
$SQL = "select * from pro where prId=".$id;
I am new to PHP. Can anyone explain what happens here?

This is taking the value of the GET (url) passed variable "previd".
Something like http://example.com/page.php?previd=123 would set
previd to 123.
Next it sets the variable $id to 123.
Next $SQL gets set to select * from pro where prId=123
Next a nefarious person can go to http://example.com/page.php?previd=;DROP TABLE pro and your database has now been deleted.
This is why people use sanitization and prepared statements.
// PDO + MySQL
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);
More Info

Related

PDO WHERE Condition Refuses to Fetch Rows

I have a query:
//Connect to DB w/ PDO
$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$id = $_GET["id"];
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?", PDO::FETCH_ASSOC);
$stmt->bindParam(1, $id);
try{
$stmt->execute();
}catch(PDOException $err){
//some logging function
}
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){
//select column by key and use
$FirstName = $result['Name'];
}
?>
This is the output:
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
The ID is being filled from the $id variable.
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$Name = $row['Name'];
But when try to get
$Name = row['Name'];
I get UNDEFINED VARIABLE: FIRSTNAME
When I run:
<?php var_dump($stmt) ?>
I get this:
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
What am I doing wrong here? It works in another file.
But ID WILL NOT work here even know it's in the query field.
I can see you are fairly new to PHP and PDO.
You have created a script that is vulnerable to SQL-injection,so we will fix that to.
It is important to understand what pdo is doing in order to understand what is going wrong. It will also make you understand the security problem you have created for yourself.
PDO makes it posible for the programmer to "compile" the SQL query before passing it the parameters and execute it.
This has some benefits, mainly it is faster when you want to execute the same query multiple times(with different parameters) and it is much more secure.
Lets take your query as an example:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = $id");
If I would manage to change the contents of $id to something like:
$id="1; SELECT * FROM users;"
The query you would execute would become:
SELECT * FROM nv_hoa WHERE id =1; SELECT * FROM users;
Which would result in you listing every user and password in the user table.
This is a very well know and one of the most dangerous attacks out there.
To counter this, we can use PDO's pre-compiled queries (a.k.a prepared statements)
Instead of:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = $id");
Now use:
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?");
Pdo now compiled your query within the $stmt object.
So now you can execute this query (as many times as you want) using the parameters you prefer.
$stmt->execute([$id]);
This executes the compilled query with the $id parameter. If the $id parameter contains SQL code, it will not become part of the query as you have already compiled the query, as so an SQL-Injection attack becomes near to impossible.
Now that your query is executed, you can fetch the results like:
while($row=$stmt->fetch()){
...
}
So in order to make your code work:
//PDO DB Connect to Fetch & Make into Vars from table nv_hoa
try {
//Connect to DB w/ PDO
$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$id = $_GET["id"];
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?");
$stmt->execute([$id]);
while ($row = $stmt->fetch())
{
$Name = $row['Name'];
}
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
Please do yourself(and others) a favor and research/learn a bit more before posting, you are making class-book mistakes that have been discussed and explained multiple times on pretty much every medium (including stackoverflow).
I solved the issue of a bool(false) output from a query even though the query dump had the ID.
Here is the fix.
The output of
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = ?", PDO::FETCH_ASSOC);
was
object(PDOStatement)#2 (1) { ["queryString"]=> string(44) "SELECT * FROM nv_hoa WHERE id = 0100782019-8" }
Which showed the ID was being passed properly. But the ID contained a special character '-' which caused the $stmt->execute([$id]); to break the page because $id was empty.
This was fixed as follows with single quotes.
$stmt = $pdo->query("SELECT * FROM nv_hoa WHERE id = '$id'");
$stmt->bindParam(1, $id);
$stmt->execute();
I have found HUNDREDS of posts about this topic and this solves it. If you varaible has special chacters in a PDO statement you need to do this id = '$id'"

select sql row using pdo with where statement

This is my first time to try PDO and still learning it. I am more familiar in using mysql or mysqli in developing php system.
After deep searching and searching I still can't seem to understand how to query using PDO
In my code I used mysqli inside a function to be called in index.php
function getUsery(){
$ip = getIPAddress();
$query = mysqli_query("select userID from tblUsers where logged='1' AND ip='$ip'");
$row = mysqli_fetch_array($query);
$emp = $row['userID'];
$logged = $row['logged'];
$userlvl = $row['userLevel'];
$_SESSION['logged'] = $logged;
$_SESSION['userLevel'] = $userlvl;
return $emp;
}
I don't really know how to select sql query using PDO with 'where' statement. Most of what I found is using array with no 'where' statement
How can I select the userID where logged is equal to '1' and ip is equal to the computer's ip address and return and display the result to the index.php
There's SQL statement with WHERE in PDO
$sql = "SELECT * FROM Users
WHERE userID = ?";
$result = $pdo->prepare($sql);
$result->execute([$id]);
Assuming that you know how to connect database using PDO, here is how to select SQL with PDO.
$stmt = $db->prepare("select userID from tblUsers where logged = '1' AND ip = :ip");
$stmt->execute(array('ip' => $ip));
$listArray = $stmt->fetchAll();
Notice the :ip at the end of SELECT. If you don't use ? as a parameters, the prefix : is mandatory and the word after that should be the same as the key in the execute function.
EDIT
In case that the above code is inside the function and $db is outside the function, declare $db as global variable inside the function.
This one is imo one of best guides on PDO and how to use it:
https://phpdelusions.net/pdo
WHERE is a part of query and queries in PDO are not much different from pure *sql queries, just there is going on a bit filtering on execution. Read the guide carefully and you will be able to execute any query you need to.

Select all posts made on the same date

I have a table structure like this:
sender| receiver| message|date|time
----------------------------------
How do I select all the messages written on the same date, with them appearing at the top, just like Facebook Chat?
I've tried something like this:
<?php
$con=mysql_connect("localhost","root","");
$db=mysql_select_db ("chat",$con);
$query=" select * from chat where sender='$send'
and receiver='$rec' order by date";
$result=mysql_query($query);
while($r2=mysql_fetch_array($result))
echo "<div>{$r2['date']}</div>";
{
echo"<div>{$r2['message']}</div>";
}
?>
You're trying to run an SQL query directly from PHP, which you can't do - you'll need to connect to your database first. Then you need to pass the $send and $rec variables to your database, preferably through prepared statements to prevent SQL injection.
It depends on whether you're using MySQLi or PDO as to exactly how you should do that, but I'll assume you're not using the mysql_ constructor, as that was deprecated as of PHP 5.5, and is removed in PHP 7.
As such, here's an example of how to do this through MySQLi with prepared statements:
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$stmt = $mysqli->prepare(
"SELECT * FROM tablename WHERE sender = ? && receiver = ?");
$stmt->bind_param("ss", $send, $rec);
// "ss' is a format string, each "s" means string
// Each variable gets passed to the question marks, in order
$stmt->execute();
$stmt->bind_result($result);
You then have the results stored in $result, and are free to manipulate from there.
Hope this helps! :)

Player score update with PHP MySQL

I have a users table where I want to update the scores each time a user finishes the game. Unityscript part is working fine but after I post the score to the database it appears doubled or tripled. I post the score as int and also the table column is of int format. My PHP looks like this:
try {
$db = new PDO("mysql:host=$host;dbname=$dbname", $db_user, $db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$data = array(
':username' => $_POST['username'],
':score' => $_POST['score']);
$statement = $db -> prepare ("UPDATE users SET score = score + :score
WHERE username = :username");
$statement->execute($data);
}
catch(PDOException $e) {
echo $e->getMessage();
}
Any help or advice is appreciated.
You are using prepared statements, but you are still allowing injection by directly implementing the $score variable. Do the same thing with score that you did with username.
What do you mean by double or triple? Do you mean that the number is two or three times bigger? If so, try using a SELECT statement to fetch the score and do the math in PHP. Then, UPDATE the users table.
Doing this will allow you to better understand what you are doing wrong. Have you tried echoing the value of score within your try and catch to see if the value repeats? The code may be running more than once.
$statement = $db -> prepare ("UPDATE users SET score = :score
WHERE username = :username");
use this, i think it will work

PHP query single line from database

I'm having a problem echoing a single line from a sql query. I'm still pretty new at this but I can't figure it out at all.
I have a page titled "listing.php?id=7"
Inside the page is this script:
<?php
mysql_connect("localhost", "user", "pass");
mysql_select_db("table");
$query = "SELECT * FROM vehicles WHERE id='$id'";
$result = mysql_query($query);
while($r = mysql_fetch_array($result))
{
$year = $r["year"];
$make = $r["make"];
$model = $r["model"];
$miles = $r["miles"];
$pricepay = $r["pricepay"];
$pricecash = $r["pricecash"];
$transmission = $r["transmission"];
$color = $r["color"];
$vin = $r["vin"];
echo "$year $make $model $miles $pricepay $pricecash $transmission $color $vin<br />";
}
?>
The problem lies within "WHERE id='$id'". When I use a var, it displays nothing, but if I manually make it my ID number, example 7, it works fine. What's am I doing wrong?
if
SELECT * FROM vehicles WHERE id=7
works but
SELECT * FROM vehicles WHERE id='$id'
doesn't work
then get ride of the quotes around $id
So
SELECT * FROM vehicles WHERE id=$id
The quotes are turing $id into a string comparison - which won't work if the column type is integer.
Even better, use PDO. Create the connection:
$db = new PDO("mysql:host=localhost;dbname=someDBname", 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
but do it in just one script, preferably in a singleton or somesuch. This has many advantages, including placing all database passwords in one file (which is easier to secure) and reducing the possibility of typos in the hostname, database name, username or password causing the connection to fail. Use it as:
try {
$query = $db->prepare(
"SELECT year, make, model, miles, pricepay,
pricecash, transmission, color, vin
FROM vehicles WHERE id=?"
);
$query->execute(array($_REQUEST['id']));
while ($row = $query->fetch(PDO::FETCH_NUM)) {
echo implode(', ', $row);
}
} catch (PDOException $exc) {
echo "Query failed.";
}
This uses a prepared query, which is not vulnerable to SQL injection. It also does away with "or die".
In case you haven't seen singletons, here's an example:
class DB {
private static $db;
static function open() {
if (! isset(self::$db) ) {
self::$db = new PDO('mysql:host=hostName,dbname=dbName', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$db;
}
}
Then, whenever you need a connection, just call DB::open(). If you need to connect to multiple hosts, store PDOs in an associative array within DB, rather than DB::$db. In this case, you could put the connection information in the DB script, or put it in a separate configuration file that DB parses.
Take your original code and add this line before the query:
$id = (int)$_GET['id']; // Sanitize Integer Input
And change your query as others suggested to remove the quotes:
$query = "SELECT * FROM vehicles WHERE id=$id";
I am assuming your id is a normal mysql auto_increment which starts at 1. That means if `$_GET['id'] is anything but a number, it will come back as 0 and thus not match anything in the database.
$query = sprintf("SELECT * FROM vehicles WHERE id=%d", mysql_real_escape_string($_GET['id']));
$result = mysql_query($query);
I hope you don't have register globals on which means you should use $_GET['id'];
You can't put quotes around the id field if it's an int in your table
Use mysql_real_escape_string to prevent sql injection

Categories