Message d'erreur liée à une contrainte de clé étrangère

Résolu/Fermé
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - Modifié le 13 mars 2022 à 18:32
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - 15 mars 2022 à 12:32
Bonsoir à tous,

J'ai un message d'erreur lors de l'enregistrement de données dans ma base sur mon serveur local alors
que chez Ionos, le traitement se passe bien... La page php qui fait l'opération est la même car je viens
d'écraser la locale par celle du serveur et l'erreur se produit toujours !

Voici le message en local :
Problème à l'enregistrement de l'entête du contrat !
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`gite`.`compositions`, CONSTRAINT `contrat` FOREIGN KEY (`id_contrat`) REFERENCES `contrats` (`id_contrat`) ON DELETE CASCADE) in /var/www/html/gite/gestion/contrat-ajout2.php:126 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(126): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 126

Voici la partie php d'enregistrement :
//Requête préparée pour l'ajout :
        $requete = $bdd->prepare('INSERT INTO contrats(date_contrat, id_client, id_batiment, date_debut, heure_debut, date_fin, heure_fin, adultes, enfants, bebes, animaux) VALUES(:date_contrat, :id_client, :id_batiment, :date_debut, :heure_debut, :date_fin, :heure_fin, :adultes, :enfants, :bebes, :animaux)');
        try
        {
            // Exécution de la requête :
            $requete->execute(array(
                'date_contrat' => $date_contrat,
                'id_client' => $client,
                'id_batiment' => $batiment,
                'date_debut' => $date_debut,
                'heure_debut' => $heure_debut,
                'date_fin' => $date_fin,
                'heure_fin' => $heure_fin,
                'adultes' => $adultes,
                'enfants' => $enfants,
                'bebes' => $bebes,
                'animaux' => $animaux
            ));
        }
        // Problème dans l'enregistrement partie haute du contrat !
        catch(Exception $e)
        {
            echo "Problème à l'enregistrement de l'entête du contrat !";
            //header('Refresh: 3; URL= contrat-ajout1.php');
            
        }





Merci d'avance pour votre aide !

Configuration: Linux / Chrome 99.0.4844.51
A voir également:

9 réponses

jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
13 mars 2022 à 18:48
Bonjour
Si tu ne sais pas comment fonctionnent les clés étrangères.... Non mets pas...
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
13 mars 2022 à 18:49
bonjour,
peux-tu nous montrer le contenu complet de contrat-ajout2.php?
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 14 mars 2022 à 09:08
<?php
ob_start();
header("Cache-Control:no-cache");
// ---------------------------------------------
// 1 - Vérification droit accès à cette page : |
// ---------------------------------------------
// Est-ce que la session existe ?
session_start();
if (!isset($_SESSION['login2']))
{
    header('Location: index.php');
    exit();
}
// ---------------------------------------------------------
// 2 - Vérification de la durée de la session actuelle :   |
// ---------------------------------------------------------
// Est-ce que la session est encore valide ?
if (time() - $_SESSION['derniereaction2'] > 900)
{
    // la session a expiré, retour page d'accueil
    session_unset();
    session_destroy();
    header('Location: index.php');
    exit();
}
// LA SESSION EST TOUJOURS EN COURS, ON CONTINUE
$_SESSION['derniereaction2'] = time(); // on relance la durée de la session
if ($_SESSION['action'] <> "contrat-ajout")
{
    $message = "Comment êtes-vous arrivé ici !";
    $message2 = "à l'accueil...";
    header('Refresh: 3; URL= accueil.php');
    $alerte = "1";
}
else
{
    // Des prestations sont elles sur le contrat ?
    if (!isset($_POST["chaine_contrat"]) || $_POST["chaine_contrat"] == "")
    {
        $alerte = "1";
        $message = "Il n'y a pas de prestation sur ce contrat !";
        $message2 = "à la page précédente...";
        //récupération PROPRE des variables AVANT de les utiliser
        $client = !empty($_POST['client']) ? $_POST['client'] : NULL;
        $batiment = !empty($_POST['batiment']) ? $_POST['batiment'] : NULL;
        $date_debut = !empty($_POST['date_debut']) ? $_POST['date_debut'] : NULL;
        $heure_debut = !empty($_POST['heure_debut']) ? $_POST['heure_debut'] : NULL;
        $date_fin = !empty($_POST['date_fin']) ? $_POST['date_fin'] : NULL;
        $heure_fin = !empty($_POST['heure_fin']) ? $_POST['heure_fin'] : NULL;
        $adultes = !empty($_POST['adultes']) ? $_POST['adultes'] : NULL;
        $enfants = !empty($_POST['enfants']) ? $_POST['enfants'] : NULL;
        $bebes = !empty($_POST['bebes']) ? $_POST['bebes'] : NULL;
        $animaux = !empty($_POST['animaux']) ? $_POST['animaux'] : NULL;
        //récupération des saisies formulaire :
        $_SESSION['client'] = htmlspecialchars($client);
        $_SESSION['batiment'] = htmlspecialchars($batiment);
        $_SESSION['date_debut'] = htmlspecialchars($date_debut);
        $_SESSION['heure_debut'] = htmlspecialchars($heure_debut);
        $_SESSION['date_fin'] = htmlspecialchars($date_fin);
        $_SESSION['heure_fin'] = htmlspecialchars($heure_fin);
        $_SESSION['adultes'] = htmlspecialchars($adultes);
        $_SESSION['enfants'] = htmlspecialchars($enfants);
        $_SESSION['bebes'] = htmlspecialchars($bebes);
        $_SESSION['animaux'] = htmlspecialchars($animaux);
        header('Refresh: 3; URL= contrat-ajout1.php');
    }
    else
    {
        // TOUT EST BON, ON VA ENREGISTRER LE CONTRAT DANS LA BASE DE DONNÉES :
        // Connexion à la base de données :
        require ("connexion.php");
        // Récupération de la date du jour :
        $date_contrat = date('Y/m/d');
        // La facture n'existe pas encore : 
        $facture='0';
        // Récupération des données formulaire :
        $client = $_POST['client'];
        $batiment = $_POST['batiment'];
        $date_debut = $_POST['date_debut'];
        $heure_debut = $_POST['heure_debut'];
        $date_fin = $_POST['date_fin'];
        $heure_fin = $_POST['heure_fin'];
        $adultes = $_POST['adultes'];
        $enfants = $_POST['enfants'];
        $bebes = $_POST['bebes'];
        $animaux = $_POST['animaux'];
        $chaine_contrat = $_POST['chaine_contrat'];
        $tab_contrat = explode('|', $chaine_contrat);
        //Requête préparée pour l'ajout :
        $requete = $bdd->prepare('INSERT INTO contrats(facture, date_contrat, id_client, id_batiment, date_debut, heure_debut, date_fin, heure_fin, adultes, enfants, bebes, animaux) VALUES(:facture, :date_contrat, :id_client, :id_batiment, :date_debut, :heure_debut, :date_fin, :heure_fin, :adultes, :enfants, :bebes, :animaux)');
        try
        {
            // Exécution de la requête :
            $requete->execute(array(
                'facture' =>$facture,
                'date_contrat' => $date_contrat,
                'id_client' => $client,
                'id_batiment' => $batiment,
                'date_debut' => $date_debut,
                'heure_debut' => $heure_debut,
                'date_fin' => $date_fin,
                'heure_fin' => $heure_fin,
                'adultes' => $adultes,
                'enfants' => $enfants,
                'bebes' => $bebes,
                'animaux' => $animaux
            ));
        }
        // Problème dans l'enregistrement partie haute du contrat !
        catch(Exception $e)
        {
            echo "Problème à l'enregistrement de l'entête du contrat !";
            header('Refresh: 3; URL= contrat-ajout1.php');
            exit();            
        }
        // Récupération du dernier ID inséré dans la table contrats :
        $last_insert_id = $bdd->lastInsertId();
        for ($ligne = 0;$ligne < sizeof($tab_contrat);$ligne++)
        {
            if ($tab_contrat[$ligne] != "")
            {
                $ligne_cont = explode(";", $tab_contrat[$ligne]);
                //Requête préparée pour l'ajout des éléments qui composent le contrat :
                $requete2 = $bdd->prepare('INSERT INTO compositions(id_contrat, id_prestation, prix, quantites) VALUES(:id_contrat, :id_prestation, :prix, :quantites)');
                $requete2->execute(array(
                    'id_contrat' => $last_insert_id,
                    'id_prestation' => $ligne_cont[0],
                    'prix' => $ligne_cont[2],
                    'quantites' => $ligne_cont[3]
                ));
            }
        }
        // L'enregistrement du contrat s'est bien passée, on détruit les variables de session :
        unset($_SESSION['client']);
        unset($_SESSION['batiment']);
        unset($_SESSION['date_debut']);
        unset($_SESSION['heure_debut']);
        unset($_SESSION['date_fin']);
        unset($_SESSION['heure_fin']);
        unset($_SESSION['adultes']);
        unset($_SESSION['enfants']);
        unset($_SESSION['bebes']);
        unset($_SESSION['animaux']);
        unset($_SESSION['action']);
        // On supprimer les variables de formulaire
        $client = '';
        $batiment = '';
        $date_debut = '';
        $heure_debut = '';
        $date_fin = '';
        $heure_fin = '';
        $adultes = '';
        $enfants = '';
        $bebes = '';
        $animaux = '';
        $alerte = "2";
        $message = "Le contrat a bien été enregistré !";
        $message2 = "à l'accueil...";
        // Clôture des requettes :
        $requete->closeCursor();
        $requete2->closeCursor();
        header('Refresh: 3; URL= accueil.php');
    }
}
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20 > emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024
14 mars 2022 à 09:40
Le problème est certainement sur ma bdd locale car je viens de transférer mes pages PHP cette fois ci de mon PC local (orid portable) vers mon serveur distant IONOS et je peux ajouter sans problème un contrat qui apparaît bien dans la bdd d'IONOS sans message d'erreur et qui peut quand on l'efface supprimer en CASCADE toutes les 'compositions' liées par l'id_contrat
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
13 mars 2022 à 18:58
C'est à dire que je n'ai pas le choix, certaines données sont liées à d'autres tables et jusqu'à maintenant cela fonctionnait et cela fonctionne encore chez Ionos...

