IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

foreach sur un objet [PHP 5.6]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut foreach sur un objet
    Bonjour,

    Est-il possible de faire un foreach sur un objet retourné dans le constructeur ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    class Functions {
     
    private $func = []; 
     
    public function __construct() { 
     $this->fonctions_a_appeler(); 
    }
     
    public function fonctions_a_appeler() {
     $this-> addFunction (['isRequired', 'isAlphaM']);
    }
     
    public function addFunction (array $functions=[]) { 
     $this->func = $functions;
    }
     
    public function getField() {
     return $this->func; 
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    class Valid {
     
    private $post = []; 
    private $func = []; //'isRequired', 'isAlphaM'
     
    public function __construct ($post,$ofunctions) { //
     var_dump($this->post = $post); 
     var_dump($this->func = $ofunctions); 
    }
     
    static function isRequired($value){
     if(!empty(trim($value))) {
      echo 'OK pour required : ' .$value. '<br><br>';
     } else {
      echo ' required KO <br><br>';
     return false;
     }
    }
     
    static function isAlphaM($value){
     if (!preg_match('/^[A-Z\'-_]{2,30}$/', $value)) {
      echo 'Alpha Majucule KO : ' .$value. '<br><br>' ; 
      return false;
     } else {
      echo 'OK Alpha : ' .$value. '<br><br>';
     }
    }
     
    public function getPost() {
     return $this->post; 
    }
     
    public function getFunction() {
     return $this->func; 
    }
     
    public function test(){
     foreach ($this->getPost() as $name => $value) {
      foreach ($this->getFunction() as $rules => $rule) {
       echo 'test des foreach'; 
       //call_user_func_array(array($this, $rule), array($value));
      //}  
     }
    }
     
    }
     
    $functions = new Functions(); 
    //var_dump($functions); 
     
    $valid = new Valid ($_POST, $functions); // je passe le post et l'objet Functions dans le constructeur 
    //var_dump($valid); 
    //var_dump($valid->getPost()); 
    //var_dump($valid->getFunction());
     
    $valid->test();
    j'aimerai déjà réussir à faire apparaître le 'echo : test des foreach '. Il n'y a pas de message d'erreurs mais rien ne s'affiche....
    Le écho apparaît lorsque je mets les appels des méthodes directement dans la propriété privée
    private $func = ['isRequired', 'isAlphaM'];

    Pb :
    peut-on faire passer un objet dans un constructeur d'une autre class
    comment réussir ma boucle sur mon objet
    faire appel call user func array pour appeler mes fonctions via mon objet

    merci pour vos retours






    Merci pour vos retours

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,
    Citation Envoyé par bricoreur Voir le message
    peut-on faire passer un objet dans un constructeur d'une autre class
    Bien sûr, il te suffit de typer ton paramètre
    Citation Envoyé par bricoreur Voir le message
    comment réussir ma boucle sur mon objet
    Boucler les fonctions d'un objet n'a quasiment aucune utilité et relève d'après moi d'une erreur de conception.

    Si tu cherches à exécuter des fonction dans un contexte particulier, tu as pour cela en PHP les closures

    Bonne continuation dans la recherche d'un système de validation flexible et ouvert

  3. #3
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Comme ça ça à l'air de fonctionner.
    J'ai mis $this->getFunction()->getField() à la place de $this->getFunction().


    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <form action="test9503b.php" method="post" name="form1">
     <input type="input" name="tosave"  id="tosave"/>
     <input type="input" name="go"      id="go" value="1"/> 
     <input type="input" name="usefile" id="usefile"/> 
      <input type="submit"/> 
    </form>

    fichier : test9503b.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    <?php
     
    class Functions {
     
     private $func = []; 
     
     public function __construct() { 
      $this->fonctions_a_appeler(); 
     }
     
     public function fonctions_a_appeler() {
      $this-> addFunction (['isRequired', 'isAlphaM']);
     }
     
     public function addFunction (array $functions=[]) { 
      $this->func = $functions; //============== je me demande s'il ne faudrait pas écrire  $this->func[] puisque $func est un tableau !
     }
     
     public function getField() {
      return $this->func; 
     }
    }
     
    class Valid {
     
     private $post = []; 
     private $func = []; //'isRequired', 'isAlphaM'
     
     public function __construct ($post,$ofunctions) { //
      $this->post = $post; 
       $this->func = $ofunctions; 
     }
     
     static function isRequired($value){
      if(!empty(trim($value))) {
       echo 'OK pour required : ' .$value. '<br><br>';
      } else {
       echo ' required KO <br><br>';
      return false;
      }
     }
     
     static function isAlphaM($value){
      if (!preg_match('/^[A-Z\'-_]{2,30}$/', $value)) {
       echo 'Alpha Majucule KO : ' .$value. '<br><br>' ; 
       return false;
      } else {
       echo 'OK Alpha : ' .$value. '<br><br>';
      }
     }
     
     public function getPost() {
      return $this->post; 
     }
     
     public function getFunction() {
      return $this->func; 
     }
     
     public function test(){
      foreach ($this->getPost() as $name => $value) {
       foreach ($this->getFunction()->getField() as $rules => $rule) { //==================== modifié
        echo 'test des foreach'; 
        //call_user_func_array(array($this, $rule), array($value));
       //}  
       }
      }
     }
    }
     
    $functions = new Functions(); 
    //var_dump($functions); 
     
    $valid = new Valid ($_POST, $functions); // je passe le post et l'objet Functions dans le constructeur 
    //var_dump($valid); 
    //var_dump($valid->getPost()); 
    //var_dump($valid->getFunction());
     
    $valid->test();

  4. #4
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut
    Merci, vos codes marchent très bien..et je pensais m'en sortir à partir de vos conseils mais je n'arrive toujours pas à écrire ma méthode validate()

    code html
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <form action = "form_post.php" method="post">
     <p><input type="text" name="nom"></p>
     <p><input type="text" name="prenom"></p>
     <input type="submit" name="SOUMETTRE" value="VALIDATION">
    </form>
    autoload.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <?php
    spl_autoload_register('autoload');
     
    function autoload($class){
     //die($class); 
     require "$class.php";
    }
    form_post.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    <?php
     
    require 'Autoload.php'; 
     
    $functions = new Functions(); 
     
     echo 'Résultat de getField() : '; 
     echo '<pre>';
     print_r($functions->getField());
     echo '</pre>';
     
    $valid = new Valid ($_POST, $functions); // 
     
     
    $valid->validate(); 
     
    if (!$valid->isValid()) {
    $valid->displayErrors(); 
    } else {
    echo 'SUITE DU TRAITEMENT - ENREGISTREMENT'; 
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    <?php
     
    class Functions {                     // le choix du nom n'est pas pertinent -> Rules_Form_connexion , Rules_Form_SignUp, Rules_Form_xxxxx
     private $func = []; 
     
     public function __construct() { 
      $this->fonctions_todo(); 
     }
     
     public function fonctions_todo() {
      $this-> addFunction ('nom', ['isRequired', 'isAlphaM']);
      $this-> addFunction ('prenom', ['isAlphaM']);
     // tous les tests que j'aimerai faire sur les champs d'un formulaire - à terme j'écrirai une class Abstraite et des class filles par formulaire distinct.....
     }
     
     public function addFunction ($name, array $functions=[]) { 
      $this->func[$name] = $functions;
     }
     
     public function getField() {
      return $this->func; 
     }
    }
     
    ?>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    <?php
     
    class Valid {
     
     private $post = []; 
     private $func = [];    
     
     public function __construct ($post,$ofunctions) { 
      $this->post = $post;
      $this->func = $ofunctions;
     }
     
     static function isRequired($value){
      if(!empty(trim($value))) {
       echo 'OK Required: ' .$value. '<br><br>';
      } else {
       echo ' Required KO <br><br>';
       return false;
      }
     }
     
     static function isAlphaM($value){
      if (!preg_match('/^[A-Z\'-_]{2,30}$/', $value)) {
       echo 'Alpha Majucule KO : ' .$value. '<br><br>' ; 
       return false;
      } else {
       echo 'OK Alpha : ' .$value. '<br><br>';
      }
     }
     
     public function getPost() {
      return $this->post; 
     }
     
     public function getFunction() {
      return $this->func; 
     }
     
     public function isValid() {  //renvoi un booléen
      return empty($this->errors);
     }
     
     private function getErrors() { // si utilisation displayErrors => private
      return $this->errors;
     }
     
     public function displayErrors(){
      $html = '<ul>';
      foreach($this->getErrors() as $errors){
       $html .= "<li> Erreur : " .$errors."</li>";
      }
      $html .= '</ul>';
      echo $html; //return $html
     }  
     
     public function validate(){ // je n'arrive pas avec les différents tableaux à chercher les bonnes valeurs et les associer ---------------------- ????
      foreach ($this->getPost() as $name => $value) {
     
       foreach ($this->getFunction()->getField() as $rules => $rule) { 
     
        // $this->$name = $this->{rule};  QUELQUE CHOSE COMME CELA 
     
       call_user_func_array(array($this, $rule), array($value)); // J'AIMERAIS APPELER MES METHODES SUR MES CHAMPS AVEC LEUR VALEURS - si erreur retourne False sinon retourne les valeurs (ou true ?)
       }
      }
     }
     
    }
    Je reste débutant donc je ne sais pas si ma conception est bonne. Mais bon maintenant je ne peux pas faire mieux
    l'idée est la suivante

    J'ai un objet dans lequel j'attribue mes règles à mes champs. (ici Class Functions)

    Je transfert cet objet dans le constructeur de ma Class Valid qui via une méthode validate() pourrait tester si mes champs en corrélation avec mon objet sont True ou False.

    je ne sais pas si cela est possible.

    l'idée est d'avoir une class Valid qui comporte mes méthodes de test + méthode Validate. ET des class ultérieures (une par formulaire) qui accueilleront les règles associées à mes champs

    j'espère avoir été clair

    Merci pour votre aide je m'embrouille

  5. #5
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Il y a deux ou trois semaines j’ai commencé à faire ce que tu veux faire en utilisant les closures. Mais entre temps je suis passé à autre chose.
    Je regarderai ce que j’ai fait en la matière (mais il ne faut pas s’attendre à du transcendant).

  6. #6
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut
    Merci
    Je vais regarder en attendant les closures pour apprendre et comprendre je l’espere

  7. #7
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Voici un exemple avec des closures. ATTENTION. Ce n'est pas un produit fini.

    validate.class.php
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    <?php
    class Validate
    {
     private $fieldArrayOfControls  = array();
     private $arrayOfData           = array();
     private $ruleNumber            = 0;
     
     public function addControl($errorMessage,$arrayOfFieldNames, $control)
     {
      $this->fieldArrayOfControls[$this->ruleNumber] = [$errorMessage,$arrayOfFieldNames,$control];
      $this->ruleNumber++;
     }
     
     
     public function control($arrayOfData)
     {
      $results = array();
     
      foreach($this->fieldArrayOfControls as $ruleNumber => $data)
      {
       // init pour traitement champs manquants
       $arrMissing    = array();
       $missingFields = false;
       // préparation du message en sortie
       $message     = $data[0];
       // constitution des paramètres de la fonction de closure
       $arrayToMap   = array();
       $fieldNames   = $data[1];
       foreach($fieldNames as $key => $fieldName)
       {
        if (! isset($arrayOfData[$fieldName]))
        {
         // champ manquant
         $missingFields = true; 
         $arrMissing[]  = $fieldName;
        }
        else 
        {
         $fieldValue   = $arrayOfData[$fieldName];
         $arrayToMap[] = $fieldValue;
         // message en sortie
         $message      = str_replace("#$fieldName",$fieldValue,$message);     
        }
       }
       if (!$missingFields)
       {
        // Pas de champ manquant => exécution de la closure
        $function           = $data[2];
        $results[$message]  = array_map($function, [$arrayToMap])[0];     
       }
       else
       {
        foreach($arrMissing as $missingField)
        {
         $results["*** Missing field '$missingField'"] = false;
        }
       }
     
      }
      return $results;
     }
    }

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    <?php
    include("validate.class.php");
    //==============================================================================
    //-------------- closures - les fonctions renvoient true ou false
    //==============================================================================
    // controle qu'un champ est rempli
    $remplissage = function($array) {
     $valeur = $array[0];
        return (!empty($valeur)) ? true : false;
    };
    // exemple de contrôle combiné => controle les valeur des 2 champs options
    $controleOption = function($array)
    {
     list($option1,$option2) = $array;
     if ($option1==$option2)
     {
      return false;
     }
     return true;
    };
    // contrôle qu'une valeur est numérique
    $numerique = function($array)
    {
     $valeur = $array[0];
     return (is_numeric($valeur)) ? true : false;
    };
    //==============================================================================
     
    $toto = new Validate();
    $toto->addControl('Le nom n\'est pas renseigné',["nom"], $remplissage);
    $toto->addControl('Le prénom n\'est pas renseigné',["prenom"], $remplissage);
    $toto->addControl("L'âge n'est pas renseigné",["age"], $remplissage);
    $toto->addControl("L'âge n'est pas numérique => #age",["age"], $numerique);
    $toto->addControl("Les deux options ne peuvent avoir la même valeur => option 1 = #option1 et option 2 = #option2",["option1","option2"], $controleOption);
    //+++++++++++++++++++++++++++++++++++++++++++++
    //-------------- j'ai mis ce nom au tableau mais on peut fort bien passer $_POST s'il est renseigné. 
    //               On peut mettre n'importe quel tableau du moment que ses postes sont "nommés"
    // problème sur les options
    $valeurAController = ['nom'=>'Dupont','prenom'=>'Pierre','age'=>25,'option1'=>'oui','option2'=>'oui'];
    $result = $toto->control($valeurAController);
    // on parcourt les résultats qui ont retourné faux pour afficher le message d'erreur.
    foreach($result as $message => $result)
    {
     if (! $result)
     {
      print "$message<br/>";
     }
    }
    //+++++++++++++++++++++++++++++++++++++++++++++
    print "<hr/>";
    // problème sur le nom l'âge et les options
    $valeurAController = ['nom'=>'','prenom'=>'Pierre','age'=>'AZ','option1'=>'oui','option2'=>'oui'];
    $result = $toto->control($valeurAController);
    foreach($result as $message => $result)
    {
     if (! $result)
     {
      print "$message<br/>";
     }
    }
    //+++++++++++++++++++++++++++++++++++++++++++++
    print "<hr/>";
    // problème sur le nom l'âge qui manque et les options
    $valeurAController = ['nom'=>'','prenom'=>'Pierre','option1'=>'oui','option2'=>'oui'];
    $result = $toto->control($valeurAController);
    foreach($result as $message => $result)
    {
     if (! $result)
     {
      print "$message<br/>";
     }
    }

    Donne :

    Nom : Capture20181028001.JPG
Affichages : 664
Taille : 39,2 Ko

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. foreach à l'envers sur un objet
    Par dedis dans le forum Langage
    Réponses: 1
    Dernier message: 02/03/2011, 21h00
  2. [JSTL] Faire un forEach sur un objet pour construire un select
    Par weed dans le forum Taglibs
    Réponses: 7
    Dernier message: 19/10/2008, 17h09
  3. pointeur multiple sur un objet
    Par Arnaud-h dans le forum C++Builder
    Réponses: 9
    Dernier message: 02/06/2004, 11h33
  4. [debutant] Contraintes d'intégrité définies sur un objet
    Par maysa dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/05/2004, 14h57
  5. Requêtes : recherche de maxi sur plusieur Objet
    Par pertuis dans le forum Langage SQL
    Réponses: 6
    Dernier message: 08/03/2004, 15h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo