假设我有一个这样的课程:
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我的用户对象,它有各种其他字段,我没有在User类中定义。显然,我可以使我的查询具体,以便它只返回我需要/想要的字段。但是,如果我不想这样做,有什么方法可以按照我想要的方式进行这项工作吗?
我喜欢fetchObject的想法,因为它是一行代码来创建这个对象并为我设置成员变量。我只是不希望它设置我在课堂上没有定义的变量。
编辑:
好像karim79似乎是正确的,fetch或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 EDIT:
感谢mamaar的评论,我又回到了文档。我发现了问题所在。 http://us.php.net/manual/en/pdo.constants.php并向下滚动到PDO :: FETCH_CLASS,它解释了如果类中不存在属性,则使用魔术方法__set()。我覆盖了我的目标类中的方法和tada,工作。再次,不是最优雅的解决方案。但现在我明白了为什么,这对我很重要:D
答案 0 :(得分:2)
PDOStatement->execute()
不返回对象 - 它返回TRUE / FALSE。
将第2行和第3行更改为
if ( $stm->execute( array( ':id' => $id ) ) ){
$user = $stm->fetchObject( 'User' );
}
并且有效
答案 1 :(得分:1)
我认为这不可行。 fetchObject
将创建一个指定为fetchObject
的{{1}}参数的类名实例(默认为stdClass)。它不会检查具有相同名称的现有类并创建实例,仅将值分配给与结果中的列名匹配的成员变量。我建议依靠更无聊的东西,比如:
$class_name
这当然意味着为您的User类提供构造函数:
$user = new User($result['id'], $result['name']);
答案 2 :(得分:1)
您可以将PDO :: FETCH_CLASS或PDO :: FETCH_INTO的PDOStatement-> fetch方法用作$ 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);
答案 3 :(得分:0)
作为替代方案,您当然可以只获取一个数组并自行对其进行类型转换:
$user = (User) $r->fetch();
是的,我没见过这种行为。也许您激活了PDO :: FETCH_LAZY,这可能会创建额外的数据。您可以使用 - > fetchObject(“stdClass”)测试它,否则原因在于您的User类或其父级?