String %0D%0A causing comparison issues in SQL? - php

I have a drop down box that contains a list of names and a search field.
The drop down is populated with a list of names from the database and the search field allows you to perform a wild card search.
At the moment the wild card search works as expected but choosing a name from the drop down does not work.
I believe this might be possibly because of some unwanted characters as I am seeing the below in my address bar on the browser having chosen a name from the drop down list and clicked the search button:
http://localhost:81/connect/players/?name=%0D%0A3&text=&action=search
I think that text above (%0D%0A) is causing a problem as my code looks like this:
if (isset($_GET['action']) and $_GET['action'] == 'search')
{
include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
$id = $_GET['name']; // name slightly confusing but does return the id
$text = $_GET['text'];
try
{
$sql = "SELECT id, name, age FROM player
WHERE player.id = '$id'
OR player.name LIKE '%$text%'
GROUP BY player.id";
$s = $pdo->query($sql);
}
catch (PDOException $e)
{
$error = 'Error fetching names.' . $e->getMessage();;
include 'error.html.php';
exit();
}
// This is responsible for populating the new player info underneath all
foreach ($s as $row)
{
$names[] = array('id' => $row['id'], 'name' => $row['name'], 'age' => $row['age']);
}
include 'searchprofiles.html.php';
exit();
}
And I believe this is preventing it from comparing the id in the database with the id that is stored in the variable $id.
I have however also just manually stripped %0D%0A out from the address bar and it still doesn't work so perhaps there might be another issue?
It should also be noted that if no value is selected from the drop down and no wild card is entered then all rows are returned.
HTML is as follows:
SEARCHPROFILES.HTML.PHP
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/includes/helpers.inc.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Manage Jokes: Search Results</title>
</head>
<body>
<h1>Search Results</h1>
<?php if (isset($names)): ?>
<table>
<tr><th>Name</th><th>Options</th></tr>
<?php foreach ($names as $name): ?>
<tr>
<td><?php htmlout($name['name']); ?></td>
<td><?php htmlout($name['age']); ?></td>
<td>
<form action="?" method="post">
<div>
<input type="" name="id" value="<?php
htmlout($name['id']); ?>">
<input type="submit" name="action" value="Edit">
<input type="submit" name="action" value="Delete">
</div>
</form>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<p>New search</p>
<p>Return to JMS home</p>
</body>
</html>
BELOW IS THE HTML FOR THE FORM WHERE THE VALUES ARE ADDED.
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/includes/helpers.inc.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Manage Profiles</title>
</head>
<body>
<h1>Manage Profile</h1>
<p>Add new profile</p>
<form action="" method="get">
<p>View player profiles satisfying the following criteria:</p>
<div>
<label for="name">By name:</label>
<select name="name" id="name">
<option value="">Any name</option>
<!-- populates the drop down with names -->
<?php foreach ($names as $name): ?>
<option value="
<?php htmlout($name['id']); ?>">
<?php htmlout($name['name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="text">Containing text:</label>
<input type="text" name="text" id="text">
</div>
<div>
<input type="hidden" name="action" value="search">
<input type="submit" value="Search">
</div>
</form>
</body>
</html>
Any help is greatly appreciated.
Thanks

The reason is the line break you have in your form control:
Change
<option value="
<?php htmlout($name['id']); ?>">
<?php htmlout($name['name']); ?>
</option>
To
<option value="<?php htmlout($name['id']); ?>">
<?php htmlout($name['name']); ?>
</option>

Related

Create session from drop down list items

I have created a drop-down list that shows the members which have been added from the user. The script for this is this one:
<?php include('server.php'); ?>
<?php
$connect = mysqli_connect("localhost", "root", "", "geofence");
?>
<html>
<head>
<title>Add members</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
</head>
<body>
<div class="container">
<br /><br />
<h2 align="center">Please, choose a family member</h2>
<br /><br />
<div class="form-group" align="center">
<form name="dropdown" action="" method="post">
<select name="choose" id="choose" width="150" style="width: 150px">
<option value="" selected disabled hidden>Choose Member</option>
<?php
$res=mysqli_query($connect,"select *
from member
where user_id=".$_SESSION['user_id']."");
while($row=mysqli_fetch_array($res)) {
?>
<option><?php echo $row["name"]; ?></option>
<?php
}
?>
</select>
</form>
<input type="button" name="ok" id="ok" class="btn btn-info" value="OK" />
</div>
</div>
</body>
</html>
<script>
$(document).ready(function(){
$('#ok').click(function(){
$(location).attr('href', 'http://localhost/Houston/index.php')
});
});
</script>
Now, what I'm trying to do is to create a session ($_SESSION['member_id']) which refers to the name that is selected from the list. I have tried several things so far but with no success. An example is this:
if (isset($_POST['choose'])) {
if (count($errors)==0) {
$query="SELECT * FROM member where name=".$_POST['choose']."";
$result=mysqli_query($db,$query);
if (mysqli_num_rows($result)==1) {
$row=mysqli_fetch_assoc( $result);
$member_id=$row['member_id'];
$_SESSION['member_id'] = $row['member_id'];
}
}
}
I need the $_SESSION['member_id'] so I can use it on another file and populate my database. What is missing?
The problem is in the option tag, you have to specify de value of each option in the select tag , like this:
<option value="<?php echo $row["member_id"];?>"> <?php echo $row["name"]; ?> </option>
So, next you just have to declare the $_SESSION for your option value
if (isset($_POST['choose'])) {
$_SESSION['member_id']=$_POST["choose"];
}

Delete article with submit button

i have a problem with deleting the articles. I want it to delete after click on submit button but i dont know how. I do not want use javascript to autosubmit form in select tag. Can u help me ? I would appriciate that. Thanks.
<?php
session_start();
include_once('../includes/conn.php');
include_once('../includes/article.php');
$article= new Article;
if(isset($_SESSION['logged_in'])){
if(isset($_POST['id'])){
$id=$_POST['id'];
$query=$pdo->prepare('DELETE FROM articles WHERE article_id=?');
$query->bindValue(1, $id);
$query->execute();
header('Location: delete.php');
}
$articles=$article->fetch_all();
?>
<html>
<head>
<title>CMS Tutorial</title>
<link rel="stylesheet" href="assets/style.css" />
</head>
<body>
<div class="container">
CMS
<br/>
<h4>Delete article:</h4>
<form action="delete.php" method="post" name="id">
<select>
<?php foreach($articles as $article){?>
<option value="<?php echo $article['article_id']; ?>"><?php echo $article['article_title']; ?></option>
<?php } ?>
</select>
<input type="submit" value="Delete article">
</form>
</div>
</body>
?>
According to your code, shift name="id" from form to select.
You are trying to get selected id of drop down, so the name should be given to select.
<form action="delete.php" method="post" name="id">
<select>
to
<form action="delete.php" method="post">
<select name="id">
Another issue noticed in your code is, you should terminate execution
immediately after header('Location: delete.php'); with die(); or
exit(); to ensure remaining lines should not be executed. In PHP,
header() is just a function which helps in setting header, and here
you are settling Location header, which further handled by browser
for taking necessary action (here redirection). So, header() does
not ensure stopping execution of remaining code.
add <?php echo $_SERVER['PHP_SELF']; ?> to the form instead of delete.php to execute the php code above and i assume the file looks as your post .
and add name="id" to select element to grap the post value to manipulate instead of form.
i hope this works according to what you provide in your post.
session_start();
include_once('../includes/conn.php');
include_once('../includes/article.php');
$article= new Article;
if(isset($_SESSION['logged_in'])){
if(isset($_POST['id'])){
$id=$_POST['id'];
$query=$pdo->prepare('DELETE FROM articles WHERE article_id=?');
$query->bindValue(1, $id);
$query->execute();
header('Location: delete.php');
}
$articles=$article->fetch_all();
?>
<html>
<head>
<title>CMS Tutorial</title>
<link rel="stylesheet" href="assets/style.css" />
</head>
<body>
<div class="container">
CMS
<br/>
<h4>Delete article:</h4>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<select name="id">
<?php foreach($articles as $article){?>
<option value="<?php echo $article['article_id']; ?>"><?php echo $article['article_title']; ?></option>
<?php } ?>
</select>
<input type="submit" value="Delete article">
</form>
</div>
</body>

Making form data stay on PHP page from a multi select form

Okay so I have 1 html page setup with a HTML multiple Attribute from. This is how it is setup:
<!DOCTYPE html>
<html>
<body>
<form action = "otherpage.php" method= "post">
<select name = "cars[]" multiple="multiple" size="4">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button type = "submit" value= "Submit">Submit</button>
<button type = "reset" value= "Clear">Clear</button>
</form>
</body>
</html>
I have a second php page, lets call it "otherpage.php" and this is how it is setup:
<!DOCTYPE html>
<html>
<body>
<form action = "" method= "post">
Name: <input type = "text" name = "yourname" />
<button type = "submit" value= "Submit2">Submit</button>
<input type="hidden" name="f" value=<?php $cars= array(); $cars= $_POST['cars']; print_r($cars); ?> />
<?php
if(isset($_POST['f'])) {echo ($_POST['f']);}
?>
</body>
</html>
When I hit the first submit on the first html page the array prints out fine. Then when I hit the other submit again on "otherpage.php", the array no longer exists and I get an error. How can I get the cars array to stay forever no matter how many times I submit on otherpage.php?
The easiest way would be to store the data in a session variable.
You have to have session_start() at the top of every file you want to use it on.
Then when you get the $_POST values:
$_SESSION['post'] = $_POST;
After that, you can do what you want with it on any other file.
You need to implode the array to string and explode it again to get back your array or encode it to a json string and reencode it again either way will work
<?php
$cars = isset($_POST['cars']) ?
$_POST['cars'] : isset($_POST['f']) ? explode(',',$_POST['f']) : [];
?>
DOCTYPE html>
<html>
<body>
<form action = "" method= "post">
Name: <input type = "text" name = "yourname" />
<button type = "submit" value= "Submit2">Submit</button>
<input type="hidden" name="f" value="<?php echo implode(',', $cars)?>"/>
</body>
</html>
I know you already accepted an answer, but it would be petty to give up my tests without showing you my version too.
The echo '<pre>'... is just for displaying results. Notice the use of value="<?php echo print_r($cars, true); ?>".
<?php
if (isset($_POST['cars'])) {
$cars = $_POST['cars'];
} elseif (isset($_POST['f'])) {
$cars = $_POST['f'];
} else {
$cars = array();
}
echo '<pre>' . print_r($cars, true) . '</pre>';
?>
<!DOCTYPE html>
<html>
<body>
<form action="" method="post">
Name: <input type="text" name="yourname" />
<?php
foreach ($cars as $car) {
echo '<br/>' . $car . '<input type="radio" name="car" value="' . $car . '" />';
}
?>
<button type="submit" value="Submit2">Submit</button>
<input type="hidden" name="f" value="<?php echo print_r($cars, true); ?>" />
</form>
</body>
</html>
Good luck.
EDIT 2: Using session
You don't need a hidden input anymore. I changed page names and a bit of html also.
Page cars_select.php:
<!DOCTYPE html>
<html>
<head>
<title>Cars selecting page</title>
</head>
<body>
<form action="cars_list.php" method= "post">
<select name = "cars[]" multiple="multiple" size="4">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button type="submit" id="selectSubmit" name="selectSubmit" value="Submit">
Cars selected. List them!
</button>
</form>
</body>
</html>
Page cars_list.php
<?php
session_start();
// Upon clicking on "selectSubmit" button.
if (isset($_POST['selectSubmit'])) {
// Set POST received cars list as session variable.
$_SESSION['cars'] = isset($_POST['cars']) ? $_POST['cars'] : array();
echo 'Called by CARS SELECT page.';
}
// Upon clicking on "listSubmit" button.
if (isset($_POST['listSubmit'])) {
echo 'Called by CARS LIST page.';
}
// Test display of SESSION array.
echo '<br/><br/>Session is: <pre>' . print_r($_SESSION, true) . '</pre>';
// Read cars list from session.
$cars = $_SESSION['cars'];
?>
<!DOCTYPE html>
<html>
<head>
<title>Cars listing page</title>
</head>
<body>
<hr/>
<form action="" method="post">
Name: <input type="text" name="yourname" />
<?php
foreach ($cars as $car) {
echo '<br/>' . $car . '<input type="radio" name="car" value="' . $car . '" />';
}
?>
<button type="submit" id="listSubmit" name="listSubmit" value="Submit">Refresh page!</button>
</form>
</body>
</html>

How to make "MadLibs" form results appear below form fields after submitting?

Thanks in advance for your help. I've searched a lot before posting this but I end up more confused than when I started :)
I'm trying to have one page contain the form fields and after pressing submit, the resulting story with user's form field entries inserted into the story.
It would be great to have the text from the form fields remain so that the user doesn't need to retype everything if they need to change a word or two.
I really appreciate your help. Hopefully this will help many people at once.
<html>
<head>
<title>My MadLib</title>
</head>
<body>
<h1>MadLib</h1>
<?php if (isset($_POST['action']) && $_POST['action'] == "show"): ?>
<p>Hello, I am a <?php echo $_POST['adj'] ?> computer that owns a <?php echo $_POST['noun'] ?>.</p>
<?php else : ?>
<form action="madlib.php" method="post">
<input type="hidden" name="action" value="show">
<p>An adjective: <input type="text" name="adj"></p>
**strong text** <p>A noun: <input type="text" name="noun"></p>
<p><input type="submit" value="Go!"></p>
</form>
<?php endif ?>
</body>
</html>
As you said you don't want to "keep it simple", you may simply add the needed value attribute to each of your <input>s, like this:
<html>
<head>
<title>My MadLib</title>
</head>
<body>
<h1>MadLib</h1>
<?php
if (isset($_POST['action']) && $_POST['action'] == "show") {
?>
<p>Hello, I am a <?php echo #$_POST['adj']; ?> computer that owns a <?php echo #$_POST['noun']; ?>.</p>
<?php
} else {
?>
<form action="madlib.php" method="post">
<input type="hidden" name="action" value="show">
<p>An adjective: <input type="text" name="adj" value="<?php echo #$_POST['adj']"; ?> /></p>
**strong text**
<p>A noun: <input type="text" name="noun" value="<?php echo #$_POST['noun']"; ?> /></p>
<p><input type="submit" value="Go!"></p>
</form>
<?php
}
?>
</body>
</html>
Note the (sometimes unloved) "#" to prevent firing a notice when $_POST['...'] doesn't exist yet. I also added the same in your <p>Hello... line.

Searchform and results on just one page, not two. Solutions?

I've been learning some PHP and MySQL from a book that teaches you how create a simple database driven site. In the book's examples, we're creating a joke database that store author names, joke text, date and id. Progressing I've been taught how to use includes in my main controller, index.php. I'm stuck at a part where they tell me to create a search feature for the joke database, coding as follows:
This is the first part of the controller called 'index.php' all it does is display the search form.
// Display search form
include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
include 'searchform.html.php'; //CHANGE 1
?>
The next part of the controller builds the SQL and then sends it to jokes.html.php, fairly simple... no problems here.
if (isset($_GET['action']) and $_GET['action'] == 'search')
{
include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
//Build SQL statement and output results into an array code here
}
include 'jokes.html.php'; //CHANGE 2
exit();
}
How would you modify the code above if the your searchform.html and jokes.html are just the single html file? I find it inconvenient using 2 files for searching.
My first attempt (I've merged searchform and jokes into "jokesearch.html.php") was to include 'jokesearch.html.php' in CHANGE 1 and again in CHANGE 2, however that didn't help... it just reloaded the page.
2nd attempt was to use header('Location: .')... no luck here too it just reloaded.
EDIT: By popular demand, I'll include the two html files.
searchform.html.php:
<?php include_once $_SERVER['DOCUMENT_ROOT'] .
'/includes/helpers.inc.php'; ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Manage Jokes</title>
<meta http-equiv="content-type"
content="text/html; charset=utf-8"/>
</head>
<body>
<h1>Manage Jokes</h1>
<p>Add new joke</p>
<form action="" method="get">
<p>View jokes satisfying the following criteria:</p>
<div>
<label for="author">By author:</label>
<select name="author" id="author">
<option value="">Any author</option>
<?php foreach ($authors as $author): ?>
<option value="<?php htmlout($author['id']); ?>"><?php
htmlout($author['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="category">By category:</label>
<select name="category" id="category">
<option value="">Any category</option>
<?php foreach ($categories as $category): ?>
<option value="<?php htmlout($category['id']); ?>"><?php
htmlout($category['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="text">Containing text:</label>
<input type="text" name="text" id="text"/>
</div>
<div>
<input type="hidden" name="action" value="search"/>
<input type="submit" value="Search"/>
</div>
</form>
<p>Return to JMS home</p>
</body>
</html>
jokes.html.php
<?php include_once $_SERVER['DOCUMENT_ROOT'] .
'/includes/helpers.inc.php'; ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Manage Jokes: Search Results</title>
<meta http-equiv="content-type"
content="text/html; charset=utf-8"/>
</head>
<body>
<h1>Search Results</h1>
<?php if (isset($jokes)): ?>
<table>
<tr><th>Joke Text</th><th>Options</th></tr>
<?php foreach ($jokes as $joke): ?>
<tr valign="top">
<td><?php htmlout($joke['text']); ?></td>
<td>
<form action="?" method="post">
<div>
<input type="hidden" name="id" value="<?php
htmlout($joke['id']); ?>"/>
<input type="submit" name="action" value="Edit"/>
<input type="submit" name="action" value="Delete"/>
</div>
</form>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<p>New search</p>
<p>Return to JMS home</p>
</body>
</html>
From a MVC perspective your initial setup is the right way to go.
Your controller collects and processes data and sends it to views (your .html.php files).
It is good practice to separate defferent elements into different views. So a search box or search results go in a different view than the jokes.
Putting both logical different elements in one view file makes maintenance harder.
Regards,
Erwin Vrolijk
snow.nl
maybe something like this
if (isset($_GET['action']) and $_GET['action'] == 'search') {
// search result
} else {
// show search form
}

Categories