I want to create an object right after fetching data from my database.
For that I’m using PDO::FETCH_CLASS and a rewritten __set() method that I’ve put in a trait.
However, I can’t figure out why I have an error mentionning : “Fatal error: Uncaught ArgumentCountError: Too few arguments to function Banner::__construct(), 0 passed and exactly 1 expected in D:Logicielswamp64wwwprojet-4writer-blogentityBanner.php on line 34”
Here is my Banner class (setters and getters omitted) :
<?php require_once(__DIR__.'Set.php'); /** * This class represents a banner that will be displayed on the homepage of the FrontEnd */ class Banner { use Set; protected $errors=[], $id, $displayOrder, $title, $caption, $image, $buttonTitle, $buttonLink, $creationDate, $modificationDate; /** * Constants for errors management during the execution of the methods */ const INCORRECT_IMAGE_LINK = 1; const INCORRECT_TITLE = 2; const INCORRECT_CAPTION = 3; /** * Class constructor which assign values that have been passed in parameters to matching attributes * * @param array $donnees The values to allocate * @return void */ public function __construct(array $data) { $this->hydrate($data); } /** * Method that allocates specified valued to the matching attributes * * @param array $donnees The values to allocate * @return void */ public function hydrate($data) { foreach ($data as $key => $value) { $method = 'set'.ucfirst($key); if (method_exists($this, $method)) { $this->$method($value); } } }
My magical method __set() is in the following Trait :
<?php trait Set { public function __set($property, $value) { $explodedProperty = explode("_", $property); for ($i = 1 ; $i < count($explodedProperty); $i++) { ucfirst($explodedProperty[$i]); } $rightPropertyName = ucfirst(implode($explodedProperty)); if (property_exists(__CLASS__, $rightPropertyName)) { $this->$rightPropertyName = $value; } else { throw new Exception('La propriété n'a pas pu se voir assigner une valeur car elle n'existe pas!'); } } }
And here is the beggining of my BannerManager where I fetch my data :
<?php require_once("model/Manager.php"); require_once("entity/Banner.php"); class BannerManager extends Manager { public function getBanners() { $db = $this->dbConnect(); $req = $db->query('SELECT id, title, caption, image, button_title, button_link, DATE_FORMAT(creation_date, '%d/%m/%Y à %Hh%imin%ss') AS creation_date_fr, DATE_FORMAT(modification_date, '%d/%m/%Y à %Hh%imin%ss') AS modification_date_fr FROM banners ORDER BY display_order LIMIT 5'); $req->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Banner'); $banners = $req->fetchAll(); return $banners; }
Advertisement
Answer
Your actual question here is How to use PDO::FETCH_CLASS
with a class that requires constructor parameters as that’s what the error message says.
And the answer is setFetchMode’s third parameter..
$req->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Banner',[[]]);
should do the trick, providing an empty array for the constructor, thus letting your code reach the point where __set()
is actually called.