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 5 years ago.
Improve this question
I'm trying to build a forum with PHP and PDO at the moment and I have a link which takes you to the page for a category with the categories ID in the URL (eg. WEBSITE/category.php?id=1). When I get there, I want to display the name of the category you are looking at using this $_GET information, but it won't seem to do it for me.
Here is what I've got:
<?php
include 'dbconfig.php';
include 'header.php';
$sql = "SELECT cat_id, cat_name, cat_description FROM categories WHERE cat_id = " . $_GET['id'];
$query = $DB_con->prepare($sql);
$query->execute();
$numRows = $query->fetchColumn();
if (!$query) {
echo 'Something went wrong whilst getting the category from the database.';
} else {
if ($numRows == 0) {
echo 'Sorry, this category does not exist';
} else {
while($catRow = $query->fetch(PDO::FETCH_ASSOC)){
echo $catRow['cat_name'];
}
}
}
include 'footer.php';
?>
So as you can see, I have tried to make a while loop that creates an array using PDO::FETCH_ASSOC allowing me to print category details, but when I go to the page nothing shows up except the header.php and the footer.php. There also aren't any errors that come up. Can anybody see what I'm doing wrong? Or let me know if there's information that I have left out. Thanks.
The problem is with $numRows PDOStatement::fetchColumn does not count the rows that are in the result set. There is PDOStatement::rowCount for that.
As for the sql injection, It is not so much the class or functions you use that make it save, but the way you use the functions. To read more about it go here (link was in the top link in related for me)
Applying what we just learned to your code will give us something like this:
$sql = "SELECT cat_id, cat_name, cat_description FROM categories WHERE cat_id = :id"; // Parameterize query to prevent sql injection
$query = $DB_con->prepare($sql);
$query->execute([":id" => $_GET['id']]); // Binding parameter(s), could also be done using bindParam
$results = $query->fetchAll(PDO::FETCH_ASSOC); // For later use
$numRows = $query->rowCount();
if ($query->errorCode() == "00000") { // I don't think that PDOStatement ever fails to be created, so $query would never not be set
echo 'Something went wrong whilst getting the category from the database.';
} else {
if ($numRows == 0) {
echo 'Sorry, this category does not exist';
} else {
foreach ($results as $category){
echo $category['cat_name'];
}
}
}
Note that the way I bind my parameters (in the execute) is my preferred way, not nessesarily the best way
Related
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 5 years ago.
I have a web page where after connecting to and selecting courses from the database, the courses are displayed with a link to view each course as below:
<div class="col-md-4">
//query db action and assign the query to $result
$result = $dbcon->query($query);
if($result -> num_rows > 0){
//If courses are available(rows > 0), fetch and display them
while($row = $result->fetch_object()){
echo '<h2>'.$row->course_title.'</h2';
echo '<p>'.$row->course_description.'</p>';
echo 'View Course';
}
}
</div>
And this is the code for view.php page:
if(isset($_GET['action']) && $_GET['action'] == "view"){
//Assign var $id to the id from the _GET array
$id = $_GET['t'];
//Use the $id to fetch course details from the database
$query = ("SELECT * FROM courses WHERE course_id = '$id'");
//Query the db action
$result = $db_connect->query($query);
$rows = mysqli_num_rows($result);
if($result && $rows > 0){
while($row = $result->fetch_object()){
echo '<div class="col-md-10">';
echo '<h1>'.$row->course_title.'</h1>';
echo '<p>'.$row->course_description.'</p>';
echo '<div class="col-md-6"><span class="inline-elm">'.$row->course_subject.'</div>';
echo '<div class="col-md-6"><span>'.$row->course_level.'</p></div>'</div>';
}
}
}
My problem is that I'm not sure whether this is proper and of course, safe to do or there is a safer/proper way to do it. Will really appreciate your answers. Thanks
It's fine to pass ids inside urls, but they should be handled like any other data, ie properly sanitized, validated and escaped. A prepared statement is a good way to do this. At the very least, here, since you expect an int, you can do:
$id = intval($_GET['t']);
Note that prepared statements do not protect against XSS vulnerabilities which would occur if doing "echo $id" without wrapping it in htmlspecialchars. Input sanitization is always nice, if it's an int, stick an intval on it! You never know...
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 6 years ago.
Improve this question
I'm trying to implement a basic login functionality on my website. I'm using the following code to fetch data from database and see if the username and password is correct or not:
$STH = $conn->prepare("SELECT * FROM users WHERE uid = '$uid'");
$STH->bindParam(':uid', $uid);
$STH->bindParam(':pass', $pass);
$uid = $_POST['uid'];
$pass = $_POST['pass'];
if($STH->execute()) {
if($row = $STH->fetch()) {
if ($row['pass'] == $pass) {
echo "Logged in Successfully <br>";
} else {
echo "Username or Password Incorrect<br>";
}
} else {
echo "<script>alert('Incorrect Username');</script>";
}
}
}
However, I keep getting the error Incorrect Username even though it is in the database. This means that there is something wrong with how I'm fetching the data after executing the query but I can't understand what exactly.
I was using the prepared statements incorrectly. I wasn't really binding anything in the query. The correct implementation would have been:
$STH = $conn->prepare("SELECT * FROM users WHERE uid = :uid");
So my problem is simple. I'm a PHP beginner (noob programmer in general, started 3 months ago) and I've been following some tutorials on how to build a "search suggestion" system, that checks in the database if what you're typing is like anything in it and displays the results real time with AJAX.
It is working partially. When I type in a full username, for example, it displays the result. But not when I type half of it, or the first letter.
<?php
require 'connect.php';
if (isset($_GET['searchText'])) {
$searchText = $_GET['searchText'];
}
if($query = $db->prepare("SELECT user_name FROM users WHERE user_name LIKE ?")) {
$query->bind_param('s', $searchText);
$query->execute();
$query->bind_result($searchTextResult);
while ($query->fetch()) {
echo $searchTextResult;
}
}
?>
Also, since I'm a total noob I'd love to have any suggestions on the code just to know if I'm employing good practice in general. I heard binding and mysqli are recommended, so I'm trying to stick to them and I rarely get any criticism at all.
The sql query which search a parameter partially would be like this:
"select user_name FROM users WHERE user_name LIKE CONCAT('%',?,'%')"
Thanks everyone for all the answers. This was my first time on StackOverflow and I loved it. I hope I can return the favor someday.
All I had to do was add "%" to the $searchText var right in the beginning and everything ran smoothly.
The correct code is now as follows:
<?php
require 'connect.php';
if (isset($_GET['searchText'])) {
$searchText = $_GET['searchText'] . '%';
}
if($query = $db->prepare("SELECT user_name FROM users WHERE user_name LIKE ?")) {
$query->bind_param('s', $searchText );
$query->execute();
$query->bind_result($searchTextResult);
while ($query->fetch()) {
echo $searchTextResult . "<br />";
}
}
?>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a site in which people can click on names and will be redirected to the corresponding URL
id | name | url
1 | facebook | www.fb.com
I have 1,200,000,023 URL I want to display. URLs which loggedin user have not visited.
My signup information are stored in userdb.php like this:
1|username|a84894gf5sag4f684gh68fh45g|email#gmail.com|NA
My display.php is
<?php
mysql_connect('mysql', '1', 'Py');
mysql_select_db('a5803761_add');
$query =mysql_query('select * from addimage order by ID DESC');
while( $row = mysql_fetch_assoc($query) )
{
echo '<div style="min-width:300px;height:100px;border:red 5px;float:left;">'.$row['name'].'</div>';
}
?>
First, you have to store which user visited which url already. This table should have a structure like that:
CREATE TABLE VISITED(ID INT AUTO_INCREMENT,
USER_ID INT,
URL_ID INT,
PRIMARY KEY(ID),
KEY(USER_ID),
KEY(URL_ID));
Then you have to interprep the users' click to store if they visit an url (with jQuery maybe, and send back this with AJAX) or use a redirecter PHP which logs the clicked url and then redirect the user to this.
If you consider the second one, this PHP should be something:
<?php
//You should check here for the URL to be an integer
$res = mysql_query('SELECT url FROM addimage WHERE id='.$url_id.';');
if (mysql_num_rows($res)>0) {
mysql_query('INSERT INTO VISITED VALUES(NULL,'.$_SESSION['logged_in_user_id'].','.$url_id.');');
$row = mysql_fetch_array($res);
Header('Location: http://'.$row[0]);
}
?>
After that, when you list your URLs, you have to check which are the user didn't visit yet:
<?php
mysql_connect('mysql', '1', 'Py');
mysql_select_db('a5803761_add');
$sql = 'select addimage.id, addimage.name, VISITED.USER_ID from addimage ';
$sql .= 'LEFT JOIN VISITED ON (addimage.id = VISITED.URL_ID) ';
$sql .= 'WHERE (VISITED.USER_ID='.$_SESSION['logged_in_user_id'].');';
$query =mysql_query('order by ID DESC');
while( $row = mysql_fetch_assoc($query) )
{
if ($row[2] == 'NULL') {
echo '<div style="min-width:300px;height:100px;border:red 5px;float:left;">'.$row['name'].'</div>';
}
}
?>
But I think it's not a good idea to list such a lot of urls in one HTML, probably the browser will eat up all the memory. Maybe you should do some kind of filter or paging mechanins.
Please consider this code as an example only, and modify it for your needs.
On the other hand, as others suggested, DO NOT use mysql_ extensions, use mysqli or PDO.
I would advise you to use mysqli or PDO. O, and write "http://" into link.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
So I have a php authentication script and everything works fine. But I'm very unsure about the way I programmed it (I hardcoded some stuff) and I was hoping stack could look through this and point out any potential problems.
Here is the script:
<?php
require_once 'Bcrypt.php';
class Mysql {
private $conn;
function __construct() {
$this->conn = new PDO('mysql:host=***;dbname=***;charset=UTF-8','***','***') or
die('There was a problem connecting to the database.');
}
function verify_Username_and_Pass($un, $pwd) {
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
$query = "SELECT *
FROM Conference
WHERE Username = :un";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':un', $un);
//$stmt->bindParam(':pwd', $pwd);
$stmt->execute();
$row = $stmt->fetchAll();
$hash = $row[0]["Password"];
$is_correct = Bcrypt::check($pwd, $hash);
if ($is_correct) {
// User exist
$firstName = $row[0]["First Name"];
$_SESSION["FirstName"] = $firstName;
return true;
$stmt->close();
}
else {
// User doesn't exist
return false;
$stmt->close();
}
}
}
?>
So how does it look?
Without testing it out, i think your code should work, the usage of BCrypt looks reasonable. There are some points that could be improved of course, some are maybe a matter of opinion.
If your query doesn't return any row (because no such user name exists), you would access an invalid index $row[0]["Password"]. You should first ask, if there is a result, before using it.
Your call for closing the database is placed after the return statement, so it will never be executed. PHP will close the database automatically, so either close it before the return statement, or remove the line.
You named your function verify_username_and_password(), but actually it does also read from the database and writes to the session. These are hidden activities, another developer cannot know that the session changes unless he reads the whole code. One possibility to solve this problem would be, to split up the function.
untested example:
$userRow = getUserRowFromDatabase($userName);
if (!is_null($userRow))
{
if (verifyPassword($password, $userRow["Password"]))
{
addLoggedInUserToSession($userRow["First Name"])
}
}
Each of these three functions have only one problem to solve. This would make your code more readable, ideally it should be like reading a story in a book.
Hope i could give you some ideas.
You can actually use mysql to verify the hash for you
SELECT COUNT(*) FROM Conference
WHERE Username = :un
AND Password = ENCRYPT(:pass, Password)
LIMIT 1