Как использовать PDO :: FETCH_CLASS с методом __set ()? - PullRequest
1 голос
/ 05 апреля 2019

Я хочу создать объект сразу после извлечения данных из моей базы данных.

Для этого я использую PDO :: FETCH_CLASS и переписанный метод __set (), который я добавил в черту.

Однако я не могу понять, почему у меня есть ошибка с упоминанием: "Неустранимая ошибка: Uncaught ArgumentCountError: слишком мало аргументов для функции Banner :: __ construct (), 0 передано и ровно 1 ожидается в D: \ Logiciels \ wamp64 \ www \ projet-4 \ writer-blog \ entity \ Banner.php on line 34"

Вот мой класс Banner (сеттеры и геттеры опущены):

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

Мой магический метод __set () имеет следующую черту:

<?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!');
        }
    }
}

И вот начало моего BannerManager, где я получаю свои данные:

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

1 Ответ

1 голос
/ 05 апреля 2019

Ваш реальный вопрос здесь: как использовать PDO::FETCH_CLASS с классом, который требует параметры конструктора, поскольку это то, что говорится в сообщении об ошибке.

И ответом является третий параметр setFetchMode. .

$req->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Banner',[[]]);

должен добиться цели, предоставив пустой массив для конструктора, что позволит вашему коду достичь точки, где на самом деле вызывается __set().

...