Need help with form processing basics. Don't understand some aspects?

I need some help with form processing basics. What do you reckon is a complete guide on the basics of form processing in PHP?

Where I’m at:
I understand <form action="preview.php" method="post">at the beginning will take the data to the preview.php page and I can access the data through the name attributes of each input by putting in something like $_POST[‘title’] for an input with a name attribute of title.

What I want to know is how you can use the name attribute in the if(isset) statement to pass sql queries. Like to make entries into the database and extract content.

One thing you need to always keep in mind with dealing with any data submitted by the user is to always assume it is tainted and you should sanitized every bit of data; eg:

  • Is it of the type that you expect?
  • Is it within the range of size/length that you expect?
  • Have all fields that you expect to be filled in been filled in?

Once the data has been sanitized, when using it with a query you should be using prepared statements to prevent SQL injection attack

Thanks. I always use prepared statements to prevent sql injection. I want to know how you can use the name attributes in the if(isset) statements. Like for instance this is what I’ve tried on the add new post page:

<?php 

include 'inc/header.php';
include 'inc/db.php';

?>

    <p> Add new post </p>
    
    <form action="preview.php" method="post">
    
    <ul>
    <li>
    <label for="title"> Title </label>
    <input type="text" name="title"/>
    </li>
    
    <li>
    <label for="body"> Body </label>
    <textarea name="body" id="body"></textarea>
    </li>
    
    </ul>
    <input type="submit" value="Submit"/>
    </form>

<?php
include 'inc/sidebar.php';
include 'inc/footer.php';
?>

Then we have the preview page as:

<?php 

include 'inc/header.php';

if (isset ($_POST['submit']) and $_POST['action'] == 'submit') {
	include 'inc/db.php';
	
	try {
		$query = "INSERT into posts (title, body) values (':title', ':body')";
		$result = $pdo->prepare($query);
		$result->bindValue(':title', $_POST['title']);
		$result->bindValue(':body', $_POST['body']);
		$result->execute();
		echo 'Post Submitted';
		}
		
	catch (PDOException $e) {
		echo 'Failed attempt loser'.$e->getMessage();
		}
}
?>

    <h1> Preview </h1>
    <p> <?php echo $_POST['title']; ?> </p>
    
    <p> <?php echo $_POST['body']; ?> </p>
    
    <input type="submit" name="submit" value="submit"/>

<?php
include 'inc/sidebar.php';
include 'inc/footer.php';
?>

OK, are you saying that doesn’t work for you? As I see it, you’re checking that the submit was pressed (though I think you also need to have name=“submit” on your first HTML code as well) and if it was, and another condition, then you run the query.

So I’m not sure I understand the question. isset(var) checks that a variable exists - but note that it doesn’t check that there’s something in it. So checking isset($_POST[‘body’]) after your form submission will return true whether or not the user filled that field in, because the post sends all form vars, empty or not.

Nope. No entries are being sent into the db. I’m not even getting any error. I’m aware of how I can put the ‘required’ message but for now I am filling in all the data to ensure I post to the db.

I have changed the name to submit. Still not working. I don’t know what’s wrong. I am confused about how to use if (isset) when you have more than one name attribute in a form. Right now I’m using the name attribute from the submit button, but I have seen people use the name attribute from the input fields as well to validate form data and to post it into the db.

I don’t know where the second condition in your if statement comes from, where you say

and $_POST['action'] == 'submit'

That implies there should be a field called ‘action’ in your form, and that it should be set to the string value ‘submit’. You don’t have such a field unless your code is just a subset. And, can you write “and” like that, I always thought it had to be written as && though there may be synonyms I am unfamiliar with.

Failing anything else, stick loads of echo() statements through your preview.php code and see how far it gets through. Or enable error reporting, but I forget how you do that.

http://php.net/manual/en/function.error-reporting.php

Also try doing a var_dump of $_POST at the top of the script to see what has been sent. If I remember correctly some browsers (= IE) don’t send the submit button if you press enter instead of clicking the submit button?

Yes, I have changed it to $_POST[‘submit’] == ‘submit’ to suit the info in the submit button on the preview page. Still not working.

I have changed it to <input type="submit" name="submit" value="submit"/>

Even changed and to &&. No go.

I have used print_r ($_POST) and checked the source code. I am getting this so I guess that’s working. There is a problem with the if (isset) statement. I have added an else statement for the if(isset) statement giving me an error message and I now get the error message.

