help with form script please

tradervic

New Member
Messages
5
Reaction score
0
Points
0
Hi,

I have set up a web page where visitors can submit a line to a poem, and need help with the code to make their comments appear on the page below the previous line in the poem.

So far all I did was copy and slightly modify a script from a similar web site, but my knowledge on asp etc. is limited, and I understand I need some sort of redirector? in my files to control the action?
If anyone knows how to fix this, or just give me a java or any kind of workable form script that simply will
let a person enter a line of text , control the number of characters per entry, and post the entry onto the same page under the previous entries by hitting the SEND button, please let me know.

my url is http://ourpoem.x10hosting.com/

Thanks a lot,

George
 

xgreenberetx

New Member
Messages
57
Reaction score
1
Points
0
in your send.asp file you are going to need to assign your post variables .
Code:
$poem = $_POST['poem'];// <------This is how it is done in PHP im not sure about ASP.
Take the variable and insert it into your database. MySQL insert is fairly simple
Code:
//make sure to connect to your databse
mysql_query="INSERT INTO poems (poem) VALUES ($poem)";
then display the results from the database.
Code:
$result = mysql_query("SELECT * FROM poems");
while ($row = mysql_fetch_array($result)) {

echo $row['poem'];
echo "<br><br>";

}

I am not very familiar with ASP, but this works in PHP
 
Last edited:

tradervic

New Member
Messages
5
Reaction score
0
Points
0
Thanks for your help. I'm sorry, I should stress that, I know zip about php, asp, sql... I know how to cut and paste html and java code into a web page, and I make flash websites, but my knowledge on all this other stuff is
about "zero". Wherever I got that code must have used asp but I know nothing about it.

So can you tell me of these commands you mention which do I need to add on my web page, and is there something I need to insert in my directory? I have no database created at this time, nor know how to do that.

Sorry, it would probably be easier if I just had a java script if one would do what I need. But if you care to explain it a bit, I am a fast learner.

Thanks,

George
 

nobackseat

New Member
Messages
4
Reaction score
0
Points
0
Hello there,

OKay, so I'm giving you a quick tutorial on how to do this in PHP.

When you first login to CPanel, there is a section (usually towards the bottom) called Databases. Click "MySQL Databases." Under "Create New Database", enter a database name. Create it and do the same for a user. Then add the user to a database. This is all done on the same MySQL Databases page.

