2013-06-19 36 views
-1

下面我有在DB我需要幫助做一個MySQL查詢

表這三張表

`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是插入表單的信息轉換成桌面遊戲碼

<?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. in case'accountname':,在INSERT之前,必須檢查通知的帳戶在表ACCOUNTS中是否有效。
  2. 案「charactername」:,前插入它必須檢查是否知情角色名是表球員

我不能這樣做,有人可以幫助我有效嗎?

+4

*必須:*本'mysql_ *'功能將被已廢棄在PHP 5.5](http://php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated )。不建議編寫新代碼,因爲它將來會被刪除。相反,無論是[MySQLi](http://php.net/manual/en/book.mysqli.php)還是[PDO](http://php.net/manual/en/book.pdo.php)和[是一個更好的PHP開發人員](http://jason.pureconcepts.net/2012/08/better-php-developer/)。 –

+0

爲什麼需要這些檢查? – Strawberry

+0

我建議用['mysqli :: real_escape_string'](http://www.php.net/manual/en/mysqli.real-escape-string.php)替換你的'anti_injection'函數。 – jterry

回答

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擴展。

+0

你有教程嗎? – user2498466

+0

http://php.net/manual/en/book.pdo.php和http:// stackoverflow。COM /問題/ 15990857 /參考常問的疑問的約-PDO –

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注入函數有一些漏洞。您必須過濾全部您的輸入導致用戶可以在瀏覽器中更改輸入數據任何控制。考慮檢查一下。

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