2011-06-05 70 views
-3

我有這樣的代碼:PHP IP記錄錯誤

<?php 
    echo $_POST['id-input']; 
    $time = time(); 
    $ip=$_SERVER['REMOTE_ADDR']; 
    $userid_c = $_POST['id-input']; 
    $con = mysql_connect("localhost","username","password"); 
    if (!$con) 
    { 
     die('Could not connect: ' . mysql_error()); 
    } 

    mysql_select_db("kritya20_data", $con); 
    $sql = "SELECT * FROM users_online WHERE user_id='$userid_c'"; 
    $query = mysql_query($sql); 
    $rows_only_c = mysql_num_rows($query); 
    if($rows_only_c == 0) 
    { 
     $sql1= "INSERT INTO users_online (user_id , online_since , lastup , lobbieid) 
     VALUES ('$userid_c' , '$time' , '$time' , '1')"; 
     $query1 = mysql_query($sql1); 
    } 
    elseif($rows_only_c==1) 
    { 
     $sql2 = "UPDATE users_online 
     SET lastup='$time' 
     WHERE user_id='$userid_c' "; 
     $query2 = mysql_query($sql2); 
    } 
    $sql3 = "SELECT * FROM iptable WHERE user_id='$userid_c'"; 
    $query3 = mysql_query($sql3); 
    $row_ip = mysql_num_rows($query3); 
    if($row_ip==0) 
    { 
      $sql4 = "INSERT INTO iptable (user_id , ip , added) 
      VALUES ('$userid_c' , '$ip' , '$time')"; 
      $query4= mysql_query($sql4); 
    } 
    elseif($row_ip>0) 
    { 
     $mt=0; 
     $mf=0; 
     $sql4 = "SELECT * FROM iptable WHERE user_id='$userid_c'"; 
     $query4 = mysql_query($sql4); 
     while($row=$query4) 
     { 
      if($ip==$row[2]) 
      { 
       $mt++; 
      } 
      else 
      { 
       $mf++; 
      } 
     } 
     if($mf!=0) 
     { 
      $sql5 = "INSERT INTO iptable (user_id , ip , added) 
      VALUES ('$userid_c' , '$ip' , '$time')"; 
      $query5= mysql_query($sql5); 
     } 
    } 
?> 

哪裏都被我的問題呢? :O ,因爲它只是第一次添加,然後每當ip改變它不會。

+0

......哦哇。我沒有想到這= = – kritya 2011-06-05 08:48:15

+0

