PDO fetchObject по какому принципу работает
Была зача осуществить подмену значений при вызове fetchObject, есть таблица (mysql) у которой один столбец с типом json, думал при создании объекта через fetchObject строку json превратить в массив, решения не нашел. Логично вызвать самому объект и заполнить его, конвертируя значения из базы как угодно.
UPD:
Была зача осуществить подмену значений при вызове `fetchObject...
@LaukhinAndrey помог с решением. Однако вопрос ниже актуален
Свойства целевого объекта приватные, и вот тут не понимаю как именно работает fetchObject, тк в объекте есть методы __set, __clone и не один из них не срабатывает, и возник вопрос, как fetchObject возвращает заполненый класс с приватными свойствами в обход магических методов?
UPD:
Вызвал все методы
class User
{
private ?string $name = null;
private ?string $surname = null;
private ?string $lastname = null;
private ?string $email = null;
private int $phone = 0;
private ?string $address = null;
private $time_register = 0;
private ?string $pass = null;
private $service = '';
function __construct(...$arg)
{
var_dump(__METHOD__);
var_dump($arg);
$this->service = json_decode($this->service, true);
}
function __destruct()
{
var_dump(__METHOD__);
}
function __call($arg1, $arg2)
{
var_dump(__METHOD__);
var_dump($arg1);
var_dump($arg2);
}
static function __callStatic($arg1, $arg2)
{
var_dump(__METHOD__);
var_dump($arg1);
var_dump($arg2);
}
function __get($arg)
{
var_dump(__METHOD__);
var_dump($arg);
}
function __set($arg1, $arg2)
{
var_dump(__METHOD__);
var_dump($arg1);
var_dump($arg2);
}
function __isset($arg)
{
var_dump(__METHOD__);
var_dump($arg);
}
function __unset($arg)
{
var_dump(__METHOD__);
var_dump($arg);
}
function __sleep()
{
var_dump(__METHOD__);
}
function __wakeup()
{
var_dump(__METHOD__);
}
function __serialize()
{
var_dump(__METHOD__);
}
function __unserialize()
{
var_dump(__METHOD__);
}
function __toString()
{
var_dump(__METHOD__);
}
function __invoke()
{
var_dump(__METHOD__);
}
function __set_state()
{
var_dump(__METHOD__);
}
function __clone()
{
var_dump(__METHOD__);
}
}
# ---------------------------------
$PDO = DB::Connect();
$PDOSt = $PDO->query('SELECT * FROM service_users');
var_dump($PDOSt->fetchObject('SCCT\Model\User'));
Результат:
string(28) "SCCT\Model\User::__construct"
array(0) {
}
object(SCCT\Model\User)#51 (9) {
["name":"SCCT\Model\User":private]=>
string(4) "Jonh"
["surname":"SCCT\Model\User":private]=>
string(3) "Doe"
["lastname":"SCCT\Model\User":private]=>
NULL
["email":"SCCT\Model\User":private]=>
string(11) "[email protected]"
["phone":"SCCT\Model\User":private]=>
int(71000010203)
["address":"SCCT\Model\User":private]=>
NULL
["time_register":"SCCT\Model\User":private]=>
string(19) "2022-05-20 13:36:18"
["pass":"SCCT\Model\User":private]=>
NULL
["service":"SCCT\Model\User":private]=>
array(1) {
["hello"]=>
string(5) "world"
}
}
string(27) "SCCT\Model\User::__destruct"
Ответы (1 шт):
Независимо от модификатора доступа, если свойство существует, то будет присвоено значение, если не существует, то будет попытка вызвать магический метод __set. Если он не определён, то свойство будет создано.
Таким образом, мы можем определить __set, чтобы предотвратить автоматическое создание свойств, но он никогда не будет вызван для существующих свойств.
С учетом того, что свойства закрытые, один из вариантов решения: сделать необходимые преобразования в конструкторе класса, передаваемого в fetchObject. Конструктор будет вызван после того, как свойства заполнятся значениями соответствующих столбцов. Это порядок по умолчанию, если не установлен PDO::FETCH_PROPS_LATE.
Другой подход – предусмотреть метод prepareProps, который вызывать при получении очередного объекта из базы.
Изменить приватный метод из вне можно при помощи класса ReflectionProperty.