Next, create a send.php and change the action attribute of the form on the homepage.. Then copy & paste this code in
PHP:
<?
$con = mysql_connect("localhost","USER","PASSWORD");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("DATABASE", $con);
?>
Recall back to when you created the user for the database, enter the username (don't forget it includes your account username with an underscore before). Replace the capitalized text with the correct information, don't forget DATABASE towards the bottom.

Next, create a createdb.php page.

Copy & paste the exact same MySQL connection from above at the top of this file with the filled in connection information, and then add this after.

PHP:
<?
# MySQL CONNECTION INFO
$sql = "CREATE TABLE IF NOT EXISTS `poem` (
`ID` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`poem` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM";
mysql_query($sql) or die(mysql_error());
echo "Database table successfully created.";
?>

Now visit createdb.php and if it says "Database table successfully created", then it was a success, if it doesn't say that, then there was an error. Please reply to this topic by posting it below.

Now your database is created.
Edit:
Now on your send.php page, you should have MySQL connection info at the top there. Add this after it

PHP:
<?
if(empty($_POST['message'])) {
echo "You must enter some characters.";
}
else {
$msg = mysql_real_escape_string($_POST['message']);
mysql_query("INSERT INTO `poem`  (`poem`) 
VALUES ('$msg')");
echo "Thank you for your poem line submission.";
echo "<br><br><a href='history.go(-1)'>Go back</a>";
}
?>

I assume under the "Our Poem" image on the homepage, you want the poem listed there, correct?

Well, this is what you do. Change your default/index page to index.php

Be sure to include your MySQL connection information again, and then add this after:

PHP:
<?
$entries = mysql_query("SELECT `poem` FROM `poem` ORDER BY ID DESC");
if(mysql_num_rows($entries) == 0) {
echo "There are no entries yet.";
}
else {
while($poem = mysql_fetch_array($entries)) {
echo "<i>$poem[poem]</i><br>";
}
?>

Hopefully that all works for you. None of this is tested, there is probably a stupid typo somewhere. But if you have any trouble, please reply here. Also, don't forget to delete createdb.php. Good luck!

nobackseat
 
Last edited:

tradervic

New Member
Messages
5
Reaction score
0
Points
0
Hey,

Thank you for all this.

I think I about got it. I got the database set up, send.php file made with e/thing you metnioned, and the createdb.php file,
and amended the index page to index.php and added all the info you mentioned on it.



Now I am getting this:

Parse error: syntax error, unexpected $end in /home/trigger/public_html/index.php on line 90

Did I add too much info?

Here is my index.php page:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta http-equiv="Content-Language" content="en-us" />
<meta http-equiv="Imagetoolbar" content="No" />
<meta name="Description" content="OUR POEM OF INFINITE EXPRESSION" />
<meta name="Keywords" content="OUR POEM OF INFINITE EXPRESSION ">
<meta name="Robots" content="All" />
<title>OUR POEM OF INFINITE EXPRESSION</title>
</head>

<body bgcolor="#ffffff">
<div align="center">
<img src="header.gif" width="711" height="347">
<table width="600" border="0">

<form action="send.php" name="poem" method="post">
<input type="hidden" name="poem" value="43808170">
<input type="hidden" name="next" value="http://ourpoem.x10hosting.com/index.htm">


<?
$con = mysql_connect("localhost","trigger_trigger","jamjam");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}

mysql_select_db("trigger_ourpoem", $con);
?>

<?
if(empty($_POST['message'])) {
echo "You must enter some characters.";
}
else {
$msg = mysql_real_escape_string($_POST['message']);
mysql_query("INSERT INTO `poem` (`poem`)
VALUES ('$msg')");
echo "Thank you for your poem line submission.";
echo "<br><br><a href='history.go(-1)'>Go back</a>";
}
?>

<?
$entries = mysql_query("SELECT `poem` FROM `poem` ORDER BY ID DESC");
if(mysql_num_rows($entries) == 0) {
echo "There are no entries yet.";
}
else {
while($poem = mysql_fetch_array($entries)) {
echo "<i>$poem[poem]</i><br>";
}
?>


<tr>
<td align="center"><img src="formtitle.gif" width="503" height="34"></td>
</tr>
<tr>
<td align="center" height="35"><input name="message" type="text" size="80" maxlength="60"></td>
</tr>
<tr>
<td align="center"><img src="formInstruction.gif" width="397" height="15"></td>
</tr>
<tr>
<td align="center"><input type="image" src="sendButton.gif" width="181" height="54" alt="Send" border="0"></td>
</tr>
<tr>
<td align="center"><img src="footer.gif" width="496" height="95"></td>
</tr>
</form>
<tr>
<td align="center">
<hr>
</td>
</tr>
</table>
</div>





</body>
</html>
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
For readability's sake, pick an indent style and stick with it.

The opening tag should be "<?php". Short tags aren't always enabled.

PHP:
	 $con = mysql_connect("localhost","username","password");
The old mysql driver is outdated. PDO is the way to go. For one thing, it supports prepared statements.

Also, the connection to the MySQL server should be done in a separate script that is included in every script that needs a DB connection. This reduces code repetition (among other benefits, this makes updating the code easier and reduces the possibility that a typo will interfere) and puts sensitive information (DB username and password) in a single location rather than scattered about. Often example scripts do things that shouldn't be done in production code; tradervic, be warned.

PHP:
  die('Could not connect: ' . mysql_error());

Don't use die for error messages when outputting HTML. mysql_error discloses too much information and doesn't provide anything useful for visitors.

PHP:
$msg = mysql_real_escape_string($_POST['message']);
I just wanted to point out how important calling mysql_real_escape_string is with the old mysql driver. Without it, code is vulnerable to SQL injection. Note that prepared statements don't have this vulnerability.

@tradervic: when posting code, use
PHP:
, [HTML] or [CODE] tags as appropriate to format it.

[quote="tradervic, post: 625204"][B][I]Parse error: syntax error, unexpected $end in /home/trigger/public_html/index.php on line 90[/I][/B]
[/QUOTE]
This means there's a missing close bracket somewhere. Indenting your code will help find it.

[PHP]
$entries = mysql_query("SELECT `poem` FROM `poem` ORDER BY ID DESC");
if(mysql_num_rows($entries) == 0) {
	echo "There are no entries yet.";
} else {
	while($poem = mysql_fetch_array($entries)) {
		echo "<i>$poem[poem]</i><br>";
	}
	?>
Here it is. The "else" block isn't closed. Add a "}" between the last "}" and the closing "?>" tag.

Here is my index.php page
Inserting a line into the poem should be handled in a separate script that redirects to the main page. This is known as the Post/Redirect/Get pattern and will prevent refreshing the page from adding a line more than once.

You don't need to keep all the open and close PHP tags from nobackseat's code. If there's only whitespace between a closing and opening PHP tag, remove the tags:
PHP:
mysql_select_db("trigger_ourpoem", $con);

if(empty($_POST['message'])) {

Don't use a table based layout, use CSS.
 
Last edited:

nobackseat

New Member
Messages
4
Reaction score
0
Points
0
Thank you for your criticism misson, I am fully aware of what you have pointed out. I figured somebody would come through and nitpick through the code.

However, I did not have time to go through, and make it as best and efficient as possible. Heck, it wasn't even tested. It just an attempt to help.

None of the "etiquette" you pointed out has hindered the script broken.

I copied most of the examples from other sites, seeing as I was in a rush. So indentation is fine, I can read it. Don't be so quick to jump to conclusions and perfect everything.

The die error was to help me help him if he had troubles (which I assumed had a high probability of occurring.) Of course, mysql_error() in a production environment is never good.

I am used to using a database class, which obviously I was not going to include in here. Therefore I used what was simplest for queries and works quite well.

Feels as if you are pointing this out for my sake. Really...somebody new to PHP really needs all these crazy corrections to perfect the code and confuse them.

Thank you for finding my mistake.

Tradervic, helpful reminder to filterl your database information when posting it, especially your password.

Good luck!
 
Last edited:

tradervic

New Member
Messages
5
Reaction score
0
Points
0
Okay, I fixed that missing "}" and thanks for the head's up on :

"Tradervic, helpful reminder to fill your database information when posting it, especially your password."

That info shows up on my index.php source page anyway, if that is how I was supposed to do it.

You guys are pretty much blowing my mind with all this tech talk. I was hoping to get some code to cut and paste into my web page and voila! Its working, but of course I don't expect you to make my website for me or do a lot of work if I can do it myself. Did I mention I don't know jack squat about all this stuff? Anyway, I hate to see you arguing with each other, so if this is too much hassle I can go somewhere else, although I appreciate the opportunity to learn new things, it really wasn't my goal to spend a lot of time learning a new coding system,
but, yet I do want a simple functional website so, what to do...

It's still not working properly, but before I start another war, hey, let me know if you can help me fix whatever is wrong, but I seriously doubt I can rewrite everything to some new updated style of php or use css, etc. because I don't know where to start, and don't have time to learn all that. That's why I pasted everything so far pretty much as it was, I'm just not a web tech kind of guy.

Thank you very much again for all your help, and any more help? You can see what its doing or not doing better than I can explain it: http://ourpoem.x10hosting.com



George
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
@nobackseat: my comments were for the sake of anyone unaware of the issues at play, including tradervic and future readers. For instance, you obviously know about SQL injection, but tradervic doesn't (in all likelihood). Without such warnings, sample code winds up in production code. The key statement in the post is "often example scripts do things that shouldn't be done in production code"; the rest was basically expanding on that.

As for nitpicking, that's what it takes to be a developer. The devil's in the details, after all.

Did I mention I don't know jack squat about all this stuff?
In that case, you might want to read over the recommendations in the thread "Want to learn to program....", or look over the web development book recommendations on StackOverflow. Otherwise you'll be stuck relying on the help of others, or paying others to do your work.

Anyway, I hate to see you arguing with each other
It's nothing serious. Technical discussions may seem combative, but it's really just a no-nonsense communication style. Arguments can be discussions or fights, and this certainly isn't a fight.

As for drop-in PHP code, here's a rewrite of nobackseat's with my suggestions factored in (not that it doesn't have room for improvement). No concern for site design has been taken into account; you'll have to style and structure the HTML as you see fit. That said, the styling should include something like the following:
Code:
.poem, .poem li {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

#line {
    width: 50%;
}

In the following code, I'm assuming column `poem` has been renamed `line`, which is a closer description of what's stored in the column. This can be done with the following SQL statement or in phpMyAdmin, accessible through cPanel.
Code:
ALTER TABLE `poem` CHANGE COLUMN `poem` `line` VARCHAR(255);
Alternatively, change "line" in any SQL statement to "poem".


We first create a file called "config.php" to hold all configuration data. This file gathers together the stuff that might need to be edited by a site administrator (as opposed to a developer); code outside of this file shouldn't need to be altered, unless you're adding features (such as supporting more than one poem) or fixing bugs. This file should be given permissions mode 600 to protect the sensitive data from prying eyes, which you can do in cPanel or your FTP program.
PHP:
<?php
$cfg = array(
  'db' => array(
    'name' => '...',  // the database name, e.g. trigger_poetry
    'user' => '...', // the DB username
    'password' => '...'
  )
);
?>

"localDB.php" defines the code responsible for creating a DB connection (in this case a function named localDBConnect).
PHP:
<?php
function localDBConnect($dbName=Null) {
    global $cfg;
    if (is_null($dbName)) {
        $dbName = $cfg['db']['name'];
    }
    static $db = array();
    if (empty($db[$dbName])) {
        $db[$dbName] = new PDO("mysql:host=localhost;dbname=$dbName", $cfg['db']['user'], $cfg['db']['password']);
    }
    $db[$dbName]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    return $db[$dbName]; 
}
?>

"poem.php" displays the poem and a form to enter a new line.
PHP:
<?php
function printPoem() {
    try {
        // turn on output buffering so we can discard poem if an exception occurs
        ob_start();
        $db = localDBConnect();
        $lines = $db->query('SELECT line FROM poem ORDER BY ID');
        echo "    <ol class='poem'>\n";
        foreach ($lines as $line) {
            echo "        <li>$line[0]</li>\n";
        }
        echo "    </ol> <hr />\n";
        ob_end_flush();
        printNewPoemLineForm();
    } catch (PDOException $exc) {
        ob_end_clean();
        error_log($exc);
        echo "Looks like we're having internal problems. An error has been logged and we'll look into it.";
        // saffolding: display the exception in the browser
        global $dbgLvl;
        if ($dbgLvl) {
            echo '<pre>', $exc, '</pre>';
        }
    }
}

function printNewPoemLineForm() {
    static $formNotices = array(
        'line' => array('empty' => "New line was blank. Please type something if you wish to add a line."),
        'form' => array()
        );

    ?>
    <script type="text/javascript" src="js/form.js"></script>
    <form action='line.php' method='POST' onsubmit="return validate(this)">
        <?php
        $line='';
        if (isset($_REQUEST['notices'])) {
            $notices = array_intersect_key($_REQUEST['notices'], $formNotices);
            if ($notices) {
                if (! empty($_REQUEST['line'])) {
                    // keep the line, if it exists, so user doesn't need to re-enter it
                    $line = htmlspecialchars($_REQUEST['line']);
                }
                echo "<ul class='notices'>\n";
                foreach ($notices as $field => $msgId) {
                    if (isset($formNotices[$field][$msgId])) {
                        $msg = $formNotices[$field][$msgId];
                    } else {
                        $msg = strip_tags($msgId);
                    }
                    echo '            <li>', $msg, "</li>\n";
                }
                echo "        </ul>\n";
            }
        }
        ?>
        <label for="line">New line:</label>
        <input name="line" id="line" value="<?php echo $line; ?>"/>
        <button name='action' value='add'>Add line</button>
    </form>
    <?php
}
?>
To use poem.php, include it in your index.php (e.g. with"<?php include_once('poem.php'); ?>") and call printPoem(). Error messages can be passed to the page via the 'notices' parameter, though the sample code only supports a limited variety of notices. How notices are handled could use quite a bit of cleanup.

poem.php also references "js/form.js", which can be used for client-side validation. In it, define validate(). It's not strictly necessary, but good for usability's sake (I'll post more on this later).

"line.php" handles requests to add a line to the poem.
PHP:
<?php
include_once('config.php');
include_once('localDB.php');

$_REQUEST['line'] = trim($_REQUEST['line']);
if (empty($_REQUEST['line'])) {
    header('Location: ' . dirname($_SERVER['REQUEST_URI']) . "?notices[line]=empty");
} else {
    try {
        $dbConn = localDBConnect();
        
        $insertLineStmt = $dbConn->prepare('INSERT INTO `poem` (`line`, `ip`) VALUES (:line, :ip)');
        $insertLineStmt->execute(array(':line' => strip_tags($_REQUEST['line'], '<b><i><u><s><em><strong><strike><pre><del><ins><sup><sub>'),
                                       ':ip' => $_SERVER['REMOTE_ADDR']));
        header('Location: ' . dirname($_SERVER['REQUEST_URI']));
    } catch (PDOException $exc) {
        error_log($exc);
        header('Location: '
               . dirname($_SERVER['REQUEST_URI']) 
               . "?notices[form]=" + urlencode("Whoops... I had an internal problem with my database. It's been logged, and we'll look into it."));
    }
}
?>

A major flaw that's yet to be addressed is flood-prevention. Someone could submit many new lines in a short period. To handle this, we could implement a wait period, so people must wait (say) 2 minutes before they can post a new line (wait period can be set in config.php). This could be based on IP addresses or user accounts, which is a little more complex to implement. For the former, people could use proxies to get around flood-detection. With IP checking, we'd also better include a limit on the overall frequency of submissions: keep an exponential running average of the time between submissions; whenever this exceeds some value (set in config.php), submitted lines aren't added. Just be sure to print messages informing users when and why their submissions are throttled. We could also implement only the global throttling and skip per-IP/per-user throttling.
 
Last edited:

tradervic

New Member
Messages
5
Reaction score
0
Points
0
Thanks Misson ,

When I get off work this evening I will work on your suggestions. I did want to set up more control
features as you guessed but just wanted something that worked to get started. I most likely will have to edit some of the entries for spam removal and any seriously offensive language, but pretty much want people to just write whatever they want whether it makes sense or not. You guys are awesome. I already know way more about php and sql than I did, so that's cool too. I just have to make more time for things like that.
That's what I dig about forums though. And this is a good one from what I can see.


Best,

George
 

nobackseat

New Member
Messages
4
Reaction score
0
Points
0
Hello, I didn't take his strong opinion of how things should be done as an argument. I definitely was not fighting.


Missed misson's post, use his solution.
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Note that I update poem.php to remove three XSS vulnerabilities. If you have a copy of poem.php and line.php older than this post, replace it with the new version. For reference, here's the section of poem.php that's been updated (part of printNewPoemLineForm):
PHP:
                if (! empty($_REQUEST['line'])) {
                    // keep the line, if it exists, so user doesn't need to re-enter it
                    $line = htmlspecialchars($_REQUEST['line']);
                }
                echo "<ul class='notices'>\n";
                foreach ($notices as $field => $msgId) {
                    if (isset($formNotices[$field][$msgId])) {
                        $msg = $formNotices[$field][$msgId];
                    } else {
                        $msg = strip_tags($msgId);
Note the calls to htmlspecialchars and strip_tags.

line.php:
PHP:
       $insertLineStmt->execute(array(':line' => strip_tags($_REQUEST['line'], '<b><i><u><s><em><strong><strike><pre><del><ins><sup><sub>'),
 
Last edited:
Top