访问fetchObject()中的PDO连接 - 实例

时间:2016-05-13 14:11:09

标签: php pdo

我正在重构我的应用程序的一部分,并将一些fetch(PDO::FETCH_ASSOC)替换为fetchObject()的专用类。

有没有办法在生成的类中访问pdo实例?见这个例子:

class User
{ 
    private $id;
    private $username;
    private $firstname;
    private $lastname;

    public function setFirstname($newValue)
    { 
        if (empty($newValue) || !is_string($newValue)) throw new Exception('Wrong');
        $this->firstname = $newValue;
    } 

    public function save()
    {
        // IMPORTANT PART:
        // I don't want to use the global object container here  
        $dbh = Application::getInstance()->getPDO();

        $sth = $dbh->prepare('UPDATE main_user SET firstname = :firstname WHERE id = :id');
        $sth->execute([ 
            'id'        => $this->id,
            'firstname' => $this->firstname,
        ]);
    } 
} 

$dbh = $application->getPDO();
$sth = $dbh->prepare('SELECT * FROM main_user WHERE id = ?');
$sth->execute([ 10 ]);
$user = $sth->fetchObject('User');
$user->setFirstname('Test');
$user->save();

我的部分应用程序使用多个数据库,因此使用多个pdo对象。为了获得可重用的代码,我想阻止使用我的全局容器类 - 当然还有global

2 个答案:

答案 0 :(得分:4)

您可以传递PDO实例,这样您就不必再次调用 Application :: getInstance() - > getPDO()

public function save(PDO $dbh)
{
    $sth = $dbh->prepare('UPDATE main_user SET firstname = :firstname WHERE id = :id');
    $sth->execute([ 
        'id'        => $this->id,
        'firstname' => $this->firstname,
    ]);
} 
// and pass the (already available) $dbh to the save-Method at the buttom
$user->save($dbh);

或评论中提到的 CD001 ,您也可以将其传递给构造函数:

class User
{
    // ...
    private $conn;

    public function __construct(PDO $conn)
    {
        $this->conn = $conn;
    }
}
// ... later at the bottom when fetching the Object:
$user = $sth->fetchObject('User', [ $dbh ]);

答案 1 :(得分:1)

您应该有一个用户存储库,将用户保存到db:

use \Path\To\User\Model\User;

class UserRepository extends AbstractRepository
{
    public function save(User $user)
    {
        $sth = $this->db->prepare('UPDATE main_user SET firstname = :firstname WHERE id = :id');
        $sth->execute([ 
            'id'        => $user->id, // make sure these properties are public on the model
            'firstname' => $user->firstname,
        ]);
    }
}

class AbstractRepository
{
    protected $db;

    // inject it using Dependency Injection
    public function __construct(DbInterface $db)
    {
        $this->db = $db;
    }
}

然后,在您的模型中,您可以使用用户存储库将其保存到db:

namespace \Path\To\User\Model;

class User
{
    public $id;
    public $username;
    public $firstname;
    public $lastname;

    protected $userRepository;

    // inject it with DI
    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function setFirstname($firstname)
    { 
        if (empty($firstname) || !is_string($firstname)) {
            throw new Exception('Wrong firstname!');
        }

        $this->firstname = $firstname;

        return $this;
    }

    public function save()
    {
        return $this->userRepository->save($this);
    } 
}

现在您需要将这些类注册到依赖注入框架(例如PHP-DI)并正确使用它们。

$user = $container->get('User');
$user->setFirstname('MyUser');
$user->create();

如果您要重构您的应用,那么您应该正确行事。

请注意,上面的示例只是提供信息,需要在生产中使用许多改进。