¿Hay alguna manera de analizar la cadena json antes de convertirla en una clase con PDO? No me gusta usar tipos de unión.
En el siguiente ejemplo, el contacto es de tipo json en la base de datos.
DOP
$stmt = $DB->prepare("SELECT first_name, last_name, contact FROM users"); $stmt->execute(); $stmt->fetchAll(PDO::FETCH_CLASS, 'User');clase de usuario
<?php class User { public string $first_name; public string $last_name; public string | object $contact; public function __construct() { $this->contact = json_decode($this->contact); } }Como sugirió Movahhedi, podría usar PDO::FETCH_FUNC , pero json_decode() debería tener lugar en la función pasada, no en el constructor. Mi sugerencia sería crear una clase UserFactory con un método como createFromDbRow() , aunque simplemente definirla como una función básica también funcionaría, por supuesto:
class User { public string $first_name; public string $last_name; public object $contact; } class UserFactory { public function createFromDbRow(string $first_name, string $last_name, string $contact) : User { $user = new User(); $user->first_name = $first_name; $user->last_name = $last_name; $user->contact = json_decode( $contact ); return $user; } } $db = new PDO('sqlite::memory:'); $db->exec('CREATE TABLE "users" ( "id" INTEGER, "first_name" TEXT, "last_name" TExT, "contact" TEXT )'); $db->exec('INSERT INTO "users" VALUES( 1, \'John\', \'Doe\', \'{"email":"johndoe@example.com"}\')'); $db->exec('INSERT INTO "users" VALUES( 2, \'Jane\', \'Doe\', \'{"email":"janedoe@example.com"}\')'); $userFactory = new UserFactory(); $stmt = $db->prepare("SELECT first_name, last_name, contact FROM users"); $stmt->execute(); $users = $stmt->fetchAll(PDO::FETCH_FUNC, [$userFactory, 'createFromDbRow' ]); var_dump( $users ); Dado que las propiedades del User son todas públicas, dejé fuera un constructor, pero, por supuesto, también podría definir un constructor:
class User { public string $first_name; public string $last_name; public object $contact; public function __construct(string $first_name, string $last_name, object $contact) { $this->first_name = $first_name; $this->last_name = $last_name; $this->contact = $contact; } } ... y luego cree los User s en UserFactory::createFromDbRow() utilizando el constructor:
class UserFactory { public function createFromDbRow(string $first_name, string $last_name, string $contact) : User { return new User( $first_name, $last_name, json_decode( $contact ) ); } }Puedes usar FETCH_FUNC
La función que definimos en realidad hace lo que hace el constructor.
function customConstruct(first_name, $last_name, $contact) { return new User($first_name, $last_name, $contact); }ahora lo hacemos
$stmt = $DB->prepare("SELECT first_name, last_name, contact FROM users"); $stmt->execute(); $stmt->fetchAll(PDO::FETCH_CLASS, 'User'); $results = $stmt->fetchAll(PDO::FETCH_FUNC, "customConstruct");clase de usuario
class User { public string $first_name; public string $last_name; public object $contact; public function __construct($first_name, $last_name, $contact) { $this->first_name = $first_name; $this->last_name = $last_name; $this->contact = json_decode($contact); } }si necesita una matriz, use:
$this->contact = json_decode($contact, true);Tal vez podamos poner la nueva función en la clase. Aunque no estoy 100% seguro.
class User { public string $first_name; public string $last_name; public object $contact; public function __construct($first_name, $last_name, $contact) { $this->first_name = $first_name; $this->last_name = $last_name; $this->contact = json_decode($contact); } function customConstruct(first_name, $last_name, $contact) { return new User($first_name, $last_name, $contact); } }