【问题标题】:PDO object not in scope of a functionPDO 对象不在函数范围内
【发布时间】:2013-04-26 20:41:44
【问题描述】:

好的,我看到了一些与我类似的问题,但他们的示例都使用 PHP 类......我的没有。也许这就是问题所在?我不应该需要课程,因为我的网站目前非常简单。

无论如何,我正在尝试使用 PDO 连接到 MySQL 数据库。我在一个名为config.php 的文件中很好地连接到数据库,并将这个文件包含在index.phprequire_once() 中。

我可以从另一个名为process.php 的文件中成功查询数据库,但问题出在该文件中的函数内;看来我的 DBO 对象超出了该函数的范围。

以下是相关代码sn-ps:

index.php

require_once('./lib/config.php');

config.php

// tested and connects fine    
$pdo = new PDO('mysql:host=' . $hostname . ';dbname=' . $dbname, $username, $password, array(
    PDO::ATTR_PERSISTENT => true
));

process.php

<?php
...
// can call $pdo fine in this file outside of functions
...

function authenticate($u, $p) {
    // can't call $pdo in here, error says $pdo is non-object
    $que = $pdo->query('select user_id, user_pass from users where user_name = \'' . $u . '\' limit 1');
    ...
}

?>

顺便说一句,我使用 PDO 是因为我在使用 mysqli 时遇到了类似的问题,并且正试图摆脱 mysql,这显然已被贬低和劝阻。

编辑:我应该首先根据我在这个问题上得到的回复数量进行澄清:我确实尝试将 $pdo 作为参数传递给函数,但没有运气或改变错误信息。

解决方案:好的,显然问题是我还需要在我的 process.php 文件中添加require_once('config.php')。不知道为什么(当 index.php 首先运行时,它不会已经包含在其中吗?)。然后我能够成功地将$pdo 作为参数传递给我的函数,瞧。

【问题讨论】:

  • 在您的身份验证功能中,$pdo 超出范围。将其作为参数传入,或将其声明为全局。
  • 如果你真的必须,在你的函数中将它声明为global $pdo;。不过,你最好通过它或将authenticate 放在一个类中。
  • 使用正确的类和对象,然后使用依赖注入。

标签: php pdo mysqli


【解决方案1】:

那是pretty basic PHP stuff。函数内部的变量是局部变量,除非您使用 global 关键字来加载它们。我想你想要这个:

function authenticate(PDO $pdo, $u, $p) {
    $que = $pdo->query('select user_id, user_pass from users where user_name = \'' . $u . '\' limit 1');
    //...
}

编辑:如果 PHP 声称 $pdo 不是一个对象,它就不是一个对象,所以它如何传递给函数并不重要。在调用 authenticate() 之前检查变量:

var_dump($pdo);

没有相关代码就无法说明原因。 (假设new PDO 成功。)

【讨论】:

  • 是的。我会呼应这里将 PDO 对象传递给函数的方法(这称为依赖注入)。它比在函数中使用global 干净得多。
  • 是的,请看我的编辑,抱歉。应该首先澄清的是,我首先尝试将$pdo 作为参数传递,但没有成功。
  • 感谢 Alvaro,请参阅我的解决方案编辑。当本地(再次)需要 config.php 文件时,参数传递就像你说的那样工作。不知道为什么我必须要求 config.php 两次,但无论如何。
  • 但是,process.php 是否包含在 index.php 中?
  • @ÁlvaroG.Vicario:不,process.php 是通过 jQuery AJAX 调用的。但是index.php 在任何东西之前运行,所以我认为那里的require_once() 足以满足网站的其余部分。
【解决方案2】:

因为$pdo 已在函数authenticate 之外声明,它在其中不可用。您需要传入 $pdo

function authenticate($u, $p, $pdo) {
    $que = $pdo->query('...');
}

或在函数内将其声明为全局,以便能够访问它

function authenticate($u, $p) {
    global $pdo;
    $que = $pdo->query('...');
}

【讨论】:

  • 对不起,请看我的编辑。我最初确实尝试将$pdo 作为参数传递,但没有运气。
  • 你不能只做function authenticate($u, $p, $pdo) 来传递它,你在调用函数时也必须这样做。 $result = authenticate($u, $p, $pdo)
  • 我知道,这两部分我都做了。请参阅我的新编辑。问题是首先缺少另一个require_once() 调用来获取数据库连接。然后参数传递起作用了。
【解决方案3】:

您需要将 PDO 对象作为参数传递给authenticate() 函数:

function authenticate(PDO $pdo, $u, $p) {
    // ..as in the question..
}

哦,您应该在查询中为该用户名使用占位符,而不是容易受到 SQL 注入攻击的字符串连接。

【讨论】:

  • 谢谢。为此目的,您看到的查询被虚拟化,而不是我将在我的代码中运行的实际查询:)。别担心,一切都会在运行时正确转义。
猜你喜欢
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多