-1

我在 DB 下面有这三个表

`accounts` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(32) NOT NULL DEFAULT '',
      `password` varchar(255) NOT NULL,
      `salt` varchar(40) NOT NULL DEFAULT '',
      `premdays` int(11) NOT NULL DEFAULT '0',
      `lastday` int(10) unsigned NOT NULL DEFAULT '0',
      `email` varchar(255) NOT NULL DEFAULT '',
      `key` varchar(32) NOT NULL DEFAULT '0',
      `blocked` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'internal usage',
      `warnings` int(11) NOT NULL DEFAULT '0',
      `group_id` int(11) NOT NULL DEFAULT '1',
      `page_access` int(11) DEFAULT NULL,
      `page_lastday` int(11) DEFAULT NULL,
      `email_new` varchar(255) DEFAULT NULL,
      `email_new_time` int(15) DEFAULT NULL,
      `rlname` varchar(255) DEFAULT NULL,
      `location` varchar(255) DEFAULT NULL,
      `created` int(16) DEFAULT NULL,
      `email_code` varchar(255) DEFAULT NULL,
      `next_email` int(11) DEFAULT NULL,
      `premium_points` int(11) DEFAULT NULL,
      `nickname` char(48) DEFAULT NULL,
      `avatar` char(48) DEFAULT NULL,
      `about_me` text,
      `vip_time` int(15) NOT NULL,
      `event_points` int(11) NOT NULL DEFAULT '0',
      PRIMARY KEY (`id`),
      UNIQUE KEY `name` (`name`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

`players` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `group_id` int(11) NOT NULL DEFAULT '1',
  `account_id` int(11) NOT NULL DEFAULT '0',
  `online` tinyint(1) NOT NULL DEFAULT '0',
  `deleted` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`,`deleted`),
  KEY `account_id` (`account_id`),
  KEY `group_id` (`group_id`),
  KEY `online` (`online`),
  KEY `deleted` (`deleted`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

`gamecodes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gamecode` varchar(50) NOT NULL,
  `accountname` varchar(50) NOT NULL,
  `premium_points` int(11) NOT NULL,
  `alreadyused` varchar(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;

这是我的 .PHP 将 FORM 的信息插入到 TABLE GAME CODES 中

<?php
        function anti_injection($sql)
        {
            $sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$sql);
            $sql = trim($sql);
            $sql = strip_tags($sql);
            $sql = addslashes($sql);
            return $sql;
        }

        $accountorname = anti_injection($_POST['accountorname']);
        $gamecode = $_POST['gamecode'];
        $category = $_POST['category'];
        $premiumpoints = anti_injection($_POST['premiumpoints']);

        switch ($category) {
            case 'accountname':
                $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) VALUES ('$gamecode','$accountorname',$premiumpoints,'N')";
                break;
            case 'charactername':
                $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) 
                        SELECT '$gamecode',accounts.name,$premiumpoints,'N' 
                        FROM accounts 
                        JOIN players
                        ON accounts.id = players.account_id 
                        WHERE players.name = '$accountorname'";
                break;
        }

        $result = mysql_query($insertquery);
    ?>

问题是:

  1. 如果 'accountname': ,在INSERT 之前它必须检查通知帐户在表 ACCOUNTS 中是否有效。
  2. 如果 'charactername': ,在INSERT 之前它必须检查通知的角色名称在表 PLAYERS 中是否有效

我做不到,有人可以帮助我吗?

4

3 回答 3

1
$selectquery = "SELECT * from accounts where accountname='$accountname'";
$selectresult = mysql_query($selectquery);
if (mysql_num_rows($selectresult)) {
    // account exists, now you can do the INSERT
}

注意

mysql 扩展自 PHP 5.5.0 起已弃用,将来将被删除。相反,应该使用 MySQLi 或 PDO_MySQL 扩展。

于 2013-06-19T12:13:37.077 回答
1

您可以为此目的使用一个函数,如下所示:

function Validate($table, $name)
{
    if ($res = mysql_query("SELECT Count(*) as isvalid FROM $table WHERE name = '$name'"))
    {
        $isvalid = 0;
        @extract(mysql_fetch_assoc($res));
        if ($isvalid == 0) return false;
        else return true;
    }
}

所以你这样称呼:

case 'accountname':
    if (Validate("accounts", $accountorname)) { 
        // Do things
    }
case 'charactername':
    if (Validate("players", $accountorname)) { 
        // Do things
    }

我没有测试它,我承认这不是最好的方法,但它应该做你想要的。

顺便说一句,您的 SQL 注入函数有一些漏洞。您必须过滤所有输入,因为用户可以更改浏览器中任何控件的输入数据。考虑审查。

于 2013-06-19T12:19:42.667 回答
0

在执行此操作之前,您始终可以执行另一个查询来检查。有了这个,你仍然会冒着有人在查询之间删除帐户的风险。如果这对您来说是一个问题,您应该查看transactions

    $shouldinsert = false;
    switch ($category) {
        case 'accountname':
            $result = mysql_query("SELECT count(*) as account_count FROM accounts WHERE name = '$accountorname'");
            $shouldinsert = mysql_num_rows($result) > 0;
            $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) VALUES ('$gamecode','$accountorname',$premiumpoints,'N')";
            break;
        case 'charactername':
            //I'm not quite sure how to check if a charactername is 'valid' but this should get you started
            $result = mysql_query("SELECT count(*) as account_count FROM players WHERE name = '$charactername'");
            $shouldinsert = mysql_num_rows($result) > 0;
            $insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) 
                    SELECT '$gamecode',accounts.name,$premiumpoints,'N' 
                    FROM accounts 
                    JOIN players
                    ON accounts.id = players.account_id 
                    WHERE players.name = '$accountorname'";
            break;
    }
    if($shouldinsert) {
        mysql_query($insertquery);
    }
于 2013-06-19T12:19:52.247 回答