Tableau à deux dimensions et foreach

Gloumii
Invité n'ayant pas de compte PHPfrance

31 mai 2012, 15:17

Bonjour à tous, je travaille actuellement sur un projet de première année de DUT et je rencontre un probléme lors de la création de mon site. J'ai créé une page d'administration pour modifier le niveau de mes membres (verrouillé, membre ou administrateur). Mes membres sont stockés dans un fichier ini (imposé) de cette façon :

Code : Tout sélectionner

[email protected];7682fe272099ea26efe39c890b33675b;2.jpg;Pouet;F;15/10/2000;0 [email protected];8ebbdb6e5d4a352d6b0b06d4ac8c55e5;3.png;Li;Tux;01/12/2011;2
(Je sais ce n'est pas la syntaxe "correcte" pour un fichier ini mais je ne le savais pas lorsque j'ai commencé mon site)

Et mon probléme est le suivant, quand je veux modifier le niveau (en fin de ligne) je lis chaque ligne de mon fichier et stocke chaque paramétre dans une case de tableau (avec un explode), ensuite je modifie le paramétre voulu, je vide mon fichier texte et je réécris mon tableau dedans, le probléme c'est que ça bloque au moment de la réécriture, ça ne rentre pas dans le foreach.

Voici mon code :

Code : Tout sélectionner

<?php if (isset($_POST['accepter'])) { $array = Array(); // Avant de mettre cette ligne j'avais une erreur" Notice: Undefined variable: array" et "Warning: Invalid argument supplied for foreach()" $i = 0; $j = 0; while (($logs = fgets($users))) { $explode = explode(';', $logs); while ($j!=7) { if($explode[0] == $_POST['userlist']) { $explode[6] = $_POST['level']; } $array[$i][$j] = $explode[$j]; $j++; } $i++; $j=0; } ftruncate($users, 0); foreach ($array as $j) { $k=0; foreach ($j as $key) { fputs($users, $key); if($k!=5) { fputs($users, ';'); } $k++; } } } ?>
Est-ce que vous savez d'ou vient le problème? Ca fait un moment que je cherche et je ne comprends vraiment pas... :?

Merci d'avance de vos réponses,


Gloumi

kny
Eléphanteau du PHP | 47 Messages

31 mai 2012, 15:26

Si je puis me permettre, vu que tu cherches à récupérer le caractère unique en fin de ligne, il te serais plus simple d'utiliser un:
//le caractère final
$mynumericindix = substr( $mystring, -1);
//la chaîne SANS le caractère final
$mystringwithoutlastnumeric = substr( $mystring, 0, -1 );
Ainsi, tu récupères ton indice numérique d'un côté si besoin, ta chaîne sans le dernier caractère de l'autre, puis tu concatènes après changements tel que:
$mynewstring = $mystringwithoutlastnumeric . $mynewnumeric; // $mynewnumeric pouvant être remplacé par ce que tu as besoin d'insérer évidemment.

Gloumii
Invité n'ayant pas de compte PHPfrance

31 mai 2012, 15:32

Bonjour, merci de ta réponse, oui effectivement pour cette page je n'y avais pas pensé mais je pourrais utiliser ta solution mais je rencontre exactement le même problème sur une page faite pour que les membres puissent modifier leur mot de passe ou leur mail, bizarrement ça marche nickel sur le mot de passe mais pour le mail j'ai exactement le même probléme qu'ici :/

kny
Eléphanteau du PHP | 47 Messages

31 mai 2012, 15:42

Pour le message d'erreur avec $array, c'était normal si tu ne le déclarais pas :)
Sinon concernant le fait que tu n'entres pas dans le foreach, n'as-tu aucun message d'erreur?
Tentes de faire un print_r() ou var_dump() de ton tableau une fois constitué avant de reset ton fichier ini, pour voir ce qu'il te donne.
L'important est de savoir exactement ou cela bloque, en vérifiant chaque étapes de progression.

