试图获取非对象的属性“角色”

时间:2019-04-30 10:16:55

标签: php mysql mysqli

我有2个级别的身份验证用户。

在第一层中,我只有用户名和密码,在第二层中,我具有用户的访问角色。

问题是,

有一个用户的数据存在于第一个表中但不存在于第二个表中的机会,即访问表尝试登录。

我没有第二个表中第一个表的所有用户的副本。

有什么办法可以检查用户是否在查询的第二个表中?

现在我的查询是

$roleQuery= " SELECT role FROM accesscredentials WHERE jid=".$_POST['username'];       
$roleArray=mysqli_query($con,$roleQuery);
$roleVal = mysqli_fetch_object($roleArray);
$role=$roleVal->role;

当用户尝试登录时,由于他们的名字不在第二个表中,所以我收到一条错误消息: “试图获取非对象的属性'角色'

您能帮我吗? 谢谢 :) 欢呼

4 个答案:

答案 0 :(得分:2)

mysqli_fetch_object()的文档说:

  

返回一个具有字符串属性的对象,该对象对应于获取的行;如果结果集中没有更多的行,则返回NULL。

因此您可以检查以下内容:

if (is_null($roleVal)) {
    $role = "not set.";
}
else {
    $role = $roleVal->role;
}

请使用prepared statements保护查询免受SQL攻击。

Qirel建议的替代方案如下所示:

if ($roleArray->num_rows > 0) {
    $roleVal = mysqli_fetch_object($roleArray);
    $role=$roleVal->role;
}
else {
    $role = "not set.";
}

任何人都可以做。但是,要使用准备好的语句来完成此操作,您必须:

// sanatize input before anything else
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
// perform prepared query
$roleQuery = "SELECT role FROM accesscredentials WHERE jid=?";       
$roleStatement = $con->prepare($roleQuery);
$roleStatement->bind_param("s", $username);
$roleStatement->bind_result($role);
$roleStatement->execute();
// fill role with something when not found
if (!$roleStatement->fetch()) {
    $role = "not set.";
}
// now you can use $role

答案 1 :(得分:2)

您有两个问题和一个漏洞。可以使用准备好的语句来修复此漏洞,但这也可以解决您的第一个问题-必须在查询中使用字符串值$_POST['username']

最后,您必须先检查是否有要获取的行,然后才能真正使用这些值。

$roleQuery= " SELECT role FROM accesscredentials WHERE jid=?";       
$stmt = $con->prepare($roleQuery);
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_result($role);
$stmt->execute();
if ($stmt->fetch()) {
    echo "Role was ".$role;
}

答案 2 :(得分:2)

在某些情况下,我是try/catch块的忠实拥护者,在我看来,这就像一个这样的用例场景。通过使用prepared statement,您(实际上)消除了SQL注入攻击的可能性,并消除了不引用sql中的字符串(该值大概是数字)的可能错误。

使用try / catch意味着您可以提出自己有用的调试消息来帮助调试逻辑,而无需诉诸使用mysqli_error()等,这在许多情况下显示得太多了。

希望这对您有用

try{
    $sql='select `role` from `accesscredentials` where `jid`=?';
    $stmt=$con->prepare( $sql );

    if( $stmt ){
        $username=filter_input( INPUT_POST, 'username', FILTER_SANITIZE_STRING );
        if( $username ){

            $stmt->bind_param('s',$username );
            $status=$stmt->execute();

            if( $status && $stmt->num_rows==1 ){

                $stmt->store_result();
                $stmt->bind_result( $role );
                $stmt->fetch();
                $stmt->free_result();
                $stmt->close();

                /* $role is available as a variable */
                echo $role;

            } else {
                throw new Exception( $stmt->num_rows==0 ? 'Query failed or there are no records' : 'Error' );
            }
        } else {
            throw new Exception('No valid username');
        }
    } else {
        throw new Exception('Failed to prepare "SELECT" query');
    }
}catch( Exception $e ){
    exit( $e->getMessage() );
}

答案 3 :(得分:0)

尝试一下

$roleQuery= "SELECT role FROM accesscredentials WHERE jid=".$_POST['username'];

if ($result=mysqli_query($con,$roleQuery))
  {
  while ($obj=mysqli_fetch_object($result))
    {
       echo $obj->role;
    }
  // Free result set
  mysqli_free_result($result);
}