Je pense que mes problèmes viennent du moment où j'ai ajouté une colonne en local mais je ne vois pas comment cela pourrait affecter le fonctionnement de des autres colonnes ? J'ai depuis viré cette colonne, mais cela n'a rien changé...

Je peux aussi me passer d'effacer en cascade les données des tables dont certaines infos sont liées par ces clés et procéder plutôt par une deuxième requête, cela me permettrait de supprimer la notion de ON DELETE CASCADE
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 14 mars 2022 à 07:45
Bonjour,
Hier j'en avais marre de chercher dans tous les sens, et après avoir rapatrié une dernière fois ma
page php du serveur distant Ionos vers mon site local sur mon pc portable, j'ai tout éteint après un
dernier essai raté.

Ce matin, avt d'envoyer un morceau de code supplémentaire pour répondre à la demande d'yg_be
je fais un nouvel essai et tout fonctionne de nouveau en local !!!!!!!

La question que je me pose est : Est-ce que le redémarrage de mon portable y est pour quelque chose ?
si oui quelle manip aurais-je pu faire sur mes tables pour simuler un redémarrage PC car si ce genre
de problème m'arrivait en distant chez IONOS je ne pourrais pas éteindre le serveur pour une nuit !

EDIT : Pour info, le dernier réglage sur le champs id_batiment de ma base de données était :
ON DELETE : RESTRICT
ON UPDATE : RESTRICT
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
14 mars 2022 à 08:49
(Je n'arrive plus à continuer ce fil de discussion ni sur Chrome ni sur Firefox...donc je le commente ????)

EDIT 2 : J'ai remis ON DELETE : CASCADE sur le champs 'id_contrat' de la table 'compositions' le message est réapparu. Pour testé, j'ai supprimé la contrainte de la table 'compositions' pour la mettre sur la table principale 'contrats' : le message d'erreur n’apparaît pas mais quand je supprime un contrat, évidemment tous les éléments qui le composent dans la table 'compositions' ne disparaissent pas !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
14 mars 2022 à 11:36
Ton soucis est donc avec l'insertion dans la table compositions.
Ce serait bien d'également mettre cela dans un try/catch, et en cas d'erreur, d'afficher la valeur de l'array de paramètres, inclus $last_insert_id.
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
14 mars 2022 à 14:01
Non, mon problème arrive au try/catch de INSERT INTO contrats...
Comme j'ai mis un exit() juste après le message "Problème à l'enregistrement de l'entête du contrat !"
rien ne s'enregistre dans 'contrats' (plantage) et rien dans 'compositions' (exit())


D'autre part, je t'ai donné une copie de mon code parce que tu me l'as demandé mais dans la mesure où
ce même code fonctionne parfaitement sur le serveur de mon hébergeur IONOS j'ai plutôt pensé que le
problème venait de ma bdd...
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 14 mars 2022 à 14:10
EDIT : Enfin, chose étrange, j'ai une page contrat-modif.php qui comme son nom l'indique permet de
modifier le contrat ('UPDATE contrats') en cas de nécessité : La modification qui agit sur les 2 mêmes tables (contrats + compositions) fonctionne parfaitement !!!
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
Modifié le 14 mars 2022 à 14:13
tes soucis avec les contraintes, c'était donc simplement parce que tu essayais d'insérer dans compositions alors que l'insertion n'avait pas fonctionné dans contrats.

en cas d'erreur dans le try/catch, il est utile d'afficher de quelle erreur il s'agit.
https://www.php.net/manual/fr/exception.getmessage.php
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 15 mars 2022 à 09:35
Excuse moi je ne comprends pas !

1. Si mon plantage se produit au moment de l'enregistrement de la partie haute du contrat (l'en-tête) dans la
table 'contrats' , toute la suite c'est à dire la partie de code concernant le contenu du contrat qui devrait
normalement s'enregistrer dans la table 'compositions' n'est même pas lue par le serveur non ?

