简体   繁体   English

在fetchObject()-instance中访问PDO连接

[英]Access PDO connection in fetchObject()-instance

I'm refactoring parts of my application and replace some fetch(PDO::FETCH_ASSOC) to dedicated classes with fetchObject() . 我正在重构应用程序的各个部分,并用fetchObject()将某些fetch(PDO::FETCH_ASSOC)替换为专用类。

Is there a way to access the pdo instance inside the generated class? 有没有办法在生成的类中访问pdo实例? See this example: 请参阅以下示例:

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();

Parts of my application use multiple databases and thus multiple pdo objects. 我的应用程序的一部分使用多个数据库,因此使用多个pdo对象。 To get reuseable code, I'd like to prevent using my global container class - and global of course. 要获得可重复使用的代码,我想避免使用我的全球集装箱班-和global课程。

You can pass the PDO Instance so you don't have to call Application::getInstance()->getPDO() again. 您可以传递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);

or as CD001 mentioned in the comments, you can also pass it to the constructor: 或如注释中提到的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 ]);

You should have an user repository which will save the user to db: 您应该有一个用户存储库,该用户存储库会将用户保存到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;
    }
}

Then, in your Model you can use the user repository to save it to 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);
    } 
}

Now you need to register these classes to a Dependency Injection Framework such as PHP-DI and to use them appropriately.. 现在,您需要将这些类注册到依赖注入框架(例如PHP-DI) ,并适当地使用它们。

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

If you are refactoring your app then you should do it right. 如果您重构应用程序,则应该正确执行。

Please note that the examples above are just informative and they need many improvements to be used in production. 请注意,以上示例仅提供参考,它们需要大量改进才能用于生产中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM