使用准备好的语句时出现“还不允许访问属性”警告[重复]

Posted

技术标签:

【中文标题】使用准备好的语句时出现“还不允许访问属性”警告[重复]【英文标题】:"Property access is not allowed yet" warning when using prepared statement [duplicate] 【发布时间】:2013-09-20 19:55:09 【问题描述】:

我正在尝试使用AES_ENCRYPT() 对我的密码进行编码来登录系统。但是在尝试实现这些代码时,我收到了来自 xdebug 的一些警告:

...
$key = 'd0gis=SUPER-cute';
$sql = "SELECT * FROM `users2` WHERE username = ? AND pwd = AES_ENCRYPT(?, ?)";
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('sss', $username, $password, $key);
$stmt->execute();
$stmt->store_result();
...

当调试器遇到第 8 行或$stmt->prepare($sql); 时,来自 xdebug 的 6 个相同的警告表会显示:

(!) 警告:main(): 在第 8 行的 D:\xampp\htdocs\learnphp\includes\authenticate_mysqli.inc.php 中还不允许进行属性访问

$stmt 中的错误属性是空的,我没有真正的问题,但我只想知道是什么原因导致出现此警告消息。

谷歌搜索了这条警告信息,但没有找到任何解决方案:

    UPDATE query with prepared statements http://php.net/manual/en/mysqli-stmt.param-count.php

【问题讨论】:

你为什么使用stmt_init()?我以前从未见过这样用过的。通常直接是$db->prepare(...) 我在 php.net 中关注 example 这很奇怪,因为有other documentation 表明您可以直接在您拥有的链接上调用prepare,而且我一直看到它是这样做的。 请在此处查看我的答案:***.com/questions/28870315/…(重复问题,虽然不知道如何标记它) 也许是这个:***.com/questions/25377030/… 【参考方案1】:

您的 mysql 连接可能没有建立。在mysqli::__construct() 之后,您必须检查mysqli::$connect_error,它在某些 PHP 版本中已损坏:

mysqli->connect_error 属性仅在 PHP 版本 5.2.9 和 5.3.0 中才能正常工作。如果需要与早期 PHP 版本兼容,请使用 mysqli_connect_error() 函数。

参见mysqli::__construct()的文档中的连接样板:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

/*
 * This is the "official" OO way to do it,
 * BUT $connect_error was broken until PHP 5.2.9 and 5.3.0.
 */
if ($mysqli->connect_error) 
    die('Connect Error (' . $mysqli->connect_errno . ') '
            . $mysqli->connect_error);


/*
 * Use this instead of $connect_error if you need to ensure
 * compatibility with PHP versions prior to 5.2.9 and 5.3.0.
 */
if (mysqli_connect_error()) 
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());

【讨论】:

【参考方案2】:

编辑:我相信我在下面描述的问题是 OP 描述的问题的原因,但是由于我在答案中描述的问题不会产生完全相同的错误消息,我不再确定这是最佳答案.

另外,我从 PHP 文档评论部分注意到了这一点:

这个参数(可能还有 mysqli_stmt 中的任何其他参数) 将引发错误消息“不允许访问属性” 但是”如果声明没有正确准备,或者没有在 全部。

为防止这种情况,请始终确保“准备”的返回值 在访问这些属性之前声明为真。

原答案: 当您尝试将某些对象(类的实例)评估为字符串时会出现此警告。

您的调试器/IDE 正在尝试评估您的一个变量 ($stmt),可能在观察列表或调用堆栈中,并且它不能作为字符串进行评估。

如果你对变量执行print_r,你会得到同样的错误,因为PHP不能把它变成一个字符串。

在您的情况下,PHP 无法将 $stmt 转换为字符串。

将此代码放在第 7 行,您将在那里看到错误:

print_r($stmt);

有点旁注:我最近从未遇到过这个问题。最近我得到了很多。为什么 php 不跳过不可访问的属性并打印其余的?我相信这与属性的范围或 getter/setter 的使用有关,但我还不太确定。当我弄清楚那部分时,我会更新。

来自官方 PHP 文档: (http://php.net/manual/en/language.oop5.magic.php#object.tostring)

__toString() 方法允许一个类决定它将如何反应 当它被视为字符串时。例如,什么 echo $obj;将要 打印。此方法必须返回一个字符串,否则是致命的 发出 E_RECOVERABLE_ERROR 级别错误...

...值得注意的是,在 PHP 5.2.0 之前的 __toString() 方法 仅在直接与 echo 或 print 结合时调用。 自 PHP 5.2.0 起,它在任何字符串上下文中被调用(例如在 printf() 使用 %s 修饰符)但不在其他类型的上下文中(例如使用 %d 修饰符)。自 PHP 5.2.0 起,在没有 __toString() 的情况下转换对象 字符串的方法会导致 E_RECOVERABLE_ERROR。

【讨论】:

这似乎并非如此。这是 PHP 和调试器的错误;查看我的“重复”标志。 我没有看到您的重复标志。但是,我将确认在某些环境中绝对是这种情况。这个问题的原因,至少在我发现、测试和验证的情况下,与尝试将对象(类的实例)评估为字符串有关。这不是一个错误,因为 PHP 已经清楚地记录了它:php.net/manual/en/language.oop5.magic.php#object.tostring 文档还指出,这种行为从 PHP 5.2 开始发生了变化。我将更新我的答案以包括来自php.net/manual/en/language.oop5.magic.php 的 sn-p 其实我想回溯一点。虽然我相信这些问题是耦合/直接相关的,但我所描述的警告似乎与 OP 并不完全相同。我还在描述 OP 确切问题的 PHP 文档上找到了这条评论:php.net/manual/en/mysqli-stmt.param-count.php#89490【参考方案3】:

在 PhpStorm 中运行测试时,还不允许访问属性。我将项目的 PHP 语言级别 设置为 7.2,CLI 解释器 设置为 7.1。我将解释器更改为 7.4,错误消失了。

【讨论】:

以上是关于使用准备好的语句时出现“还不允许访问属性”警告[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用准备好的语句Java选择[重复]

Android:当我使用 AsyncTask 时出现“调用线程必须是准备好的 Looper 线程”错误

准备好的语句失败(带有错误消息!)

MySQL 错误:准备好的语句协议尚不支持此命令

在准备好的语句中使用 LIKE '%$var%' 的正确方法? [mysqli]

编译过程时出现oracle错误