Php 使用PDO获取对象的新实例时出现问题

Php 使用PDO获取对象的新实例时出现问题,php,pdo,Php,Pdo,我在一个网站上增加了一个通关部分,我遇到了一个PDO的恼人的小问题。我创建了一个ClearanceItem类来保存单个项目的信息。该项的所有属性都受到保护,我已经为它们创建了访问器和变异器。我以这种方式创建类有两个原因: 我可以在设置属性时验证属性。这对我来说很重要,因为数据库是根据客户机维护的Excel文件按照时间表填充的。我可以通过使用变量来验证excel文件中的信息是否在特定范围内 由于网站同时使用英语和法语,访问者可以根据视图语言正确格式化数据(如价格) 我希望能够循环PDO结果集,为每

我在一个网站上增加了一个通关部分,我遇到了一个PDO的恼人的小问题。我创建了一个ClearanceItem类来保存单个项目的信息。该项的所有属性都受到保护,我已经为它们创建了访问器和变异器。我以这种方式创建类有两个原因:

  • 我可以在设置属性时验证属性。这对我来说很重要,因为数据库是根据客户机维护的Excel文件按照时间表填充的。我可以通过使用变量来验证excel文件中的信息是否在特定范围内
  • 由于网站同时使用英语和法语,访问者可以根据视图语言正确格式化数据(如价格)
  • 我希望能够循环PDO结果集,为每一行自动获取ClearanceItem类的新实例。通过设置获取模式或使用PDOStatement::fetchObject()可以轻松完成此操作。不过,我对这些财产受到保护的事实有疑问。当PDO创建一个类的新实例时,它似乎使用了一种称为反射注入的方法来设置属性。这意味着受保护的属性直接由PDO设置,绕过了我创建的变量。由于这个原因,应该是数字的属性(以及由变数设置为数字的属性)被设置为字符串。最糟糕的是,我使用MySQL GROUP_CONCAT以单个字符串的形式返回多个商店和库存的信息,然后mutator应该将其拆分为一个数组。由于PDO直接设置此属性,因此它最终将作为字符串结束


    通过使用工厂方法从resultset行返回的数组中创建ClearanceItem的新实例,我可以轻松克服这个问题。不过,这似乎是不必要的额外步骤。有人知道PDO是否可以在尊重属性可见性的同时,为记录集中的每一行返回一个类的实例,并使用变量来设置属性吗?

    我刚刚验证过,它将为每个属性集调用函数u set()

    class test { function __construct() { print "Constructor\n"; var_dump(func_get_args()); } function __get($x) { print "In get\n"; var_dump($x); } function __set($x, $y) { print "In set\n"; var_dump($x); } } $m = getMasterPDODB(); $stm = $m->prepare("SELECT * FROM users"); if( $stm && $stm->execute() ) { while( $cls = $stm->fetchObject("test") ) { var_dump($cls); } } 课堂测试{ 函数_u构造(){ 打印“构造函数”\n; var_dump(func_get_args()); } 函数获取($x){ 打印“在获取中”\n; var_dump(x美元); } 函数集($x,$y){ 打印“在集合中”\n; var_dump(x美元); } } $m=getMasterPDODB(); $stm=$m->prepare(“从用户中选择*); 如果($stm&&$stm->execute()){ 而($cls=$stm->fetchObject(“测试”)){ var_dump($cls); } } 给我

    Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[6] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[6] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5]
    因为我的详细信息是一个json对象,所以我可以将它解析为所需的字段。你可以让它调用你从那里创建的变异子。这似乎是不使用疯狂忍者魔法的最佳方法。

    我刚刚验证过,它将为每个属性集调用函数u set()

    class test { function __construct() { print "Constructor\n"; var_dump(func_get_args()); } function __get($x) { print "In get\n"; var_dump($x); } function __set($x, $y) { print "In set\n"; var_dump($x); } } $m = getMasterPDODB(); $stm = $m->prepare("SELECT * FROM users"); if( $stm && $stm->execute() ) { while( $cls = $stm->fetchObject("test") ) { var_dump($cls); } } 课堂测试{ 函数_u构造(){ 打印“构造函数”\n; var_dump(func_get_args()); } 函数获取($x){ 打印“在获取中”\n; var_dump(x美元); } 函数集($x,$y){ 打印“在集合中”\n; var_dump(x美元); } } $m=getMasterPDODB(); $stm=$m->prepare(“从用户中选择*); 如果($stm&&$stm->execute()){ 而($cls=$stm->fetchObject(“测试”)){ var_dump($cls); } } 给我

    Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[6] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[6] 建造师 排列 空的 成套 字符串“id”(长度=2) 成套 字符串“活动”(长度=6) 成套 字符串“email”(长度=5) 成套 字符串“密码短语”(长度=10) 成套 字符串“详细信息”(长度=7) 对象(测试)[5]
    因为我的详细信息是一个json对象,所以我可以将它解析为所需的字段。你可以让它调用你从那里创建的变异子。这似乎是不使用疯狂忍者魔法的最佳方式。

    谢谢杰里米,这很奇怪。我曾尝试过这种方法,但对我来说不起作用。区别在于我将第二个参数传递给PDOStatement::fetchObject(),这是一个要传递给构造函数的参数数组。当我在没有这个数组的情况下尝试我的代码时,它一开始对我也起作用。然后我尝试在数组中添加一个