2016-05-13 2 views
0

Я рефакторинг частей моего приложения и заменяю некоторые fetch(PDO::FETCH_ASSOC) выделенным классам с помощью fetchObject().Доступ к соединению PDO в 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.

+1

Сделайте член класса (например, 'User :: $ conn') и передайте свое PDO-соединение в качестве параметра в конструкторе, чтобы установить его? – CD001

ответ

4

Вы можете передать экземпляр PDO, поэтому вам не нужно звонить Приложение :: 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 ]); 
+0

Мысль о том, чтобы передать его с помощью 'save()', но в случае, если это произойдет после построения, не может быть заметного соединения. Я пойду с аргументом конструктора, это выглядит очень хорошо. Благодаря! – clemens321

1

Вы должны иметь хранилище пользователя, который позволит сэкономить пользователю БД:

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

Теперь вам нужно зарегистрировать эти классы в Framework, такие как PHP-DI Dependency Injection и использовать их соответствующим образом ..

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

Если вы рефакторинга приложение, то вы должны сделать это правильно.

Обратите внимание, что приведенные выше примеры являются просто информативными, и им необходимо много усовершенствований, которые будут использоваться в производстве.

Смежные вопросы