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 :

mettre un paramètre dans une classe


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 493
    Billets dans le blog
    1
    Par défaut mettre un paramètre dans une classe
    Bonjour,

    je ne voudrais pas dupliquer mon code ; hors dans celui-ci, il y a une définition de classe qui peut varier par le nom de la bdd ; le reste de la définition de la classe est identique donc je voudrais le factoriser mais ne sais pas le faire ; peut-on m'aider ?

    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
    <?php
     
    class MyPdo extends PDO {
     
    	static public $DB_NAME = nom_de_bdd_variable;
     
    	static public $HOST = "localhost";
     
    	static public $USER ="root";
     
    	static public $PASS ="root";
     
     
     
    //  le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
    	function __construct() {
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
    	parent::__construct('mysql:host=' . MyPdo::$HOST . ';dbname=' . MyPdo::$DB_NAME, MyPdo::$USER,MyPdo::$PASS, $pdo_options);
    	}
     
    }

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Par défaut
    - Enlèves les attributs static, tu n'en as pas besoin.
    Argh. Je sens que tu nous fais une singleton, là. C'est complèment inutile en PHP, et à utiliser avec précaution en Programmation Orientée Objet.

    Il y a une littérature abondante sur Internet si tu veux savoir pourquoi un Singleton n'est pas la meilleure solution dans beaucoup de cas, et tout particulièrement en PHP. N'utilise pas un singleton à moins que tu ne sois absolument sûr de tes raisons.

    Quand à la solution, c'est simple:
    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
    <?php
     
    class MyPdo extends PDO {
     
    	protected $DB_NAME;
     
    	protected $HOST = "localhost";
     
    	protected $USER ="root";
     
    	protected $PASS ="root";
     
     
     
    //  le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
    	public function __construct($db_name) {
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
            $this->DB_NAME = $db_name;
     
    	parent::__construct('mysql:host=' . $this->HOST . ';dbname=' . $this->DB_NAME, $this->USER, $this->PASS, $pdo_options);
    	}
     
    }

  3. #3
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 493
    Billets dans le blog
    1
    Par défaut
    Je connais un peu la poo mais connaissais pas le concept de singleton ; apparemment, c'est une classe à instance unique ; or dans mon cas, il y a 2 instances (puisqu'il y a 2 bdd). D'autre part, j'ai pas trouvé de littératures déconseillant cela en PHP : tu as un lien ?

    J'ai un peu modifié le code en prenant en compte ta proposition + d'autres idées, mais pas encore bon :

    class_MyPdo.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
    <?php
    error_reporting(E_ALL ^ E_DEPRECATED ^ E_NOTICE);
    ini_set('display_errors','1'); 
     
     
     
    // MyPDO
     // ls : la classe MyPdo hérite de la classe PDO (extends)
    class MyPdo extends PDO {
     
    	protected $HOST = "localhost";
     
    	protected $USER ="root";
     
    	protected $PASS ="root";
     
    	//protected $DB_NAME="";
     
     
     
    // ls : le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
    	function __construct($db_name) {	
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
    	parent::__construct('mysql:host=' . MyPdo::$HOST . ';dbname=' . $db_name, MyPdo::$USER,MyPdo::$PASS, $pdo_options);
     
    	}
     
    }
    ?>
    MyPdo.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php
    include("class_MyPdo.php");
    ?>
    MyPdo_planning.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php
    include("class_MyPdo.php");
    ?>

    connect_mysql.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    include_once (dirname(__DIR__).'\\eis\new\MyPdo.php');
    header('Content-type: text/html; charset=UTF-8');
    //// connexion
    try{
    				$bdd = new MyPdo("su_dev_eis");
      }
    catch(PDOException $e){
    				echo "argggggggggggggg".$e->getMessage();
    				return(FALSE);
    			}		
    ?>

    connect_mysql_planning.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    include_once (dirname(__DIR__).'\\eis\new\MyPdo_planning.php');
    header('Content-type: text/html; charset=UTF-8');
    //// connexion
    try{
    				$bdd_planning = new MyPdo("planning_dev");
    			}
    catch(PDOException $e){
    				echo "argggggggggggggg".$e->getMessage();
    				return(FALSE);
    			}
    ?>

    qu'en penses-tu ?

    [EDIT du 18/07 19:45]je viens de m'apercevoir que j'avais oublié de mettre le message d'erreur :
    Fatal error: Access to undeclared static property: MyPdo::$HOST in C:\wamp\www\devjupiter_serveur291214\eis\new\class_MyPdo.php on line 29

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Par défaut
    En PHP, en Java, en C# ou ailleurs, un Singlketon est toujours à utiliser avec beaucoup de précautions, et uniquement quand on sait très bien les conséquences qui en découlent.
    Quelques liens (désolé, je n'ai pas de liens en français. Pour faire court, ça introduit un état global dans l'application (or on sait que quelque chose qui est global est mauvais, cf. variables globales; et qu'un état doit être avoir la portée la plus petite possible pour éviter d'entraîner des cascades de problèmes et donc des bugs difficiles à identifie); c'est contraire au principe de responsabililité unique (le S de SOLID), ça rend impossible la séparation des codes, or c'est l'un des principes de base de la POO (et accessoirement ça rend le code impossible à tester); et en PHP plus spécifiquement ça n'apporte pas grand chose car tout est détruit de toutes façon une fois la requête traitée par le serveur. Le singleton est donc régénéré à chaque nouvelle requête, or son principal intérêt c'est de ne créer un objet qu'une seule fois.

    Quant au code, tu n'as pas fait ce que je t'ai dit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parent::__construct('mysql:host=' . $this->HOST . ';dbname=' . $this->DB_NAME, $this->USER, $this->PASS, $pdo_options);
    Une fois les attributs static enlevés, tu dois utiliser $this-> pour accéder aux propriétés, et non "::"

  5. #5
    Membre Expert
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 493
    Billets dans le blog
    1
    Par défaut
    Désolé de ne pas avoir bien suivi tes conseils ; j'avais zappé.

    Maintenant, je pense les suivre :
    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
    <?php
    error_reporting(E_ALL ^ E_DEPRECATED ^ E_NOTICE);
    ini_set('display_errors','1'); 
     
     
     
    // MyPDO
     // ls : la classe MyPdo hérite de la classe PDO (extends)
    class MyPdo extends PDO {
     
    	protected $DB_NAME;
     
    	protected $HOST = "localhost";
     
    	protected $USER ="root";
     
    	protected $PASS ="root";
     
     
     
    // le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
    	function __construct($db_name) {	
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
    	$this->$DB_NAME = $db_name;
     
    	parent::__construct('mysql:host=' . $this->$HOST . ';dbname=' . $this->$DB_NAME, $this->$USER,$this->$PASS, $pdo_options);
     
    	}
     
    }
    et j'ai encore un message d'erreur que je ne comprends pas :
    Fatal error: Cannot access empty property in C:\wamp\www\devjupiter_serveur291214\eis\new\class_MyPdo.php on line 29
    Sinon, dans mon cas, vu qu'il y a 2 instances (2 tables) tu es d'accord qu'il n'y a pas de singleton ?
    Sinon je comprends pas ça
    or on sait que quelque chose qui est global est mauvais
    Je comptais faire des 2 objets MyPDO 2 variables globales pour qu'elles soient accessibles de partout, une fois créées (une seule fois) : pas bon ?

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Par défaut
    Il faudrait que tu sois plus attentif ou que tu saches mieux interpréter les messages d'erreurs.

    Regarde bien, il y a des différences entre mon exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public function __construct($db_name) {
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
            $this->DB_NAME = $db_name;
     
    	parent::__construct('mysql:host=' . $this->HOST . ';dbname=' . $this->DB_NAME, $this->USER, $this->PASS, $pdo_options);
    	}
    et ton implémentation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function __construct($db_name) {	
    	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
    	$this->$DB_NAME = $db_name;
     
    	parent::__construct('mysql:host=' . $this->$HOST . ';dbname=' . $this->$DB_NAME, $this->$USER,$this->$PASS, $pdo_options);
     
    	}
    Pour être plus clair:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->DB_NAME = $db_name;
    est différent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->$DB_NAME = $db_name;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parent::__construct('mysql:host=' . $this->HOST . ';dbname=' . $this->DB_NAME, $this->USER, $this->PASS, $pdo_options);
    est différent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parent::__construct('mysql:host=' . $this->$HOST . ';dbname=' . $this->$DB_NAME, $this->$USER,$this->$PASS, $pdo_options);
    Est-ce que tu utilises un IDE? un IDE te signalerait immédiatement ce genre d'erreur (comme la coloration syntaxique de developpez.net te montre immédiatement les différences entre les codes).

    Sur les globales: le principe même de la POO est de subdiviser un programme en petites unités indépendantes qui communiquent entre elles. L'existence des variables globales casse cette indépendance: toutes les unités deviennent dépendantes de cette variable globale.
    Imagine qu'il y ait un bug dans une variable. Si elle est locale, ce bug n'affectera que l'unité (fonction, méthode, classe) qui la contient. Le bug est donc facile à trouver et à corriger: il suffit de regarder la fonction, méthode ou classe qui contient cette variable. Le problème est plus compliqué pour une variable globale: n'importe quelle partie de ton programme peut modifier ou supprimer cette variable. En cas de bug, l'investigation doit donc porter sur tout le programme, et non sur une simple fonction/méthode/classe. Bonne chance à toi si ton programme comporte des centaines de classes et de fichiers...

    Bref, sur un programme simple, qui tient en deux-trois fichiers, l'utilisation de variables globales est mauvaise mais n'est pas catastrophique; mais si tu comptes progresser et avoir des programmes plus larges un jour, mieux vaut se débarasser de cette mauvaise habitude.

    Attention: tout ceci est valable si tu écris Orienté Objet, ç'est-à-dire si tu organises tout ton code en classes non statiques. Si tu écris en procédural, même si tu utilises des objets, c'est moins important.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/01/2010, 17h33
  2. peut on mettre du javascript dans une classe css
    Par aléatoire dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 21/08/2009, 20h34
  3. Comment mettre ce code dans une classe ?
    Par oranocha dans le forum Langage
    Réponses: 2
    Dernier message: 16/07/2008, 14h51
  4. Passer un paramètre dans une classe
    Par soso78 dans le forum VB.NET
    Réponses: 1
    Dernier message: 27/05/2008, 08h03
  5. Réponses: 2
    Dernier message: 27/03/2005, 16h09

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