我创建了一个运动联盟网站,其中包含使用PHP和MySQL的动态时间表和排名。该网站的基本功能之一是学校按照已经播放的时间表选择游戏并登录以报告分数。您可以在下面看到评分报告页面的示例:
经过几个月的工作,一切似乎都正常。然而,今天早上我意识到了一个重要的疏忽,就在新赛季的时间表即将开始之前:
我们的一些学校在每个部门都有多个团队,因为他们有额外的学生。因此,例如,可能有一个St. Barbara和一个St. Barbara#2参加同一个联赛和/或分区。有时,来自较大学校的四支队伍中有多达三支。
这是一个问题,因为我编写的验证代码会检查学校用户名,以确保它们与MySQL数据库中的主要学校用户帐户匹配,然后才能报告分数。因此,圣芭芭拉没有被授权为他们的圣芭芭拉#2队报告得分,即使他们属于同一所学校!我不想为属于该学校的每个团队创建单独的用户帐户,因此我需要以某种方式修改代码。我希望圣芭芭拉能够使用相同的用户名登录所有不同的团队,无论最后是否有其他字符(如果有意义的话)。
以下是我的脚本中的函数,用于验证用户名(学校)以确保他们是参与游戏的两个团队之一:
// Validate the school:
if (empty($_POST['school'])) {
echo "You forgot to enter your school.<br>";
$validate = 'false';
} elseif ($_POST['school'] != $_POST['away_team'] && $_POST['school'] != $_POST['home_team']) {
echo "Your school does not match one of the two on file for this game.<br>";
$validate = 'false';
} else {
$school = mysqli_real_escape_string($db, trim($_POST['school']));
$validate = 'true';
}
接下来,这是稍后验证用户名和密码是否与数据库中的一条记录匹配的函数:
// If all conditions are met, process the form:
if ($validate != 'false') {
$q1 = "SELECT school_id FROM user_schools WHERE (school_name='$school' AND pass='$pass')";
$r1 = mysqli_query($db, $q1);
$num = mysqli_num_rows($r1);
if ($num == 1) {
// ***a whole bunch of other stuff that I'm omitting because it's not relevant
}
}
是否可以添加一个“附录”,可以说,对于那些拥有多个团队的学校来说会有例外的代码?有点像:
elseif ($_POST['school'] == $_POST['away_team'] **MINUS ADDITIONAL INTEGERS AT THE END** || $_POST['school'] == $_POST['home_team'] **MINUS ADDITIONAL INTEGERS AT THE END**) {
$validate = 'true';
}
对不起整个长篇大论。只是想确保我解释得恰到好处!有什么想法吗?非常感谢您的反馈。
编辑 - 以下是感兴趣的人的整个脚本:
<?php
// Connect to the database:
require ('../mysqli_connect.php');
// Validate the school:
if (empty($_POST['school'])) {
echo "You forgot to enter your school.<br>";
$validate = 'false';
} elseif ($_POST['school'] != $_POST['away_team'] && $_POST['school'] != $_POST['home_team']) {
echo "Your school does not match one of the two on file for this game.<br>";
$validate = 'false';
} else {
$school = mysqli_real_escape_string($db, trim($_POST['school']));
$validate = 'true';
}
// Validate the password:
if (empty($_POST['pass'])) {
echo "You forgot to enter your password.<br>";
$validate = 'false';
} else {
$pass = mysqli_real_escape_string($db, trim($_POST['pass']));
$validate = 'true';
}
// Validate the away score:
if (!isset($_POST['away_score'])) {
echo "You forgot to enter the away score.<br>";
$validate = 'false';
} elseif (!is_numeric($_POST['away_score'])) {
echo "You entered an invalid score for the away team.<br>";
$validate = 'false';
} else {
$away_score_confirm = mysqli_real_escape_string($db, trim($_POST['away_score']));
$validate = 'true';
}
// Validate the home score:
if (!isset($_POST['away_score'])) {
echo "You forgot to enter the home score.<br>";
$validate = 'false';
} elseif (!is_numeric($_POST['$home_score']) && $_POST['$home_score'] < 0 ) {
echo "You entered an invalid score for the home team.<br>";
$validate = 'false';
} else {
$home_score_confirm = mysqli_real_escape_string($db, trim($_POST['home_score']));
$validate = 'true';
}
// Determine the winner and loser, and set variables:
if ($_POST['away_score'] > $_POST['home_score']) {
$winner = mysqli_real_escape_string($db, trim($_POST['away_team']));
$winner_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
$loser = mysqli_real_escape_string($db, trim($_POST['home_team']));
$loser_score = mysqli_real_escape_string($db, trim($_POST['home_score']));
$tie = 'no';
} else if ($_POST['away_score'] < $_POST['home_score']) {
$winner = mysqli_real_escape_string($db, trim($_POST['home_team']));
$winner_score = mysqli_real_escape_string($db, trim($_POST['home_score']));
$loser = mysqli_real_escape_string($db, trim($_POST['away_team']));
$loser_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
$tie = 'no';
} else if ($_POST['away_score'] == $_POST['home_score']) {
$tie = 'yes';
$tie1 = mysqli_real_escape_string($db, trim($_POST['away_team']));
$tie2 = mysqli_real_escape_string($db, trim($_POST['home_team']));
$tie_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
}
// Declare remaining hidden inputs as variables:
$league = mysqli_real_escape_string($db, $_POST['league']);
$game_id = mysqli_real_escape_string($db, $_POST['game_id']);
// If all conditions are met, process the form:
if ($validate != 'false') {
$q1 = "SELECT school_id FROM user_schools WHERE (school_name='$school' AND pass='$pass')";
$r1 = mysqli_query($db, $q1);
$num = mysqli_num_rows($r1);
if ($num == 1) {
// Get the game ID:
$q2 = "SELECT $game_id FROM $league";
$r2 = mysqli_query($db, $q2);
// Get the row for the game ID:
$row = mysqli_fetch_array($r2, MYSQLI_NUM);
// Perform an UPDATE query to modify the game scores:
$q3 = "UPDATE $league SET home_score='$home_score_confirm', away_score='$away_score_confirm' WHERE game_id=$row[0]";
$r3 = mysqli_query($db, $q3);
if (mysqli_affected_rows($db) == 1) {
$confirm = 'true';
} else {
$confirm = 'false';
}
// Update the winning team in the standings:
$q4 = "SELECT school_id FROM test_league_standings WHERE school_name='$winner'";
$r4 = mysqli_query($db, $q4);
// Get the row for the school:
$row2 = mysqli_fetch_array($r4, MYSQLI_NUM);
$q5 = "UPDATE test_league_standings SET games=games + 1, win=win + 1, pts_for=pts_for + '$winner_score', pts_against=pts_against + '$loser_score' WHERE school_id=$row2[0]";
$r5 = mysqli_query($db, $q5);
$q6 = "UPDATE test_league_standings SET pct=(win / games), avg_for=(pts_for / games), avg_against=(pts_against / games) WHERE school_id=$row2[0]";
$r6 = mysqli_query($db, $q6);
if (mysqli_affected_rows($db) == 1) {
$confirm = 'true';
} else {
$confirm = 'false';
}
// Update the losing team in the standings:
$q7 = "SELECT school_id FROM test_league_standings WHERE school_name='$loser'";
$r7 = mysqli_query($db, $q7);
// Get the row for the school:
$row3 = mysqli_fetch_array($r7, MYSQLI_NUM);
$q8 = "UPDATE test_league_standings SET games=games + 1, loss=loss+1, pts_for=pts_for + '$loser_score', pts_against=pts_against + '$winner_score' WHERE school_id=$row3[0]";
$r8 = mysqli_query($db, $q8);
$q9 = "UPDATE test_league_standings SET pct=(win / games), avg_for=(pts_for / games), avg_against=(pts_against / games) WHERE school_id=$row3[0]";
$r9 = mysqli_query($db, $q9);
if (mysqli_affected_rows($db) == 1) {
$confirm = 'true';
} else {
$confirm = 'false';
}
if ($confirm != 'false') {
header("Location: schedules_test.html?league=" . $league);
} else {
echo "The scores could not be reported due to a system error. Apologies for the inconvenience. If this problem continues, please contact us directly.";
}
} else {
echo "Your school and password combination do not match those on file for this game.";
}
}
mysqli_close($db);
?>
答案 0 :(得分:1)
目前我将假设您确认$_POST['away_team']
和$_POST['home_team']
有效且正确。
如果您只是想检查$_POST['away_team']
是否以字符串$_POST['school']
开头,您可以使用strpos
函数:
elseif (strpos($_POST['away_team'], $_POST['school']) === 0 || strpos($_POST['home_team'], $_POST['school'])) {
echo "Your school does not match one of the two on file for this game.<br>";
$validate = 'false';
}
我想同意tadman关于SQL注入的评论。即使您不愿意重写应用程序以利用将数据注入查询的卓越方法,但绝对应该在运行查询时转义数据。 不在其他任何地方逃避它。如果你这样做,最终你将忘记逃避它,它将不会像它应该那样明显。例如:
if ($validate != 'false') {
$q1 = sprintf(
"SELECT school_id FROM user_schools WHERE (school_name='%s' AND pass='%s')",
mysqli_real_escape_string($_POST['school']),
mysqli_real_escape_string($_POST['pass'])
);
$r1 = mysqli_query($db, $q1);
$num = mysqli_num_rows($r1);
if ($num == 1) {
// ***a whole bunch of other stuff that I'm omitting because it's not relevant
}
}