Gloumii
Invité n'ayant pas de compte PHPfrance

31 mai 2012, 15:49

Ah oui effectivement... Mon tableau est vide apparement sur cette page : array => empty.

Par contre sur ma page de modification du mail et mot de passe ça fonctionne quand je modifie le mot de passe, je donne le code de celle-ci au cas ou :
            <?php 
                $users = fopen('../fichiers/users.ini', 'a+');
                $array = Array(Array());

                if(isset($_POST['modifier'])) {

                    // Vérification de forme pour le nouvel email
                    if($_POST['newpseudo'] != NULL) {
                        // L'adresse mail est déjà utilisée?
                        while (($buffer = fgets($users)) !== false) {
                            $log = explode(';', $buffer);
                            if($log[0] == $_POST['newpseudo']) {
                                echo 'Cette adresse de messagerie est déjà utilisée.';
                                fclose($users);
                                exit();
                            }
                        }
                        // Vérification de la validité de l'e-mail
                        if(!filter_var($_POST['newpseudo'], FILTER_VALIDATE_EMAIL)) {
                            echo "Adresse mail invalide.";
                            exit();
                        }
                        $pseudo=TRUE;
                    }
                    else {
                        $pseudo=FALSE;
                    }

                    // Vérification pour le nouveau mot de passe
                    if($_POST['newmdp'] != NULL) {
                        if(empty($_POST['mdp3'])) {
                            echo "Veuillez remplir tous les champs mot de passe pour modifier celui-ci";
                            exit();
                        }

                        // Vérrification de la longueur minimum du mot de passe (le maximum étant déjà bloqué par la taille du champ)
                        if(strlen($_POST['newmdp'])<8) {
                            echo "Mot de passe trop court, choisissez un mot de passe comportant entre 8 et 16 caractères.";
                            exit();
                        }
                    
                        // Correspondance des mdp
                        if(strcmp($_POST['newmdp'], $_POST['mdp3'])!=0) {
                            echo "Les mots de passe ne correspondent pas.";
                            exit();
                        }
                        $mdp=TRUE;
                    }
                    else {
                        $mdp=FALSE;
                    }


                    $i = 0;
                    $j = 0;
                    while (($logs = fgets($users))) {
                        $explode = explode(';', $logs);

                        while ($j!=7) {

                            if($explode[0] == $_SESSION['pseudo']) {
                                if($pseudo == TRUE) {
                                    $explode[0] = $_POST['newpseudo'];
                                    $_SESSION['pseudo'] = $_POST['newpseudo'];
                                }
                                if($mdp == TRUE) {
                                    $explode[1] = md5($_POST['newmdp']);
                                }
                            }

                            $array[$i][$j] = $explode[$j];
                            $j++;
                        }
                        $i++;
                        $j=0;
                    }

                    var_dump($array);
//                    ftruncate($users, 0);
//
//                    foreach ($array as $j) {
//                        $k=0;
//                        foreach ($j as $key) {
//                            fputs($users, $key);
//                            if($k!=6) {
//                                fputs($users, ';');
//                            }
//                            $k++;
//                        }
//                    }
                }
            ?>
Et le var_dump retourne ceci quand je modifie uniquement le mot de passe :

Code : Tout sélectionner

array 0 => array 0 => string '[email protected]' (length=16) 1 => string '7682fe272099ea26efe39c890b33675b' (length=32) 2 => string '2.jpg' (length=5) 3 => string 'Pouet' (length=5) 4 => string 'F' (length=1) 5 => string '15/10/2000' (length=10) 6 => string '0 ' (length=3) 1 => array 0 => string '[email protected]' (length=13) 1 => string '9d1858e6dfaedd7cc436de74e0d5156f' (length=32) 2 => string '3.png' (length=5) 3 => string 'Li' (length=2) 4 => string 'Tux' (length=3) 5 => string '01/12/2011' (length=10) 6 => string '2 ' (length=3)