我不認爲代碼是可怕的(雖然它有[SQL注入漏洞](http://php.net/manual/en/security.database.sql-injection.php)需要修復),但是您確實需要先進行一些調試,嘗試找出問題所在,並添加更詳細的信息。我們無法爲您執行這些步驟 – 2011-06-05 09:25:31

+1

'canuwritetehcodezplz' – Petah 2011-06-05 09:43:26

回答

1

我修改了下面的代碼以改進佈局,描述性變量名稱,添加了調試,提出了簡化代碼並修正錯誤的邏輯改進方法。

請仔細閱讀並嘗試在未來的代碼中使用其中的一些代碼,它將極大地幫助您調試,或者只是編寫人們可以理解的代碼。我不是想聽起來像一個居高臨下的屁股,我們都開始在某個地方,而我仍然犯下愚蠢的錯誤!

如果有什麼我已經做了,你不明白(代碼或爲什麼我這樣做)請問。

<?php 
    $debug_on = true; 

    #Variable section 
    $time = time(); 
    $ip=$_SERVER['REMOTE_ADDR']; 
    $userid_c = $_POST['id-input']; 

    if($debug_on) { 
     echo "<p>time: '$time'</p>"; 
     echo "<p>ip: '$ip'</p>"; 
     echo "<p>userid_c: '$userid_c'</p>"; 
    } 

    #Connect to database 
    $con = mysql_connect("localhost","username","password"); 
    if (!$con) { 
     die('Could not connect: ' . mysql_error()); 
    } 
    mysql_select_db("kritya20_data", $con) or die('Could not select database'); 

    #Insert or update users_online 
    $user_exits_sql = "SELECT * FROM users_online WHERE user_id='$userid_c'"; 
    $user_exits_query = mysql_query($user_exits_sql); 
    $user_exists = mysql_num_rows($user_exits_query); 
    if($user_exists == 0) { 
     $insert_user_sql = "INSERT INTO users_online (user_id , online_since , lastup , lobbieid) VALUES ('$userid_c' , '$time' , '$time' , '1')"; 
     if($debug_on) { 
      echo "<p>No record found in `users_online` - Inserting new record</p>"; 
      echo "<p>$insert_user_sql</p>"; 
     } 
     mysql_query($insert_user_sql); 
    } 
    else { # no need for 'elseif($rows_only_c==1)' as this is the only other option 
     $update_user_sql = "UPDATE users_online 
          SET lastup='$time' 
          WHERE user_id='$userid_c' "; 
     if($debug_on) { 
      echo "<p>Record found in `users_online` - Updating existing record</p>"; 
      echo "<p>$update_user_sql</p>"; 
     } 
     mysql_query($update_user_sql); 
    } 

    #Insert or update iptable 
    $user_ip_exists_sql = "SELECT * FROM iptable WHERE user_id='$userid_c'"; 
    $user_ip_exists_query = mysql_query($user_ip_exists_sql); 
    $user_ip_exists = mysql_num_rows($user_ip_exists_query); 
    if($user_ip_exists==0) { 
     $user_ip_insert_sql = "INSERT INTO iptable (user_id , ip , added) 
           VALUES ('$userid_c' , '$ip' , '$time')"; 
     if($debug_on) { 
      echo "<p>No record found in `iptable` - Inserting new record</p>"; 
      echo "<p>$user_ip_insert_sql</p>"; 
     } 
     mysql_query($user_ip_insert_sql); 
    } 
    else { # 'elseif($row_ip>0)' 
     $mt = 0; 
     $mf = 0; 
     $iptable_sql = "SELECT * FROM iptable WHERE user_id='$userid_c'"; 
     $iptable_query = mysql_query($iptable_sql); 
     #The next line is your bug, 
     #should read while($row = $iptable_query->mysql_fetch_array()) 
     while($row = $iptable_query) { 
      if($ip==$row[2]) { 
       $mt++; 
      } 
      else { 
       $mf++; 
      } 
     } 
     # For bonus points you could use $iptable_query->mysql_fetch_row(), then $row->ip rather than $row[2]. 
     # This makes it obvious what variable you are trying to access. 
     if($mf != 0) { 
      $iptable_insert_sql = "INSERT INTO iptable (user_id , ip , added) 
            VALUES ('$userid_c' , '$ip' , '$time')"; 
      if($debug_on) { 
       echo "<p>No record found in `iptable` for user with this ip address - Inserting new record</p>"; 
       echo "<p>$iptable_insert_sql</p>"; 
      } 
      mysql_query($iptable_insert_sql); 
     } 

     # This whole section seems to be: 
     # If user doesnt exist, add them, 
     # If user does exist, but not for this ip, add them 
     # If this is right this could be made much simpler by changing $user_ip_exists_sql to be where user_id='$userid_c' and ip='$ip' 
     # then you could remove all the $mt, $mf stuff 
    } 
?> 
+0

盡力閱讀所有這些長代碼,但它仍然容易受到sql注入的影響。假設$ user_id是一個整數,您可以添加'(int)$ _ POST ['id-input'];'以確保沒有其他東西可以輸入 – Ibu 2011-06-05 09:43:33

+0

好點,pear允許處理注入的參數化語句,mysqli和在php5中的pdo,看看http://en.wikibooks.org/wiki/PHP_Programming/SQL_Injection – mattumotu 2011-06-05 09:53:42

+0

或看看http://stackoverflow.com/questions/6198104/reference-what-is-a-perfect -code-sample-using-the-mysql-extension/6198584#6198584關於使用mysql_query之類的建議 – mattumotu 2011-06-05 10:07:10

0

可能會對代碼進行一些改進。但是請嘗試將while($row=$query4)更改爲while($row=mysql_fetch_array($query4))

同樣,當您運行$sql3 = "SELECT * FROM iptable WHERE user_id='$userid_c'";兩次時,爲什麼不直接使用第一個查詢的結果集而不是將另一個查詢發送到數據庫。