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 :

propre ou pas propre ?


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité2
    Invité(e)
    Par défaut propre ou pas propre ?
    Bonjour à tous,

    J'ai besoin de conseils pour une fonction dans laquelle je fais plusieurs requêtes Mysql. Je ne trouve pas ma façon de faire très propre et voudrais avoir vos conseils pour faire quelque chose "dans les règles de l'art".

    Merci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function GetTemplateVar($ContId,$TplId){ 
    		$tab = $this->GetDb()->select("SELECT template_name,css_id FROM ".$this->__get('db_prefix')."_templates WHERE template_id =".$TplId);
    		$this->__set('css_id', $tab->css_id);
    		$tab = parent::GetDb()->select("SELECT content_id,content_name,last_modified_by,create_date,modified_date FROM ".parent::__get('db_prefix')."_content WHERE content_id =".$ContId);
    		$this->smarty->content_id = $tab->content_id;
    		$this->smarty->title = $tab->content_name;
    		$tab = parent::GetDb()->select("SELECT type,text_name,content,create_date,modified_date FROM ".parent::__get('db_prefix')."_content_text WHERE content_id = ".$ContId." and text_name like 'content_en'");
    		$this->smarty->content=$tab->content;
    		$tab=parent::GetDb()->select("SELECT css_text,media_type FROM ".$this->__get('db_prefix')."_css WHERE css_id = ".$this->__get('css_id'));
    		$this->smarty->css_text = $tab->css_text;
    		$this->smarty->css_media_type = $tab->media_type;
    		$this->GetTemplate($TplId);
    	}

  2. #2
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Hello

    Déjà commence par aérer un peu, ça facilitera la lecture même pour toi (tu verra quand tu devra reprendre le code que tu as écrit il y a 6 mois par exemple). ça vaut également pour les commentaire.
    Pense surtout à ne pas dépasser les 140 caractères (affichage intégral sur 19 pouces - les puristes C vont te dire 80 caractère mais je trouve que c'est trop peu pour PHP), cela t'évitera d'avoir l'ascenseur vertical qui rends la lecture du code pénible.

    Premier point: je ne vois nulle part la sécurisation de tes requêtes SQL. Qu'est ce qu'il se passe dans ta fonction quand une requête échoue ? ça lance des warnings ? ça part en fatal error ? Ou pire: ça fait n'importe quoi !

    Second point: tu mets des variables directement dans les requêtes. Ce n'est pas vraiment un problème si tu as le contrôle total de ces données, en revanche si elles arrivent de l'utilisateur, il vaut mieux les sécuriser pour éviter les injections.
    Cette sécurité contre les injection à été introduite par l'interface mysqli et reprise par PDO (que tout bon programmeur PHP se devrait d'utiliser sous peine d'être fouetté publiquement ) en utilisant les requêtes préparées.

    Troisième point: A aucun moment tu ne vérifie les retours de tes fonction, tu es à ce point sûr que tout marche comme sur des roulettes huilés dans le beurre ? Une légère vérification du retour de tes fonctions / méthodes serait de bon ton.
    Un exemple tout bête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaClasse::methodeDeClasse()->methodeInstance()->autreMethode();
    Il suffit qu'une seule de ses fonctions renvoie null, false ou void (ou n'importe quel autre type scalaire d'ailleurs) au lieu d'un objet et tout part en FATAL ERROR.

    Mais bon, ne dramatise pas, dans l'ensemble ton code est bien (surtout en comparaison de toutes les horreurs qu'on peut voir sur ce forum.)
    Donc pou résumer tout ça je dirais: blinde ton code et protèges-le !

  3. #3
    Invité2
    Invité(e)
    Par défaut
    Merci.
    En fait, la fonction "select()" est est une méthode d'une autre classe. Les requêtes y sont préparées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function select($query) {
    		try
            {
                $requete = $this->PDOInstance->prepare($query);
                $requete->execute();
    			$result = $requete->fetch(PDO::FETCH_OBJ);
    			return $result;
            }
            catch (Exception $e) 
            {
                //On indique par email que la requête n'a pas fonctionné.
                 error_log(date('D/m/y').' à '.date("H:i:s").' : '.$e->getMessage(), 1, 'XX@XXXXX.com');
            }
    	}
    Je récupère les données avec __get().Mais je viens d'avoir un problème assez bizarre : il a fallu que j'ajoute dans chaque constructeur de classe dérivée "parrent::__construct()" pour que cela fonctionne. Pourtant, avant que je test les possibilité de gestion des messages d'erreur php, cela fonctionnait très bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function __get($data){
    			return $this->param[$data];
    	}
    Et sinon, voilà la fameuse classe qui me pose problème après ajout de quelques verifications. Je ne vois pas quoi faire de plus... ?
    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
    public function GetTemplateVar($ContId,$TplId){ 
    		// Recuperation des differentes variables necessaires a l affichage du template.
    		$tab = $this->GetDb()->select("SELECT template_name,css_id FROM ".$this->__get('db_prefix')."_templates WHERE template_id =".$TplId);
    		if($tab)
    			$this->__set('css_id', $tab->css_id);
    		$tab = parent::GetDb()->select("SELECT content_id,content_name,last_modified_by,create_date,modified_date FROM ".parent::__get('db_prefix')."_content WHERE content_id =".$ContId);
    		if($tab) {
    			$this->smarty->content_id = $tab->content_id;
    			$this->smarty->title = $tab->content_name;
    			}
    		$tab = parent::GetDb()->select("SELECT type,text_name,content,create_date,modified_date FROM ".parent::__get('db_prefix')."_content_text WHERE content_id = ".$ContId." and text_name like 'content_en'");
    		if($tab)
    			$this->smarty->content=$tab->content;
    		$tab=parent::GetDb()->select("SELECT css_text,media_type FROM ".$this->__get('db_prefix')."_css WHERE css_id = ".$this->__get('css_id'));
    		if($tab){
    			$this->smarty->css_text = $tab->css_text;
    			$this->smarty->css_media_type = $tab->media_type;
    			$this->GetTemplate($TplId);
    			}
    	}
    Merci.

  4. #4
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Vu que je ne connais pas ton code en détail, je ne sais pas non plus ou ça coince; pars à la chasse aux erreurs, fait des traces un peut partout, utilise un débugger (www.xdebug.org).

    C'est quel genre de problème pour commencer ? Un problème de logique ? La méthode ne renvoie pas les bons résultats ? Il y a une erreur fatale ? Jannet Jackson sors un nouveau disque ?

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    772
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2004
    Messages : 772
    Par défaut
    Citation Envoyé par phpdeveloppeur Voir le message
    Merci.
    En fait, la fonction "select()" est est une méthode d'une autre classe. Les requêtes y sont préparées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function select($query) {
    		try
            {
                $requete = $this->PDOInstance->prepare($query);
                $requete->execute();
    			$result = $requete->fetch(PDO::FETCH_OBJ);
    			return $result;
            }
            catch (Exception $e) 
            {
                //On indique par email que la requête n'a pas fonctionné.
                 error_log(date('D/m/y').' à '.date("H:i:s").' : '.$e->getMessage(), 1, 'XX@XXXXX.com');
            }
    	}
    Attention, cette méthode select ne te protège pas des injections SQL !! C'est au moment où tu introduis tes variables venant de l'utilisateur dans la requête qu'il faut les échapper (avec mysql_real_escape_string notamment).

    De plus, utiliser des requêtes préparées, c'est bien, mais l'intérêt est réel pour des requêtes exécutées en boucle dans un script avec des valeurs changeantes. Dans ton cas elle ne sert à rien et ne te protège même pas des injections SQL.

    Continue sur PDO, c'est effectivement une bonne pratique, et renseigne toi sur les requêtes préparées, comment et pourquoi les utiliser. Idem pour la protection contre les injections !

  6. #6
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Attention, cette méthode select ne te protège pas des injections SQL !! C'est au moment où tu introduis tes variables venant de l'utilisateur dans la requête qu'il faut les échapper (avec mysql_real_escape_string notamment).

    De plus, utiliser des requêtes préparées, c'est bien, mais l'intérêt est réel pour des requêtes exécutées en boucle dans un script avec des valeurs changeantes. Dans ton cas elle ne sert à rien et ne te protège même pas des injections SQL.
    En effet, il faut que tu utilise des patterns de remplacement pour tes prepare statement sinon ça ne sert strictement à rien et ça ne te protège pas.
    Les requêtes préparées sont surtout utile car elles permettent de ne pas avoir à construire manuellement les requêtes, s'en servir comme tu le fais n'est pas correct.

    En revanche, si les requêtes préparées le protège des attaques par injection, elles ne protègent pas les XSS, prudence donc.

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Citation Envoyé par pc.bertineau Voir le message
    Attention, cette méthode select ne te protège pas des injections SQL !! C'est au moment où tu introduis tes variables venant de l'utilisateur dans la requête qu'il faut les échapper (avec mysql_real_escape_string notamment).
    mysql_real_escape_string avec PDO ???

    faire ca me semble plus logique, même si je vois pas pourquoi tu récupères qu'un seul résultat :
    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
    public function select($query, array $input_parameters)
    {
        try
        {
            $requete = $this->PDOInstance->prepare($query);
            $requete->execute($input_parameters);
            $result = $requete->fetchObject();
            $result->closeCursor();
     
            return $result;
        }
        catch (Exception $e) 
        {
            //On indique par email que la requête n'a pas fonctionné.
            error_log(date('D/m/y').' à '.date("H:i:s").' : '.$e->getMessage(), 1, 'XX@XXXXX.com');
        }
     
        return false;
    }

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    772
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2004
    Messages : 772
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    mysql_real_escape_string avec PDO ???
    PDO sans requête préparée ne dispense pas d'échapper les données extérieures, si ?

    Personnellement je n'utilise pas systématiquement les preparedStatement comme je l'ai expliqué plus haut. L'exemple de phpdeveloppeur montre bien qu'une requête préparée sans séparer les paramètres de la requête ne protège pas non plus des injections...

Discussions similaires

  1. Imbrication de ForEach propre ou pas ?
    Par benny-blanco dans le forum C#
    Réponses: 2
    Dernier message: 27/05/2012, 20h49
  2. valeurs propres et vecteurs propres d'une matrice
    Par Naomé dans le forum Mathématiques
    Réponses: 12
    Dernier message: 07/06/2011, 19h30
  3. valeurs propres et vecteurs propres
    Par math09 dans le forum MATLAB
    Réponses: 1
    Dernier message: 21/10/2009, 07h00
  4. valeurs propres et vecteurs propres d'une matrice
    Par galadorn dans le forum C++
    Réponses: 2
    Dernier message: 28/02/2009, 20h06
  5. Réponses: 15
    Dernier message: 18/07/2007, 14h11

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