2010-05-29 90 views
4

可以说我有一个这样的类:我可以使PDOStatement-> fetchObject不使用非成员变量吗?

Class User { 
    var $id 
    var $name; 
} 

我跑在PHP中使用PDO像这样的查询:

$stm = $db->prepare('select * from users where id = :id'); 
$r = $stm->execute(array(':id' => $id)); 
$user = $r->fetchObject('User'); 

如果我vardump我的用户对象时,它具有其他各种领域其中我没有在用户类中定义。显然,我可以让我的查询具体化,这样它只会让我回到我需要/想要的字段。但是,如果我不想这样做,是否有办法按照我想要的方式使其工作?

我喜欢fetchObject的想法,因为它是创建这个对象并为我设置成员变量的一行代码。我只是不希望它设置我的班级中没有定义的变量。

编辑:

嗯,好像是karim79权利和获取或fetchObject将无法正常工作,我希望它的方式。在执行获取以获得所需结果后,我添加了以下代码。

$valid_vars = get_class_vars('User'); 
foreach (get_object_vars($user) as $key => $value) { 
    if (!array_key_exists($key, $valid_vars)) { 
     unset($user->$key); 
    } 
} 

显然不是最优雅的解决方案:/我要去延长PDOStatement对象类,并添加自己的方法fetchIntoObject或类似的东西,并自动做这些取消设置。但愿不应该是太大的开销,但我希望能够轻松地读取到一个对象,具有1行代码:)

SUPER编辑:

由于mamaar的评论,我再次回到了文档。我发现问题是什么。 http://us.php.net/manual/en/pdo.constants.php并向下滚动到PDO :: FETCH_CLASS,并说明如果类中不存在属性,则使用魔术方法__set()。我重写了我的目标课堂和田田的方法,工作。再次,不是最优雅的解决方案。但现在我明白了为什么,这对我很重要:D

+0

对不起,我有点迟到了,但我有同样的问题,因为你,所以我只是发现这个职位。在这里了解了这个问题之后,我已经决定在所有的类中有一个用于重写'__set()'的基类更容易,为什么不能从已经创建了__set()'方法的基类继承这样的类?抛出异常? – AgentConundrum 2010-10-04 05:03:23

回答

1

我不认为这是可能的。 fetchObject将创建一个指定为fetchObject$class_name参数(默认为stdClass)的类名实例。它不会检查具有相同名称的现有类并创建一个实例,只将值赋给与结果中的列名匹配的成员变量。我会建议依靠一些更无聊的,就像这样:

$user = new User($result['id'], $result['name']); 

这当然将意味着放弃您的用户类的构造函数:

Class User { 
    var $id 
    var $name; 

    public function __construct($id, $name) 
    { 
    $this->id = $id; 
    $this->name = $name; 
    } 

} 
+0

对。我想避免这样的解决方案,因为fetchObject的吸引力在于它可以用1行代码来实现。我可能只是扩展PDOStatement并添加我自己的方法fetchIntoObject或做我想做的事情。希望表现会好。 – 2010-05-29 02:50:29

0

作为替代,你当然可以只取一个数组,并只需简单地自己输入一下:

$user = (User) $r->fetch(); 

顺便说一句,我还没有看到这种行为。也许你已经激活了PDO :: FETCH_LAZY,这可能会创建额外的数据。你可以用 - > fetchObject(“stdClass”)来测试它,否则原因在于你的User类或它的Parent?

+0

不幸的是,类型转换不起作用,只是抛出错误。你可以键入cast('object'),但不是像(User),(Bar)等特定的类... 至于FETCH_LAZY,我尝试过使用fetch,fetchObject,fetchInto等各种方式,相同。它填充成员变量,然后钉上额外的字段db给它到底,所以在我的例子中,而不是有2个变量(id,name),我的测试对象将有3(id,name,descr)。 – 2010-05-29 02:52:23

1

你也许可以使用PDOStatement->与PDO :: FETCH_CLASS或PDO :: FETCH_INTO取方法为$ fetch_style参数

编辑:所以我试着自己,并得到了它与PDOStatement->setFetchMode

工作
class User 
{ 
    public $id; 
    public $name; 
} 

$db = new PDO('mysql:host=127.0.0.1;dbname=test', 'username', 'password'); 

$stmt = $db->prepare("select * from users where id=:userId"); 
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User'); 
$stmt->execute(array(':userId' => 1)); 

$user = $stmt->fetch(); 
var_dump($user); 
+0

我已经尝试FETCH_INTO和FETCH_CLASS fetch()方法,仍然得到相同的结果。 – 2010-05-29 17:01:44

+1

我得到它使用PDOStatement :: setFetchMode,我的答案是编辑一个工作的例子。 – mamaar 2010-06-01 09:35:43

+0

感谢您的更新。我试过你的确切代码(显然改变了数据库信息),它仍然给我同样的问题。您的评论让我再次查看文档,并发现问题所在。 http://us.php.net/manual/en/pdo.constants.php并向下滚动到PDO :: FETCH_CLASS,并解释如果该类中不存在属性,则使用魔术方法__set()。我重写了我的目标课堂和田田的方法,工作。 – 2010-06-07 00:48:27

2

PDOStatement->execute()不返回对象 - 它返回TRUE/FALSE。

变更线2和3

if ($stm->execute(array(':id' => $id))){  
    $user = $stm->fetchObject('User'); 
} 

和它的作品

+0

我用户行'$ user = $ stm-> fetchObject('User');'但我无法从$ user中检索数据。 – reegan29 2016-02-17 10:30:14

相关问题