简体   繁体   English

PHP + MySQL脚本不起作用

[英]PHP+MySQL script not working

I made this script which is giving me a lot of troubles. 我编写了这个脚本,这给我带来了很多麻烦。 I'm not so good at MySQL and maybe I'm trying to do stuff too advanced for my knowledge of SQL, but I would really really really like to make this work. 我不太擅长MySQL,也许我正在尝试做一些对我的SQL知识来说太高级的事情,但是我真的很想完成这项工作。

My php script is: 我的PHP脚本是:

<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";

$db_handle = mysql_connect($server, $user_name, $password);
$db_found = mysql_select_db($database, $db_handle);


$SQL="SELECT * FROM accounts WHERE username='$getusername' and password='$getpassword'";
$result=mysql_query($SQL);


$count=mysql_num_rows($result);


if($count==1){
    $blockstring=$getpos.'/'.$getblock.'|';
    $SQL="SELECT LOCATE('$getpos', blocks) FROM worlds WHERE name='$getworldname'";
    $result=mysql_query($SQL);
    $count=mysql_num_rows($result);
    echo $count;
    //if there's already that block
    if ($result!=0){
        $posUnknown='|'.$getpos.'/';
        $posKnown='|'.$getpos.'/'.$getblock;
        $SQL="UPDATE worlds SET blocks=replace(blocks,concat('$posUnknown',substring_index(substring_index(blocks, '$posUnknown', 2), '|', 1),'|'),'$posKnown') WHERE name='$getworldname'";
        $result=mysql_query($SQL);
    }else{
        $SQL="UPDATE worlds SET blocks=CONCAT(blocks,'$blockstring') WHERE name='$getworldname'";
        $result=mysql_query($SQL);
    }
    print 'OK';
}else{
    print 'NO';
}
?>

I'm sure I made some mistake, also big ones into the queries, but sadly I can't figure out what I'm doing wrong. 我确定我在查询中犯了一些错误,也犯了很大的错误,但可悲的是我无法弄清楚自己在做什么错。

An example of the content of blocks could be: 块内容的示例可能是:

x10y20z30/0|x999y1231z30/1|x3330y4444z0/99999|etc x10y20z30 / 0 | x999y1231z30 / 1 | x3330y4444z0 / 99999 |等

What this script does, well, what I wanted it to do is: 该脚本的作用是,我想要执行的操作是:

  • Check username and password, and that works luckily, 检查用户名和密码,很幸运,
  • check if the given block already exists in "blocks" 检查给定的块是否已经存在于“块”中
  • if it does exist replace the value (the one after the /) of the already existing block with the new one, 如果确实存在,则用新的块替换现有块的值(/后面的一个),
  • if it doesn't exist just add it to "blocks". 如果不存在,则将其添加到“块”中。

But it doesn't work and I know why. 但这不起作用,我知道为什么。 I know it's because of the SQL, but I can't figure out how to make it work. 我知道这是因为SQL,但是我不知道如何使它工作。

You have some serious issues with your code's security, as pointed out in a comment. 正如注释中指出的那样,您的代码安全性存在一些严重问题。 I have done what I can without really changing what your code is doing: 我已经做了我能做的,而没有真正改变您的代码正在做的事情:

<?PHP
    $getusername=$_GET['user'];
    $getpassword=$_GET['pass'];
    $getworldname=$_GET['worldname'];
    $getblock=$_GET['block'];
    $getpos=$_GET['pos'];
    $user_name = "asdasdasd";
    $password = "asdasd";
    $database = "asdasd";
    $server = "localhost";

You should be using mysqli, not mysql: 您应该使用mysqli,而不是mysql:

    $db = new mysqli($server, $user_name, $password, $database);

All input needs to be escaped before it is used in a query with real_escape_string: 在对带有real_escape_string的查询中使用所有输入之前,需要对所有输入进行转义:

    $SQL="SELECT * FROM accounts WHERE username='" . $db->real_escape_string($getusername) . "' and password='" . $db->real_escape_string($getpassword) . "'";
    $result=$db->query($SQL);

    $count=$result->num_rows;

    if($count==1) {
        $blockstring=$getpos.'/'.$getblock.'|';
        $SQL="SELECT LOCATE('" . $db->real_escape_string($getpos) . "', blocks) FROM worlds WHERE name='" . $db->real_escape_string($getworldname) . "'";
        $result=$db->query($SQL);

        $count=$result->num_rows;
        echo $count;

        //if there's already that block
        if ($count!=0) {
            $posUnknown='|'.$getpos.'/';
            $posKnown='|'.$getpos.'/'.$getblock;

This is probably where you're having trouble, because it looks like you're storing all of this information in a single row: 这可能是您遇到麻烦的地方,因为您似乎将所有这些信息存储在一行中:

            $SQL="UPDATE worlds SET blocks=replace(blocks,concat('" . $db->real_escape_string($posUnknown) ."',substring_index(substring_index(blocks, '" . $db->real_escape_string($posUnknown). "', 2), '|', 1),'|'),'" . $db->real_escape_string($posKnown) . "') WHERE name='" . $db->real_escape_string($getworldname). "'";
            $result=$db->query($SQL);
        } else {
            $SQL="UPDATE worlds SET blocks=CONCAT(blocks,'" . $db->real_escape_string($blockstring) ."') WHERE name='" . $db->real_escape_string($getworldname) . "'";
            $result=$db->query($SQL);
        }
        print 'OK';
    } else {
        print 'NO';
    }
?>

Since all of your block information is being shoved together in a single column, your database is not normalized at all and appears to be like this: 由于所有块信息都被汇总到一列中,因此数据库根本没有被规范化,看起来像这样:

Worlds
name    blocks

Your database should probably be structured a lot more like this: 您的数据库的结构应该更像这样:

Worlds
id | name
---------------
 1 | demoworld

Blocks
id | WorldID | x     | y    | z  | data
-----------------------------------------
 1 |       1 |    10 |   20 | 30 |     0
 2 |       1 |   999 | 1231 | 30 |     1
 3 |       1 | 33330 | 4444 |  0 | 99999

You can recreate the data layout you provided when you query the data, and when someone tries to add something like x20y30z40/12345, you can parse that to get the x, y, z, and data portions. 您可以重新创建查询数据时提供的数据布局,并且当有人尝试添加x20y30z40 / 12345之类的内容时,可以对其进行解析以获取x,y,z和数据部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM