为什么有人访问我的网站时,我的数据库未更新? [英] Why is my database not being updated when someone visits my website?

查看:150
本文介绍了为什么有人访问我的网站时,我的数据库未更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某些原因,当用户来到我的网站玩多人游戏时,会发送对php文件的调用,但数据库从不添加新玩家或更新其信息。



php文件通过javascript文件中的以下代码行调用:

  xmlhttp.open('GET' xml_http_request.php?mod0 =+ truckHeading +& mod1 =+ newhtr [1] +& mod2 =+ absRoll +& lla0 =+ lla [0] +& lla1 = [1] +& lla2 =+ lla [2] +& pid =+ rCC +& rangeCheck =+ rangeCheck +& ranger =+ ranger +& ; message =+ message +& unLoader = false,true); 

这里是php代码:

 <?php 
require(db1.php); // for use live public database
//require(\"db.php); //用于使用本地数据库

$ inserter = 0;

//分配pid(如果还没有)
$ pid = $ _ GET ['pid'];
if($ pid =='false'){
$ inserter = 1;
$ query =SELECT id FROM positioner;
$ result = mysql_query($ query);
$ num_rows = mysql_num_rows($ result);
$ i = 1;
while($ row = @ mysql_fetch_assoc($ result)){
if($ i!= $ row ['id']){$ pid = $ i; break; } // take first available id
$ i ++;
}
if($ pid =='false'){$ pid = $ num_rows + 1; } //如果id列表中没有空洞,取下一个更高
mysql_free_result($ result);
}

$ unLoader = $ _ GET ['unLoader'];