2. J'ai mis un catch(Exception $e) sur ma première requête (celle qui plante) et j'ai bien un message d'erreur :
cf mon premier post...


pour rappel :
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`gite`.`compositions`, CONSTRAINT `contrat` FOREIGN KEY (`id_contrat`) REFERENCES `contrats` (`id_contrat`) ON DELETE CASCADE) in /var/www/html/gite/gestion/contrat-ajout2.php:126 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(126): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 126



3. Pourquoi le serveur d'IONOS qui ne plante absolument pas ne réagit t-il pas comme mon serveur local sur mon PC puisque c'est la même page PHP qui tente d'enregistrer les données ?
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
15 mars 2022 à 10:01
le message d'erreur ne correspond pas au code que tu as partagé en #6.

le try/catch empêche le plantage, donc le code continue, sauf si tu mets un exit().

comme le code continue sans avoir inséré le contrat, il arrive à l'insertion de la composition, qui, sans try/catch, se plante, vu la contrainte qui empêche d'insérer une composition sans contrat

Si tu veux comprendre ce qui se passe, il est nécessaire de faire ce qui est expliqué en #11.
Si c'est trop compliqué pour toi, supprime le try/catch, tu auras un plantage avec un message explicatif.
1
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
15 mars 2022 à 10:14
Ah ok, je comprends...
J'ai ajouté exit() quand je me suis rendu compte que j'allais flinguer ma table 'compositions' avec
l'insertion de données sans que la partie haute soit renseignée dans la table 'contrats'...

Je viens de virer le try/catch et j'ai ça qui est plus parlant du coup :


Fatal error: Uncaught PDOException: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect time value: '' for column `gite`.`contrats`.`heure_debut` at row 1 in /var/www/html/gite/gestion/contrat-ajout2.php:121 Stack trace: #0 /var/www/html/gite/gestion/contrat-ajout2.php(121): PDOStatement->execute() #1 {main} thrown in /var/www/html/gite/gestion/contrat-ajout2.php on line 121
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 15 mars 2022 à 11:40
EDIT : Les champs 'Heure d'arrivée' & 'Heure de départ' n'étant pas obligatoires à la validation du
formulaire je me retrouvais à enregistrer du vide ce qui devait causer l'erreur...

J'ai ajouté ça :

$heure_debut = $_POST['heure_debut'];
$heure_debut=='' ? $heure_debut='00:00':$heure_debut = $_POST['heure_debut'];
$heure_fin = $_POST['heure_fin'];
$heure_fin=='' ? $heure_fin='00:00':$heure_fin = $_POST['heure_fin'];


... et tout est réglé !
Merci beaucoup yg_be !
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476 > emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024
15 mars 2022 à 11:40
moi j'écrirais plutôt:
$heure_debut = $_POST['heure_debut']=='' ? '00:00' : $_POST['heure_debut']; 
1
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
15 mars 2022 à 12:32
Plus pro...pre !
;-)
Merci
0