Position actuelle: Accueil> Derniers articles> Résolvez le problème de l'inadéquation de type lors de l'obtention du résultat de Pdostatement :: fetchObject

Résolvez le problème de l'inadéquation de type lors de l'obtention du résultat de Pdostatement :: fetchObject

gitbox 2025-05-11

Lorsque vous utilisez PDO pour les opérations de base de données, Pdostation :: FetchObject est une méthode très pratique qui peut dire directement les résultats de la requête dans un objet. Mais parfois, nous rencontrons des problèmes de décalage de type, tels que le champ qui était à l'origine un entier ( int ) dans la base de données est converti en une chaîne ( chaîne ). Cette situation est particulièrement gênante lorsqu'elle traite de grandes quantités de données ou nécessitant un type strict de structures de données.

Jetons un coup d'œil aux raisons et aux solutions.

Cause du problème

Pdostatement :: fetchObject lui-même ne déduit pas automatiquement le type de PHP en fonction du type de champ de base de données. Il remplit simplement les données dans les propriétés de l'objet, donc de nombreuses fois, les nombres sont traités sous forme de chaînes. En effet, PDO renvoie toutes les données en tant que chaîne par défaut.

Jetons un coup d'œil à un exemple:

 <?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject();

var_dump($user);
?>

La sortie peut être:

 object(stdClass)#1 (2) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(4) "John"
}

Comme vous pouvez le voir, même si l'ID est de Type INT dans la base de données, le résultat est une chaîne en PHP.

Solution

Il existe plusieurs méthodes courantes pour résoudre ce problème:

1. Utilisez l'option PDO :: att_stringify_fetches (non recommandée)

PDO a un paramètre appelé PDO :: att_stringify_fetches , qui peut contrôler l'opportunité de convertir automatiquement les nombres en chaînes. Cependant, il convient de noter que cette option ne peut être efficace que dans les fonctions Fetch () et n'a aucun effet direct sur FetchObject , il n'est donc pas recommandé.

2. Conversion de type manuel (recommandé)

La méthode la plus pratique consiste à définir une classe et à effectuer manuellement la conversion de type dans le constructeur ou la méthode magique __set .

Par exemple:

 <?php
class User {
    public int $id;
    public string $name;

    public function __construct() {
        // La coercition de type peut être effectuée ici
    }

    public function __set($name, $value) {
        if ($name === 'id') {
            $this->id = (int) $value;
        } elseif ($name === 'name') {
            $this->name = (string) $value;
        }
    }
}

$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject(User::class);

var_dump($user);
?>

De cette façon, lorsque vous récupérez les données de la base de données, vous pouvez vous assurer que le type est correct.

3. Convertir explicitement les types de champs dans les instructions de requête (facultatif)

Dans les instructions SQL, force directement les champs au type requis, tels que:

 SELECT id + 0 AS id, name FROM users

De cette façon, l'ID est déjà un entier lorsque la base de données revient, mais cette méthode n'est pas particulièrement élégante et a une mauvaise maintenance, il ne convient donc que pour le sauvetage d'urgence temporaire.

4. Utilisez des fonctions de cartographie personnalisées (adaptées aux grands projets)

S'il existe de nombreux endroits dans votre projet qui nécessitent une cartographie d'objets, pensez à écrire un outil de mappeur général. Par exemple:

 <?php
function mapUser($data) {
    $user = new User();
    $user->id = (int) $data->id;
    $user->name = (string) $data->name;
    return $user;
}

$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users');
$rawUser = $stmt->fetchObject();
$user = mapUser($rawUser);

var_dump($user);
?>

Cette méthode est plus contrôlable et est facile à gérer et à se développer, comme l'ajout de la logique de vérification à l'étape ultérieure.

Autres précautions

  • Le type de champ de table de données est raisonnablement conçu : essayez de faire en sorte que les champs de la table de la base de données soient autant que possible. Par exemple, l'ID doit être int et le montant doit être décimal . N'utilisez pas de chaînes au lieu de champs numériques.

  • En utilisant des déclarations de type solides : dans PHP 7.4+, en utilisant des indices de type et des déclarations de type d'attribut peuvent détecter les erreurs plus tôt.

  • Encapsulation de couche d'accès aux données unifiées (DAL) : Si le projet est grand, il est préférable d'encapsuler l'accès à la base de données et la cartographie des objets en modules unifiés pour éviter la main-d'œuvre répétée.

résumé

Il est très pratique d'utiliser FetchObject , mais afin d'assurer le type de données correct, il est généralement recommandé de définir la classe vous-même, de coopérer avec la conversion manuelle ou d'utiliser des fonctions de mappage. Cela peut rendre le code plus robuste et réduire le problème du débogage ultérieur.

Si vous souhaitez connaître l'utilisation et la cartographie des objets plus détaillés, vous pouvez vous référer à: https://gitbox.net/docs/pdo-tutorial .