在数据库中发布信息的更好方法


Better Way to Post Info in DB?

当前,我在HTML端的代码如下所示:

<form action="newstory.php" method="post">
<input type="hidden" name="author" value="<?php echo $loggedInUser->display_username; ?>"
/>
<input type="hidden" name="userid" value="<?php echo $loggedInUser->user_id ?>" />
Story Title: <input type="text" name="story_name" /><br>
Story: <textarea rows="10" cols="30" name="story" /></textarea><br>
<input type="submit" />
</form>

这是PHP方面:

include("dbconnect.php");
mysql_select_db("scratch", $con);
$author     = mysql_real_escape_string($_POST['author']);
$author_id  = mysql_real_escape_string($_POST['userid']);
$story_name = mysql_real_escape_string($_POST['story_name']);
$story      = mysql_real_escape_string($_POST['story']);
$sql= "
INSERT INTO stories (author, author_id, story_name, story)
VALUES ('$author', '$author_id','$story_name', '$story')
";

if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "Story Submitted! Redirecting to Homepage...";
//User is shown this for about 3 seconds
header('Refresh: 3; URL=index.php');
mysql_close($con)

我想摆脱

<input type="hidden" name="author" value="<?php echo $loggedInUser->display_username; ?
>"/>

因为人们可以很容易地编辑它并以任何用户的身份发布,但我不确定有什么好方法。userid也是如此。

感谢您的帮助!

通过表单中的隐藏输入字段发送userid是一个巨大的安全威胁。任何人都可以更改该值,例如Chrome的检查器或FireBug。当有人登录时;您必须在会话中至少存储他们的userid。您还可以在会话中存储更多信息,这样您就不必在每次请求时都查询数据库,例如在页面上的某个位置显示登录用户的用户名。

我现在不知道你是如何处理登录的,也不知道$loggedInUser是如何填充的,但它应该是一个会话变量,例如$_SESSION['user']['id']。这样,你就可以随时知道用户是谁,而不必通过表格发送数据;那真是不可能。

确保每个页面的顶部都有session_start(),理想情况下,您可以使用模板,并且只需将session_start()添加到index.php的顶部。

$sql= "
INSERT INTO stories (author, author_id, story_name, story)
VALUES ('$author', '$author_id','$story_name', '$story')
";

至少应该是

$sql= "
INSERT INTO stories (author, author_id, story_name, story)
VALUES ('". $author ."', '". $author_id ."', '". $story_name ."', '". $story ."')
";

我个人建议:

$q = "
INSERT INTO stories
        SET author_id = ". $_SESSION['user']['id'] ." # This is an integer (I assume) so don't use apostrophe's
          , story_name = '". mysql_real_escape_string($_POST['story_name']) ."'
          , story = '". mysql_real_escape_string($_POST['story']) ."'
";

从表中删除字段author。只需使用author_id进行表引用,否则您将存储重复的数据,当有人更改作者名称时,故事中的作者名称就会过时/不正确/过时。

检查是否设置了用户,如果用户对象有效,则只显示该表单。在使用mysql保存之前,请使用用户对象中的值,而不是从POST数据中读取值。

<?php if ( isset($_POST['story_name']) ) {
// story posted.. check if user is set
if ( isset($loggedInUser->user_id) ) {
    // save into database using $loggedInUser->user_id and $loggedInUser->author_name
}
?>
<?php
// just show the form if the user object is set
if ( isset($loggedInUser->user_id) ){
?>
<form> <!-- and show the form over here --> </form>
<?php } ?>

哦,你的mysql_real_escape_string()很好!另一个最佳实践是使用sprintf():将变量添加到查询中

$author     = mysql_real_escape_string($loggedInUser->author_name);
$author_id  = mysql_real_escape_string($loggedInUser->user_id);
$story_name = mysql_real_escape_string($_POST['story_name']);
$story      = mysql_real_escape_string($_POST['story']);
$sql= sprintf("
INSERT INTO stories (author, author_id, story_name, story)
VALUES ('%s', '%s', '%s', '%s')
", $author, $author_id, $story_name, $story); // %s accepts the value to be a string. %d accepts a decimal for example.