Есть ли способ передать результаты PDO в качестве параметров конструктора? Скажем, у меня есть следующий класс:
class Test { private $value1; private $value2; function __construct($val1, $val2) { $this->value1 = $val1; $this->value2 = $val2; } }
Затем, используя драйвер PDO, я выбираю некоторые данные из БД, скажем:
SELECT price, quantity FROM stock $results = $query->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Test");
Прямо сейчас, PDO пропускает эти значения непосредственно к полям класса и обходит конструктор.
Может быть, мне что-то не хватает, но я хочу передать результаты запроса в конструктор. Конструктор не может быть зависимым от запроса, я хочу иметь возможность создавать экземпляр этого класса даже без использования PDO.
[Я отредактировал этот ответ, так как мой предыдущий ответ больше не точен.]
FETCH_CLASS извлекает частные свойства. Пожалуйста, обратитесь к этому ответу .
Может быть, мне что-то не хватает, но я хочу передать результаты запроса в конструктор.
Результаты запроса могут быть привязаны к вашим свойствам объекта напрямую с помощью PDO::FETCH_CLASS
нам также нужен конструктор, который может перезаписать значения из PDO, если это необходимо, поэтому удалите PDO::FETCH_PROPS_LATE
из fetch
.
function __construct($val1=null, $val2=null) { // now the constructor is called after the fetch // if you pass values to it, they will be assigned if ($val1!==null) $this->price = $val1; if ($val2!==null) $this->quantity = $val2; }
у нас есть два способа создания объекта
$stmt = $db->prepare('SELECT price, quantity FROM stock'); $stmt->setFetchMode(PDO::FETCH_CLASS,'Test'); $result = $stmt->fetch();
$result = new Test(25,100);
если вы хотите работать со значениями, которые поступают из базы данных, вы можете сделать это в конструкторе, оставив FETCH_PROPS_LATE
.
function __construct($val1=null, $val2=null) { if ($val1!==null) $this->price = $val1; if ($val2!==null) $this->quantity = $val2; $this->formattedPrice = number_format($this->price,'2'); }
Единственный способ, которым я понял, – использовать константу FETCH_FUNC и предоставить функцию для создания объекта через конструктор.
function rowMapper( $price, $quantity) { return new Test( $price, $quantity); } $results = $query->fetchAll( PDO::FETCH_FUNC, "rowMapper");
Теперь ваши объекты будут созданы только с помощью вашего конструктора, вместо того, чтобы вводить значения PDO в частных данных и разрушать инкапсуляцию.
В вашем случае вы можете передать их следующим образом:
$results = $query->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Test", array('val1', 'val1'));
Читайте о третьем параметре для fetchAll()
здесь .
Я столкнулся с этой ситуацией, создав репозиторий PDO для своих объектов. Я не использую этот подход, потому что мне не нравится сопоставлять параметры один к одному. Это было самое близкое, что я мог бы подражать конструктору, используя статический заводский шаблон.
class User { private $id; public $name; public $isMinor; // make sure parameters are in the same order as the mysql result public static function buildFromPdo($id, $age, $name) { $user = new self; $user->id = $id; $user->name = $name; $user->isMinor = $age < 18; return $user; } public function getId() { return $this->id; } } $stmt = $db->prepare('SELECT id, age, name FROM users'); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_FUNC, "User::buildFromPdo");
«$ result» будет массивом объектов User.