PHP PDO :: FETCH_LAZY - 在访问时不创建对象变量名

时间:2013-01-22 15:32:07

标签: php pdo

我正在使用PDO,无法理解PDO :: FETCH_LAZY。在PHP手册中,它说“...... PDO :: FETCH_LAZY在访问时创建对象变量名称......”。我有这个代码来测试这个:

class b{
    function __construct(){}
}
$b = new b();

$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'pssword');

//testtable{id int, title varchar, msg varchar, time varchar}

$res = $pdo->query("SELECT * FROM testtable limit 1");
$b = $res->fetch(PDO::FETCH_LAZY);
echo $b->msg;
var_dump($b);

这应该只用一个属性msg打印对象b。但相反,输出是这样的:

This is a sample message.

object(PDORow)#6 (5) {
  ["queryString"]=>
  string(31) "SELECT * FROM testtable limit 1"
  ["id"]=>
  string(1) "1"
  ["title"]=>
  string(5) "sample title"
  ["msg"]=>
  string(13) "This is a sample message."
  ["time"]=>
  string(7) "1232123"
}

任何人都可以对此有所了解吗?感谢。

2 个答案:

答案 0 :(得分:1)

在行

$b = $res->fetch(PDO::FETCH_LAZY);

你给变量$ b重写'b'对象

给了新值(PDORow对象)

答案 1 :(得分:1)

PDORow是一个内部类,文献很少。 甚至不是in the manual(搜索结果)。

查看PDORow的唯一方法是如果您使用FETCH_LAZY:

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->bindValue(':id', 1, PDO::PARAM_INT);
$stmt->execute();
$lazy = $stmt->fetch(PDO::FETCH_LAZY);

有趣的是,它的所有属性都是公共的。第一个“ queryString”与sql查询关联。这是某种代理。

您可以将其重新用于其他语句,以获取完整的对象。 (几乎)获取PDORow不会增加内存使用量。它不可序列化,并且对其调用未定义的属性不会引发错误。

More about it on phpdelusions.net

  

使用延迟获取时从PDO返回的对象不是stdclass对象,它们是pdorow类型,并且具有一些神奇的功能,包括延迟的数据获取-这与pdo _驱动程序的设置方式有些混淆

You can follow this interesting discussion

从php-src中,we can see that PDORow is not meant to be instantiated

You can see several details about the class in pdo_stmt.c Ctrl + F PDORow其余

修改

FETCH_LAZY的可能用例是:

// get the lazy object - aka, PDORow
    $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
    $stmt->bindValue(':id', 100, PDO::PARAM_INT);
    $stmt->execute();
    $lazy = $stmt->fetch(PDO::FETCH_LAZY);

接下来,重新使用它:

// do whatever you please with the properties, since they're all public
   $publicProps = get_object_vars($lazy);

然后,如果需要,加载真实对象:

// loading lazy object
    $stmt = $pdo->prepare($publicProps['queryString']);
    $stmt->bindValue(':id', $publicProps['id'], PDO::PARAM_INT); 
    /** you could use a regex to get an array of parameters' names prefixed by ':' in the original queryString
    * eg, $queryString = 'SELECT * FROM users WHERE firstName = :firstName AND email = :email';
    * preg_match_all('/:[^\s]+/', $queryString, $matches);
    * would give you an array with ":firstName" and ":email"
    */
    $stmt->execute([':id' => $publicProps['id']]);
    $notLazy = $stmt->fetch();

顺便说一句,(个人笔记)这越来越像教义代理了,所以嗨,马可!你最近好吗药膏,阿米科。