kny
Eléphanteau du PHP | 47 Messages

31 mai 2012, 16:03

Je ne peux réellement faire d'essai, cependant tu précises que le tableau est vide, donc cela vient des while.
Il faut donc vérifier quelles données tu récupères et que tu insères.

Autrement je remarque que dans ton code fonctionnel - mots de passe - le foreach comprends un $k != 6.
Or dans le problématique, un $k != 5...
Cela ne réécrira donc pas le code convenablement, puisque tu auras un ";" de trop ou de moins (normalement de trop si je ne me trompe pas)

Petit nouveau ! | 7 Messages

31 mai 2012, 16:21

Ah oui c'est vrai j'ai oublié de le modifier merci beaucoup :)

Bon j'ai fait quelques tests et apparemment je n'entre même pas dans le while, je ne comprends vraiment pas pourquoi... :(
Pourtant j'ouvre bien le fichier plus haut : $users = fopen('../fichiers/users.ini', 'a+');, j'ai essayé de le refermer et de le rouvrir juste au niveau de cette partie mais rien à faire ça ne change pas

kny
Eléphanteau du PHP | 47 Messages

31 mai 2012, 16:51

Tu as testé d'autre ouvertures en fopen? tel que 'w+' ou 'c+'

Petit nouveau ! | 7 Messages

31 mai 2012, 17:07

J'ai essayé comme ceci :
            <?php
                if (isset($_POST['accepter'])) {
                    $array = Array();
                    $users = fopen('../fichiers/users.ini', 'c+');

                    $i = 0;
                    $j = 0;
                    while (($logs = fgets($users))) {
                        $explode = explode(';', $logs);


                        while ($j!=7) {
                            if($explode[0] == $_POST['userlist']) {
                                $explode[6] = $_POST['level'];
                            }
                            
                            $array[$i][$j] = $explode[$j];
                            $j++;
                        }
                        $i++;
                        $j=0;
                    }


                    fclose($users);
                    $users = fopen('../fichiers/users.ini', 'a+');

                    ftruncate($users, 0);

                    foreach ($array as $j) {
                        $k=0;
                        foreach ($j as $key) {
                            fputs($users, $key);
                            if($k!=6) {
                                fputs($users, ';');
                            }
                            $k++;
                        }
                        fputs($users, "\r\n");
                    }
                }
            ?>
Bizarrement ça fonctionne ici (mais toujours pas sur la modification de l'email), j'ai juste un problème je me retrouve avec 2 retours à la ligne à la fin du fichier ça fait planter le reste :/

Petit nouveau ! | 7 Messages

31 mai 2012, 18:21

Bon j'ai résolu mon problème ne me demandez pas comment, par quelques bidouillages pas très propres mais bon ça fera l'affaire... Je pense que le problème était que je ne fermais pas systématiquement mon fichier après utilisation.

J'ai juste un dernier petit probléme, lorsque je modifie l'adresse mail toujours, ça fonctionne mais j'ai un warning au niveau de mes tests : "Warning: fgets(): 5 is not a valid stream resource"
Sur ce morceau de code :
                $test = fopen('../fichiers/users.ini', 'a+');

                if(isset($_POST['modifier'])) {

                    // Vérification de forme pour le nouvel email
                    if($_POST['newpseudo'] != NULL) {
                        // L'adresse mail est déjà utilisée?
                        
                        while (($logs = fgets($test)) !== false) {
                            $log = explode(';', $logs);
                            if($log[0] == $_POST['newpseudo']) {
                                echo 'Cette adresse de messagerie est déjà utilisée.';
                                fclose($test);
                                exit();
                            }
                            fclose($test);
                        }

Mammouth du PHP | 2278 Messages

31 mai 2012, 19:09

Code : Tout sélectionner

[email protected];7682fe272099ea26efe39c890b33675b;2.jpg;Pouet;F;15/10/2000;0 [email protected];8ebbdb6e5d4a352d6b0b06d4ac8c55e5;3.png;Li;Tux;01/12/2011;2
(Je sais ce n'est pas la syntaxe "correcte" pour un fichier ini mais je ne le savais pas lorsque j'ai commencé mon site)
C'est la syntaxe classique d'un fichier CSV, en ajoutant un saut de ligne après chaque enregistrement.

Voici mon code :
Globalemant un code sans commentaires est un code nul

Code : Tout sélectionner

<?php /* acceper c'est quoi?*/ if (isset($_POST['accepter'])) { /* déjà il faut array() avec une minuscule. Ensuite quelle étrange idée de donne rà une variable le nom d'une fonction, au lieu de lui donner un nom significatif de son rôle*/ $array = Array(); // Avant de mettre cette ligne j'avais une erreur" Notice: Undefined variable: array" et "Warning: Invalid argument supplied for foreach()" $i = 0; $j = 0; /* il sort d'où ce users?*/ while (($logs = fgets($users))) { /* mêmes remarques que pour array*/ $explode = explode(';', $logs); while ($j!=7) { if($explode[0] == $_POST['userlist']) { $explode[6] = $_POST['level']; } $array[$i][$j] = $explode[$j]; $j++; } $i++; $j=0; } ftruncate($users, 0); foreach ($array as $j) { $k=0; foreach ($j as $key) { fputs($users, $key); if($k!=5) { fputs($users, ';'); } $k++; } } } ?>
Est-ce que vous savez d'ou vient le problème? Ca fait un moment que je cherche et je ne comprends vraiment pas... :?

Merci d'avance de vos réponses,


Gloumi
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 7 Messages

31 mai 2012, 19:33

Cette partie n'est pas encore commentée mais elle fonctionne maintenant, et j'ai commenté la partie qui pose maintenant problème.
En plus de ça j'explique justement mon code au dessus de ma citation étant donné qu'il n'y a pas de commentaires

Ah j'avais pas vu ton autre commentaire
C'est la syntaxe classique d'un fichier CSV, en ajoutant un saut de ligne après chaque enregistrement.
Oui on m'avait dit de faire ça pour mon premier projet et c'était avec un .dat du coup j'ai repris la même syntaxe mais j'ai appri un peu tard qu'il y avait une autre syntaxe pour les .ini :/

Mammouth du PHP | 2278 Messages

01 juin 2012, 08:54

C'est l'extension .ini qui te perturbe:
Ce sont des fichiers d'initialisation de variables, de déclaration de fonctions (en C par exemple) qui ont une syntaxe différente suivant le langage utilisé ou le programme qui s'en sert.
C'est vrai que tes donées auraient un air plus standard dans un mes_donnees.dat que dans fic.ini.
Moi je me méfierais d'un prof tatillon qui irait chipoter sur l'extension, d'autant que PHP a son propre fichier .ini (http://www.php.net/manual/fr/ini.list.php) qui, lui, a une syntaxe à part. D'autant que ça suppose le changement d'un seul nom dans ton code. (Au fait pourquoi ne peut-on pas choisir soi-même le fichier à importer?).
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 7 Messages

01 juin 2012, 10:45

Oui effectivement elle me pose problème, en fait je me suis contente de reprendre la syntaxe .dat et de modifier l'extension mais je ne savais pas à ce moment là qu'il y avait une syntaxe spéciale pour les ini je l'ai appris un peu tard sachant que je dois rendre le projet ce soir. Je le saurais pour la prochaine fois... :-\ En tout cas merci de m'avoir éclaircit sur le sujet :)

Ce que j'aimerais juste corriger c'est l'erreur que j'ai maintenant sur ma page de modification du profil, j'ai un warning sur mon test mais je ne comprends pas pourquoi étant donné que cette boucle est partout dans mon site et qu'elle fonctionne :/

Mammouth du PHP | 2278 Messages

01 juin 2012, 12:58

L'erreur actuelle se trouve où exactement?
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD