PHP检查一个ID是否与活动ID相关联

问题描述 投票:0回答:1

我正在用PHP做一个项目,就像一个帮助台(我是编程世界的新手)。每位员工($ zaposlenik)都可以回答一次问题。如果他已经回答了选定的问题,他应该被重定向到mojaTvrtka.php(他工作场所的主页),应该有一个回音说“你已经回答了这个问题”。我不知道为什么它不会工作。 IF的else部分工作正常。

<?php 
include("baza.php");
include("header.php");

$pid=$_POST['id'];
$zaposlenik=$_SESSION['activeUserId'];
$tekst=$_POST["tekstOdgovora"];
$datum=date('Y-m-d H:i:s');

$connect=connectDB();
$query1="SELECT pitanje_id,odgovor.zaposlenik_id AS odgZap
FROM odgovor
LEFT JOIN zaposlenik
ON odgovor.pitanje_id=zaposlenik.korisnik_id
WHERE odgovor.zaposlenik_id='$activeUserId'";

$result1=queryDB($connect,$query1);

if(mysqli_num_rows($result1) == $zaposlenik))
{
        header("Location:mojaTvrtka.php");
        echo "Vec ste odgovorili na ovo pitanje!";
}
else 
{
    $query="INSERT INTO odgovor
    (pitanje_id,zaposlenik_id,tekst,datum_vrijeme_odgovora) VALUES ('$pid','$zaposlenik','$tekst','$datum')";

    $result=queryDB($connect,$query);

header("Location: detaljiPitanja.php?id=$pid");
}

disconnectDB($connect);
?>
php mysql
1个回答
0
投票

一些东西,

网络是无状态的,这意味着从一个请求到另一个事务是分开完成的(稍后会详细介绍)

在你的代码中

if(mysqli_num_rows($result1) == $zaposlenik))
{
    $message = urlencode("Vec ste odgovorili na ovo pitanje!"); //make sure to url encode it, so it's safe for query args
    header("Location:mojaTvrtka.php?flash_message=$message"); //pass message via the url
    exit(); //always exit after header, ABSOLUTELY no output is allowed before header
}

现在因为无状态本质,我们必须使用某种持久存储来传递消息。数据不会跨请求传递。这是你的回声不起作用的部分原因。另一个原因是即使你回复它,页面重定向,所以没有人能看到它。最简单(也是最丑陋)的方法是将该消息作为url的一部分传递。

在标题重定向之后使用exit非常重要。做事之后会导致“奇怪”的事情发生。

然后在页面上,这是指向你可以

 $flash_message = isset($_GET['flash_message']) ? "<div class=\"flash_message\" >{$_GET['flash_message']}</div>" : '';

 echo $flash_message;

未经测试,但它很简单。

另一部分

你有这个:

  if(mysqli_num_rows($result1) == $zaposlenik))

基本上,你在这里说的是activeUserId的值应该与结果的数量匹配。因此,如果我的id是120292,那么我必须确切地说这个条件或返回的这个条件的行是假的。然后触发else,当然有这个$query="INSERT INTO odgovor

实际上你只想知道他们是否有一排。所以

 if(mysqli_num_rows($result1) == 1)//returns exactly 1 rows

或者你可以通过这种方式测试它的真实性

if(mysqli_num_rows($result1)) //returns some number of rows

最后一件事

即使我不能读到这个:

$query1="SELECT pitanje_id,odgovor.zaposlenik_id AS odgZap
     FROM odgovor
     LEFT JOIN zaposlenik
     ON odgovor.pitanje_id=zaposlenik.korisnik_id
     WHERE odgovor.zaposlenik_id='$activeUserId'";

我可以判断您是否需要匹配用户ID和问题ID,您只有一个WHERE条件。所以你可能需要在那里添加一些问题ID。我会假设存在某种形式的关系(我假设是答案表)将其与问题表联系起来。如外键(问题ID)。所以你只需要添加它,并获得有问题的id(看看我在那里做了什么)。

//Obviously this is just PSUDO code, so replace this with your actual field and value...
WHERE odgovor.zaposlenik_id='$activeUserId' AND question_id='$questionId'";

SQL注入

这个东西odgovor.zaposlenik_id='$activeUserId'也值得注意SQL注入,所以请使用预备语句。

注射的例子是这样的:

   $activeUserId = "' OR 1 LIMIT 1 --";

这样做会让你的查询:

   SELECT pitanje_id,odgovor.zaposlenik_id AS odgZap
   FROM odgovor
   LEFT JOIN zaposlenik
   ON odgovor.pitanje_id=zaposlenik.korisnik_id
   WHERE odgovor.zaposlenik_id='' OR 1 LIMIT 1 --'

--是SQL中注释的开始,因此在运行之后没有任何内容。这样做是选择第一行(OR 1始终为true)并返回该行。

在这种情况下,它是非常平凡的,因为它只是像他们回答问题一样,但重点是我能够执行任何我想对你的数据库的SQL命令。假设用户输入发现它进入$activeUserId,即使它不是值得冒风险?

准备好的语句允许你像这样做你的SQL;

    WHERE odgovor.zaposlenik_id=? AND question_id=?

当你准备它时,数据库会解析SQL,说没关系。然后在DB知道不使它们成为SQL时添加并执行这些值,从而使这些攻击成为不可能(如果正确完成)。

我发现一个例子有助于说明这有多糟糕。这就是说我不打算写一篇关于如何正确准备查询的教程,因为网上有很多内容。

干杯!

© www.soinside.com 2019 - 2024. All rights reserved.