if($ unLoader =='true'){
$ ddb = dbq(DELETE FROM positioner WHERE id ='。$ pid。LIMIT 1;);
} else {

$ dbMi = $ _ GET ['dbMi'];

$ mod0 = $ _ GET ['mod0'];
$ mod1 = $ _ GET ['mod1'];
$ mod2 = $ _ GET ['mod2'];

$ lla0 = $ _ GET ['lla0'];
$ lla1 = $ _ GET ['lla1'];
$ lla2 = $ _ GET ['lla2'];

$ rangeCheck = $ _ GET ['rangeCheck'];
$ i.e = addslashes($ _ GET ['ie']);
if($ i.e ==''){$ i.e ='x'; }
$ message = addslashes($ _ GET ['message']);

$ rangeCheck ='true';
//只检查每x个刻度(50,〜3秒)的范围?
//,$ rangeCheck是真的第一次
if($ rangeCheck =='true'){
$ ranger = array();
// get lat lon of all for determine who are in range
$ query =SELECT id,lla0,lla1 FROM positioner WHERE id!='。$ pid。
$ result = mysql_query($ query);

// if distance< 10000,put id in ranger array
while($ row = @ mysql_fetch_assoc($ result)){
//立即离开范围检查
// $ di = dister($ row [' lla0'],$ row ['lla1'],$ lla0,$ lla1);
// if($ di< 10000){
$ ranger [] = $ row ['id'];
//}
}
mysql_free_result($ result);
if(count($ ranger)== 0){
$ rangerS ='';
} else {
$ rangerS = implode(,,$ ranger);
}

// rangeChecks之间从js
获取ranger数组} else {
$ rangerS = $ _ GET ['ranger']; // $ rangerS:string(用于插入)
$ ranger = explode(,,$ rangerS); // $ ranger:array(for looping)
}

//第一次插入新行
if($ inserter == 1){
$ idb = dbq(INSERT positioner(id,mod0,mod1,mod2,lla0,lla1,lla2,ranger,ie,message,model)
VALUES('。$ pid。','。$ mod0。 ','。$ mod1。','。$ mod2。','。$ lla0。','$ lla1。 $ rangerS。','。$ ie。','。$ message。','。$ dbMi。

} else {
//使用当前模型数据和范围检查结果更新数据库
$ udb = dbq(UPDATE positioner SET mod0 ='$ mod0。 '',mod1 ='。$ mod1。',mod2 ='。$ mod2。',lla0 ='。$ lla0。',lla1 ='。$ lla1。 $ lla2。',ranger ='。$ rangerS。',也就是='。$ ie。',message ='$ message。',model ='$ dbMi。 'WHERE id ='。$ pid。'LIMIT 1;);
}

header(Content-type:text / xml);
echo'< markers>';
echo'< marker ranger ='。$ rangerS。'pid ='。$ pid。'/>';

//循环遍历ranger数组中id的次数
foreach($ ranger为$ rang){
$ query =SELECT mod0,mod1, mod2,lla0,lla1,lla2,即消息,模型FROM定位器WHERE id ='。$ rang。';
$ result = mysql_query($ query);
while($ row = @ mysql_fetch_assoc($ result)){

echo'< marker mod0 ='。$ row ['mod0']。'/>
echo'< marker mod1 ='。$ row ['mod1']。'/>';
echo'< marker mod2 ='。$ row ['mod2']。'/>';
echo'< marker lla0 ='。$ row ['lla0']。'/>';
echo'< marker lla1 ='。$ row ['lla1']。'/>';
echo'< marker lla2 ='。$ row ['lla2']。'/>';
echo'< marker ie ='。rawurlencode(stripslashes($ row ['ie']))。'/>
echo'< marker message ='。rawurlencode(stripslashes($ row ['message']))。'/>';
echo'< marker dbMi ='。$ row ['model']。'/>';
}
}

echo'< / markers>';

} // end if unLoader

//计算距离的函数,用于范围检查
/ *对于少数游客不需要
function dister($ lat1,$ lon1,$ lat2,$ lon2){
$ R = 6378100;
$ lat1 * = pi()/ 180;
$ lon1 * = pi()/ 180;
$ lat2 * = pi()/ 180;
$ lon2 * = pi()/ 180;
$ dLat = $ lat2- $ lat1;
$ dLon = $ lon2- $ lon1;
$ a = sin($ dLat / 2)* sin($ dLat / 2)
+ cos($ lat1)* cos($ lat2)*
sin * sin($ dLon / 2);
$ c = 2 * atan2(sqrt($ a),sqrt(1- $ a));
$ di = $ R * $ c;
$ di = round($ di,6);
return $ di;
}
* /
?>


解决方案

有些笔记。




  • 分配pid(如果尚未)块是悲剧性的。您正在抓取表的全部内容,然后逐行检查以查看是否找到了正确的内容。在选择下一个 pid 时,代码盲目假设行数将与id列匹配。

  • 您的 DELETE FROM(自动递增)列可以使用自动递增列, 查询包含 SQL注入漏洞 。如果 pid 不是字符串'false',它将永远不会被验证。有人可以销毁整个 positioner 表。你如何保护它呢?好...

  • 您正在使用 addslashes 。这不是代码 ,它是一个代码 stench addslashes 从来没有,在任何时候在整个计算历史是正确的使用*。我想你正在寻找一个真实的数据库转义机制。由于您使用的是mysql界面,因此您需要 mysql_real_escape_string

  • lla1 lla2 ?这些是最好的和最描述性的名称,你可以想出的列?我将假设这些是经纬度对。

  • 再次,您在 SELECT 中有SQL注入。 li>
  • INSERT 中,您可能盲目地信任 $ rangerS 。 SQL注入ahoy!

  • 并且在 UPDATE

  • rant简短地关于字符串'true'和字符串'false',但是那些来自坏的Javascript。考虑让它们作为 1 0 提交。此外,请考虑使用像jQuery这样的现代Javascript库,而不是滚动自己的Ajax位。
  • 这里的核心问题其实是 pid 检查。我打赌你总是得到一个新的或不正确的 pid 从表中返回,因为 id 不太可能完全匹配行计数。然后你用new pid 做一个盲无错误检查 INSERT ,但如果你的索引设计正确,这将失败并出现重复的键错误。因此,没有更新。 但这只是猜测。除了这里的漏洞,我不确定我是否完全了解发生了什么,我不会发现任何明显不正确的。



    这里还有另一个可能的问题。我将假设 pid 意味着从上下文中的玩家ID 。您的代码是盲目地相信请求来自 pid 的玩家,而是任何人只需在此提出请求,任何有效的 pid ,并为人们做移动。



    *好吧,也许有人发现 addslashes 有用一次两次...


    For some reason when a user comes to my site to play multiplayer the call to the php file is sent, but the database never adds a new player or updates their information.

    php file is called with the following line of code from a javascript file:

    xmlhttp.open('GET',"xml_http_request.php?mod0="+truckHeading+"&mod1="+newhtr[1]+"&mod2="+absRoll+"&lla0="+lla[0]+"&lla1="+lla[1]+"&lla2="+lla[2]+"&pid="+rCC+"&rangeCheck="+rangeCheck+"&ranger="+ranger+"&namely="+namely+"&message="+message+"&unLoader=false", true);
    

    Here's the php code:

    <?php
    require("db1.php"); //for using live public database
    //require("db.php"); //for using local database
    
    $inserter=0;
    
    //assign pid if have not already
    $pid=$_GET['pid'];
    if($pid=='false'){
      $inserter=1;
      $query="SELECT id FROM positioner";
      $result=mysql_query($query);
      $num_rows=mysql_num_rows($result);
      $i=1;
      while($row=@mysql_fetch_assoc($result)){
        if($i!=$row['id']){ $pid=$i;break; } //take first available id
        $i++;
      }
      if($pid=='false'){ $pid=$num_rows+1; }  //if no hole in id list, take next one higher
      mysql_free_result($result);
    }
    
    $unLoader=$_GET['unLoader'];
    
    if($unLoader=='true'){
      $ddb=dbq("DELETE FROM positioner WHERE id = '".$pid."' LIMIT 1;");
    }else{
    
      $dbMi=$_GET['dbMi'];
    
      $mod0=$_GET['mod0'];
      $mod1=$_GET['mod1'];
      $mod2=$_GET['mod2'];
    
      $lla0=$_GET['lla0'];
      $lla1=$_GET['lla1'];
      $lla2=$_GET['lla2'];
    
      $rangeCheck=$_GET['rangeCheck'];
      $namely=addslashes($_GET['namely']);
      if($namely==''){ $namely='x'; }
      $message=addslashes($_GET['message']);
    
      $rangeCheck='true';
      //only check range every x number of ticks (50, ~3 seconds)?
      // , $rangeCheck is true first time
      if($rangeCheck=='true'){
        $ranger=array();
        //get lat lon of all for determining who is in range
        $query="SELECT id, lla0, lla1 FROM positioner WHERE id != '".$pid."' ";
        $result=mysql_query($query);
    
        //if distance < 10000, put id in ranger array
        while($row=@mysql_fetch_assoc($result)){
          //leave rangeCheck off for now
          //$di=dister($row['lla0'],$row['lla1'],$lla0,$lla1);
          //if($di<10000){
          $ranger[]=$row['id'];
        //}
        }
        mysql_free_result($result);
        if(count($ranger)==0){
          $rangerS=''; 
        }else{
          $rangerS=implode(",", $ranger);
        }
    
        //between rangeChecks get ranger array from js
      }else{
        $rangerS=$_GET['ranger'];  // $rangerS: string(for inserting) 
        $ranger=explode(",",$rangerS); // $ranger: array(for looping)
      }
    
      //insert new row first time
      if($inserter==1){
        $idb=dbq("INSERT positioner (id,mod0,mod1,mod2,lla0,lla1,lla2,ranger,namely,message,model) 
          VALUES ('".$pid."', '".$mod0."', '".$mod1."', '".$mod2."', '".$lla0."', '".$lla1."', '".$lla2."', '".$rangerS."', '".$namely."', '".$message."', '".$dbMi."');");
    
      }else{
        //update the database with current model data and result of range check
        $udb=dbq("UPDATE positioner SET mod0 = '".$mod0."', mod1 = '".$mod1."', mod2 = '".$mod2."', lla0 = '".$lla0."', lla1 = '".$lla1."', lla2 = '".$lla2."', ranger = '".$rangerS."', namely = '".$namely."', message = '".$message."', model = '".$dbMi."' WHERE id = '".$pid."' LIMIT 1;");
      }
    
      header("Content-type: text/xml");
      echo '<markers>';
      echo '<marker ranger="'.$rangerS.'" pid="'.$pid.'" />';
    
      //loop through a number of times equal to number of id's in ranger array
      foreach($ranger as $rang){
        $query="SELECT mod0, mod1, mod2, lla0, lla1, lla2, namely, message, model FROM positioner WHERE id = '".$rang."' ";
        $result=mysql_query($query);
        while ($row=@mysql_fetch_assoc($result)){
    
          echo '<marker mod0="'.$row['mod0'].'" />';       
          echo '<marker mod1="'.$row['mod1'].'" />'; 
          echo '<marker mod2="'.$row['mod2'].'" />'; 
          echo '<marker lla0="'.$row['lla0'].'" />';     
          echo '<marker lla1="'.$row['lla1'].'" />'; 
          echo '<marker lla2="'.$row['lla2'].'" />'; 
          echo '<marker namely="'.rawurlencode(stripslashes($row['namely'])).'" />';
          echo '<marker message="'.rawurlencode(stripslashes($row['message'])).'" />';
          echo '<marker dbMi="'.$row['model'].'" />';  
        }
      }
    
      echo '</markers>';
    
    } //end if unLoader
    
    //function for calculating distance between latlon pairs, for range check
    /* not necessary for only a few visitors
    function dister($lat1,$lon1,$lat2,$lon2){
      $R=6378100;
      $lat1*=pi()/180; 
      $lon1*=pi()/180;
      $lat2*=pi()/180; 
      $lon2*=pi()/180;
      $dLat=$lat2-$lat1;
      $dLon=$lon2-$lon1;
      $a=sin($dLat/2)*sin($dLat/2)
        +cos($lat1)*cos($lat2)*
        sin($dLon/2)*sin($dLon/2);
      $c=2*atan2(sqrt($a),sqrt(1-$a));
      $di=$R*$c;
      $di=round($di,6); 
      return $di;        
    }
    */
    ?>
    

    解决方案

    Some notes.

    • The "assign pid if have not already" block is tragic. You're grabbing the entire contents of the table, and then row-by-row checking to see if you found the right one. The code blindly assumes that the row count is going to match the id column when picking what the next pid should be. The proper thing to do (for MySQL) would be using an auto-increment column so that you don't need to worry about that mess.
    • Your DELETE FROM query contains an SQL Injection vulnerability. If pid is not the string 'false', it will never be validated. Someone can destroy the entire positioner table. How do you protect against it? Well...
    • You're using addslashes. This isn't a code smell, it's a code stench. addslashes has never, ever at any time in the entire history of computing been the correct thing to use*. I think you're looking for a real database escaping mechanism. Because you're using the atrocious "mysql" interface, you want mysql_real_escape_string.
    • lla1 and lla2? Those are the best and most descriptive names for columns you could come up with? I'm going to assume those are latitude/longitude pairs.
    • Once again, you have SQL injection in that SELECT.
    • And in that INSERT, you are possibly blindly trusting $rangerS. SQL Injection ahoy!
    • And in the UPDATE.
    • I'd also like to rant briefly about string 'true' and string 'false', but those are coming from bad Javascript. Consider having them submitted as 1 and 0 instead. Also, please, please consider using a modern Javascript library like jQuery instead of rolling your own Ajax bits. It will save you time and stress.

    I think the core problem here is actually the initial pid check. I'm going to bet that you're always getting a new or incorrect pid back from the table, because the id is unlikely to perfectly match the row count. Then you're doing a blind no-error-check INSERT with the "new" pid, but if your indexes are designed properly, this will fail with a duplicate key error. Therefore, no updates. But this is just speculation. Other than the vulnerabilities here, I'm not sure I completely understand what's happening, and I'm not spotting anything obviously incorrect.

    There's another possible problem here. I'm going to assume that pid means player ID from the context. Your code is blindly trusting that the request is coming from the player that owns that pid, but anyone can just make a request here with any valid pid and make moves for people as a result. I'm not sure you intended that.

    * Okay, maybe someone found addslashes useful once or twice...

    这篇关于为什么有人访问我的网站时,我的数据库未更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