PDO :: FETCH_CLASS с несколькими классами - PullRequest
0 голосов
/ 12 октября 2011

Я пытаюсь превратить результат запроса в классы.

$result->setFetchMode(PDO::FETCH_CLASS, 'myclass', array());

Это работает довольно хорошо, однако имя класса myclass зависит от значений столбца.

Возможно липолучить каждую строку и превратить ее в другой класс в зависимости от значений строк?


Пример пользователя:

ID # name # age
1  # jon  # 12
2  # sue  # 23
3  # tom  # 24

Я хочу, чтобы все пользователи в возрасте до 21 годабыть экземплярами класса child.Строки с возрастом 21 и выше должны быть экземплярами класса adult.

Таким образом, "jon" должен быть экземпляром child."sue" и "tom" должны быть экземплярами adult.

Ответы [ 4 ]

1 голос
/ 12 октября 2011

Поскольку вы не знаете тип (имя класса) возвращаемых объектов до выполнения запроса, вы не можете его указать.

Однако вы можете инкапсулировать эту логику в другой тип, который вы используете в качестве возвращаемого типакоторый затем может вернуть определенный тип возвращаемого значения:

/**
 * Should not have any private, public or protected members in it's definition.
 * 
 * Does only work for public properties.
 */
class ReturnObject {
    public function getConcrete()
    {
        /* decide here which class */
       $classname = 'Child'; // or 'Adult'

       return $this->selfAs($classname);
    }

    private function selfAs($classname)
    {
        $l = strlen(__CLASS__);
        $s = sprintf('O:%d:"%s"', strlen($classname), $classname).substr(serialize($this), 5+strlen($l)+$l);
        $instance = unserialize($s);
        $instance->__construct();
        return $instance;
    }
}

Затем вы можете использовать функцию getConcrete() для каждого возвращаемого объекта, чтобы вернуть ваш конкретный тип, ваша логика принятия решения связана с возвратом из базы данных.

Редактировать: Я изменил его на версию, которая сначала инициализирует свойства объектов с помощью unserialize (пожалуйста, проверьте, работает ли это, это основано на предположении, что мы говорим только об открытых свойствах, и я неМы не знаем, выполняет ли PDO только установщики или более через отражение в используемом вами режиме), а затем вызывает функцию конструктора.Конструктор должен быть общедоступным (и должен существовать), чтобы это работало.

Технически возможно сделать это доступным также для частных и защищенных членов, однако это требует реального осмысления и также требует анализаа также сериализованные данные.Этот класс только переименовывает имя класса, но не внутри закрытых свойств.

Однако это только один из способов сделать это.Возможно, вам нужна только функция ->isChild() или ->isAdult() в вашем классе Person.

0 голосов
/ 13 февраля 2014
0 голосов
/ 12 октября 2011

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

SELECT 
id,
name,
age,
CASE WHEN age < 21 THEN 'child'
ELSE 'adult' END
AS class_name
FROM SOME_TABLE";

Then use your PDO::FETCH_ASSOC as fetch type
Then when you loop over your results
you can easily instantiave class based on
$result['class_name'] like this:
$class = $result['class_name'];
$obj = new $class;
0 голосов
/ 12 октября 2011

Это не может быть сделано автоматически, это слишком специфично.Вы можете просто перебрать каждую строку и создать экземпляр правильного класса с правильными аргументами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...