if (isset ($_POST[‘submit’]) && $_POST[‘submit’] == ‘submit’) {
include ‘inc/db.php’;

try {
	$query = "INSERT into posts (title, body) values (':title', ':body')";
	$result = $pdo->prepare($query);
	$result->bindValue(':title', $_POST['title']);
	$result->bindValue(':body', $_POST['body']);
	$result->execute();
	echo 'Well done';
	}
	
catch (PDOException $e) {
	echo 'Failed attempt loser'.$e->getMessage();
	}

}

else {
echo ’ error the isset statement is incorrect’ ;
}

I can see the error at the bottom being displayed.

Try removing the space after isset ?

I know you said you’d changed it, but in the first html for your form you set the value as “Submit”, not “submit”. If I use the original code, add the name parameter to the input and change the value to have the proper case, it works OK for me. With “and”, too.

Do not quote name placeholders.

(':title', ':body')

should be

(:title, :body)

Thanks a lot for your (goes for everybody) help. It was a really stupid mistake and I wasted over 24 hours on this. It wasn’t working because I didn’t have the preview content and submit button inside html form tags.

**<form action="" method="post">**

<p> <?php echo $_GET['title']; ?> </p>

<p> <?php echo $_GET['body']; ?> </p>

<input type="submit" name="submit" value="submit"/>

**</form>**

Seems to be working now. It was only when I tried changing from post to get that I realised there was no method specified on the page.

I have another query now that I’m deleting posts. I can see the id is auto increment. So if I have posts numbered 1,2,3,4,5 and so on, if I delete 3, I’m left with 1,2,4,5 which is causing a bit of problem on my main article page which looks something like this:

<?php 

include 'inc/db.php';

if (isset($_GET['id'])) {

$query = 'SELECT * from posts where id = :id';
$stmt = $pdo->prepare($query);
$stmt -> bindValue (':id', $_GET['id']);
}

$post = $stmt->fetch(PDO::FETCH_OBJ);

?>

<h1> <?php echo $post->title; ?> </h1>
<p> <?php echo $post->body; ?> </p>

<p><a href="single.php?id=<?php echo $_GET['id']+1 ;?>"> Next </a></p>
<p><a href="single.php?id=<?php echo $_GET['id']-1 ;?>"> previous </a></p>

I’ve got the next and previous links for the articles with the +1. Now when I am on article 2 and I hit next, if I have deleted article 3, I get an error. How do you reckon I deal with this issue?

Here is what the page that takes you here looks like:

<div id="main-section">

<div class="wrap">
<?php foreach ($results as $result): ?>
<h1><a href="single.php?id=<?php echo $result['id'];?>"> <?php echo $result['title'] ?> </a></h1>
<p> <?php echo $result['body']; ?> </p>
<?php endforeach; ?>
</div><!-- end wrap-->

</div><!-- end main section-->

You’ve either got to deal with it when you output the link, or when you follow the link. So for the first option, you’d have to figure out the id of the next/previous article and use those values in your links. Maybe a separate query to find the next/previous article IDs would do it.

For the second option, you’d need to take the id in from your page and deal with what happens when it doesn’t exist. So you’d also need to know what “direction” to go in, so maybe your link should pass in the current article id and either “+” or “-” to indicate the direction you’re moving in.

Either way you have to add some validation - what will you do when you’re displaying post 1? Right now you’re giving a link to post zero, and the same when displaying the post with the highest id.

I must admit on the original issue I wasn’t even looking at the second-tier handling, I was thinking the problem was between the original html and the preview.php, so I didn’t notice the missing form tags.

That’s why I told you to check the content of $_POST and see what exactly the form was sending :wink:

I’m not sure of what you mean. I’m thinking since I get a message that says Notice: Trying to get property of non-object in xyz everytime the id is missing, do you mean I should go by something like this:

if (object not found) {
// skip to next id
}

else {
display current id
}

Yeah I’m just not too familiar with var_dumping elements. I did it, but got nothing. I think that’s what you wanted me to check anyway. I usually go with the print_r command. Can you share some insights on my last query about the id going missing? I’d love to know what you think about it.

For the pagination you could use the current item id and the direction to construct the query that will get the next or previous item. For example the next item:

SELECT 
    ....
FROM tablename
WHERE id > $currentid
ORDER BY id
LIMIT 1

Thanks brother. I will be trying that one out. It didn’t make sense to me at first but does now somewhat. What do you reckon I can do for pagination on the main page where I could retrieve say 10 posts on the first page, then have the following system for retrieving further data page wise:

previous 1 2 3 4 5 6 7 next