0

我使用 PHP 和 MySQL 创建了一个运动联盟网站,其中包含动态时间表和排名。该网站的一项基本功能是让学校在赛程中选择已经进行过的比赛并登录报告分数。您可以在下面看到一个分数报告页面的示例:

http://www.parochialathleticleague.org/report_score.html?league=test_league&game_id=5&away_team=St.%20Polycarp&home_team=St.%20Columban

经过几个月的工作,一切似乎都运行良好。然而,今天早上我意识到了一个重要的疏忽,就在新赛季的赛程即将上线之前:

我们的一些学校在每个部门都有多个团队,因为他们有额外的学生。因此,例如,可能有一个 St. Barbara 和一个 St. Barbara #2 参加同一个联赛和/或分区。有时,来自较大学校的四支球队中有多达三支。

这是一个问题,因为我编写的验证代码会检查学校用户名,以确保它们与 MySQL 数据库中的主学校用户帐户匹配,然后才能报告分数。因此,即使他们属于同一所学校,St. Barbara 也无权为他们的 St. Barbara #2 队报告分数!我不想为属于该学校的每个团队创建单独的用户帐户,因此我需要以某种方式修改代码。我希望 St. Barbara 能够为所有不同的团队使用相同的用户名登录,无论最后是否有其他字符(如果有道理的话)。

这是我的脚本中验证用户名(学校)的函数,以确保他们是参与相关游戏的两个团队之一:

// 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);

?>
4

1 回答 1

1

目前,我将假设您正在验证这一点$_POST['away_team']并且$_POST['home_team']是有效且正确的。

如果您只想检查以string$_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
    }
}
于 2013-09-12T19:23:18.233 回答