8
votes

Comment "correctement" gérer $ _GET variables dans PHP?

Actuellement, j'ai le code suivant:

if(isset($_GET['mid']) && !empty($_GET['mid'])) {
    $mid = $_GET['mid'];

    if(is_numeric($mid) && $mid > 0) {
        if(isset($_GET['op']) && !empty($_GET['op'])) {
            $op = $_GET['op'];

            if($op == 'info') {
            }

            if($op == 'cast') {
            }
        }
    }
}


5 commentaires

Tout d'abord, rendez votre code juste sensible. si (is_numérique ($ moyenne) && $ moyenne> 0) { => si ($ MID)) , => si (! vide ($ _ obtenir [' MID '])) et ainsi de suite. Voir php.net/empty


Je ne savais pas is_numeric () renvoyé false pour 0 . L'autre que je ne connaissais pas non plus.


Ce n'est pas le cas. is_numérique () retourne true sur 0 . Vous pouvez effondrer isset () dans ! Vide () , cependant.


@Mark Trapp: Dites-le à 40% des intervenants.


IS_Numeric n'est pas mais vous avez déjà vérifié pour 0 avec vide (), donc sans $ $ MID> 0 requis


10 Réponses :


6
votes

J'écrirais une fonction qui prendrait le nom de l'index et renvoie la valeur dans $ _ obtenir ou lancez une exception.

cela, ou l'encapsuler dans une classe similaire Pour ce qui suit: xxx


5 commentaires

Pourriez-vous donner un exemple sur cette approche de classe?


assez agréable, bien qu'utiliser statique n'est pas aussi "gentil" ou réutilisable pour _post


@zanlok: Le passage d'une matrice au constructeur est laissé comme un exercice pour le lecteur.


Votre réponse n'a pas la même approche; C'est fondamentalement différent. trop défensive?


Je me demande ce qui se passerait si vous faites cela; écho get :: int ("heure") lorsque votre URL est comme; ? heure = 0



2
votes

Vous pouvez faire une fonction d'assistance: xxx

qui rendrait votre code un peu plus propre, mais que vous le codez lui-même, il est allright.


1 commentaires

Vérification si une variable isset et / ou vide est redondant. vide déjà vérifie s'il est défini.



-1
votes

Il n'y a rien de mal à cela. Imbriquée si des déclarations sont absolument bien. Vous pouvez utiliser filtre cependant.


2 commentaires

Oui, la question était davantage sur la "complexité du code" en termes de son apparence. J'ai normalement tendance à avoir des lignes aussi longtemps que 80chars et avec beaucoup d'imitation si des déclarations, le "code réel" aura peu d'espace respiratoire.


Eh bien, pour les démarreurs, vide déjà des vérifications si une variable Isset.



4
votes
  1. vide vérifie déjà si une variable isset .
  2. is_numérique est un peu verbeux, car vous vérifiez également contre 0 .
  3. Un relevé d'interrupteur est le mieux adapté pour vérifier les variables contre plusieurs valeurs de chaîne

    Je ferais ceci: xxx

    Si vous devez stocker $ € _ obtenir ['op'] dans une variable pour plus tard, vous pouvez Faites-le avant le bloc de commutation, bien que je ne voudrais pas si c'était nécessaire.


0 commentaires

2
votes

Ce que vous pouviez faire est de définir une fonction de filtrage (qui existe déjà dans PHP> = 5.2) qui filtrerait une variable basée sur un argument sur quel type il s'agit, une chaîne ou plus selon Vos exigences.

$foo = myfilter($_GET['foo'], 'numeric');
$bar = myfilter($_GET['bar'], 'alphanumeric');


1 commentaires

En fait, il existe en PHP> = 5.2



12
votes

J'utiliserais filtre_input avec le filtre filtre_sanitize_number_float pour la mi-journée. Quelque chose comme ça: xxx


2 commentaires

Cela a un problème: si _ get ['op'] contient la chaîne info , votre bloc de commutation exécutera tout le code dans chaque cas. Vous devriez ajouter des pauses.


@Mark hEhh ... n'a pas pensé à ça.



0
votes

Je ferais quelque chose comme ci-dessous. Plus ou moins. Mais vous pouvez également utiliser un filtre pour une grande partie de ces choses. Et vous pouvez également désactiver les avertissements et simplement utiliser vide () et ne vous inquiétez pas d'Isset dans le premier morceau.

function checkVar($var)
{
    if(isset($var) && !empty($var)) {
        return true;
    }
    return false;
}

function checkID($id){
    if(checkVar($id) && is_numeric($id) && $id > 0) {
        return $id;
    }
    return false; 
}

if($mid = checkID($_GET['mid'])) {
    if(checkVar($_GET['op'])) {
        switch($_GET['op']) {
            case 'info':
            break;

            case 'cast':
            break;
        }
    }
}


4 commentaires

Vérification si une variable isset et / ou non vide est redondant. vide déjà vérifie s'il est défini.


@Stephen: php.net/manual/fr/funcky.empty.php Pas selon les docs. Ce qui signifie qu'il lancerait un avertissement. Peut-être que vous avez des avertissements éteints et vous ne l'avez jamais vu.


Tsk. Tsk. Vérifiez vos faits. Ceci est à partir de la page que vous avez référencée: "vide () est le contraire de (booléen) var, sauf qu'aucun avertissement n'est généré lorsque la variable n'est pas définie."


Ensuite, quelqu'un devrait ajouter cela à la liste des conditions de valeur de retour. Parfois, je déteste vraiment la documentation incompatible de PHP. Mais pas besoin d'être snotty.



0
votes

Il semble un peu complexe. Mais il semble que vous souhaitiez tester une énormément de conditions de pointe. Cependant, il existe des moyens d'unifier le processus. J'utilise un classe wrapper pour cela:

if ($_GET->int["mid"]) {
if ($_GET->in_array("op", "info,cast")) {


4 commentaires

Qui surcharge le $ _ obtenir superglobal? Pas gentil!


@Stephen: ça fait. La sémantique est proche. Mais si vous aimez la complexité, vous pouvez également définir des objets wrapper: $ getvars = nouvelle entrée ($ _ obtenir) yikes.


Je ne sais pas pourquoi cela a été évité. Je ne suis peut-être pas d'accord avec la mise en œuvre recommandée, mais c'est toujours une stratégie valide. +1 pour l'équilibre.


@Stephen: J'aurais peut-être pu la descendre aussi, car c'est un peu trop excédant pour ce que veut. Mais c'est une option néanmoins et simplifie effectivement les choses - une fois que vous êtes ami ou prolongé l'API.



3
votes

J'aime l'idée de créer une classe Inputfilter qui implémente ArrayAccess. Ceci est plus orienté objet et plus personnalisable, car vous pouvez ajouter des méthodes à caprice pour la personnalisation et travailler avec le même objet filtrant principal.

<?php

// empty for now, fill in later if desired
class InputFilterException extends Exception {}

/*
 * Use the ArrayAccess interface as a template.
 *
 * Usage examples:
 *    $controller->get = InputFilter($_GET);
 *    echo $controller->get->value_string_html('variable');
 *    $controller->post = InputFilter($_POST);
 *    echo $controller->get->value_integer('variable');
 */
class InputFilter implements ArrayAccess {

    protected $data;

    function __construct( $data ) {
        if( !is_array($data) ) {
            throw new InputFilterException ("Only arrays are allowed here");
        }
        $this->data = $data;
    }

    // do not actually use these
    function __get( $offset ) {
        throw new InputFilterException( "Don't use as an array, use functions ->string() ->int() etc: ['" . $offset . "']" );
    }
    function __set( $offset, $value ) {
        throw new InputFilterException( "Don't modify directly: ['" . $offset . "'] = \"" . $value . "\"" );
    }

    // implement ArrayAccess

    function offsetExists( $offset ) {
        return isset( $this->data[$offset]) );
    }

    function offsetSet( $offset, $value ) {
        $this->data[$offset] = $value;
    }

    function offsetUnset( $offset ) {
        unset( $this->data[$offset] );
    }

    function offsetGet( $offset ) {
        throw new InputFilterException ("Don't use this object as an array, but were an array : ". $offset);
    }

    protected function getValue( $offset ) {

        if( is_array($this->data[$offset]) ) {
            throw new InputFilterException ("must use the asArray() function");
        }
        return $this->data[$offset];
    }

    function data_count() {
        return count($this->data);
    }

    public function set_value( $offset, $data ) {
        $this->offsetSet( $offset, $data );
    }

    // get an array *in* the data
    public function asArray($offset) {

        if( !is_array ($this->data[$offset]) ) {
            throw new InputFilterException("only use asArray() for arrays");
        }
        return new Filter( $this->data[$offset] );
    }

    // validators...

    function is_set( $offset ) {
        return $this->offsetExists($offset);
    }

    function is_empty( $offset ) {
        return $this->is_set($offset) && strlen($this->data[$offset]) == 0;
    }

    function is_numeric( $offset ) {
        return $this->is_set($offset) && is_numeric($this->data[$offset]);
    }

    function is_integer( $offset ) {

        if( !$this->is_set($offset) ) {
            return false;
        } elseif( is_numeric($this->data[$offset]) ) {
            $int_value = intval($this->data[$offset]);
            return $int_value == $this->data[$offset];
        } elseif( strlen($this->data[$offset]) == 0 ) {
            return true;
        }
        return false;
    }

    function is_array( $offset ) {
        return $this->is_set($offset) && is_array($this->data[$offset]);
    }

    // return data formatted

    function value_string( $offset ) {
        return $this->getValue($offset);
    }

    function value_string_html( $offset ) {
        return htmlentities( $this->getValue($offset), null, 'UTF-8' );
    }

    function value_integer( $offset ) {
        return intval( trim($this->getValue ($offset)) );
    }

    function value_numeric( $offset ) {
        return doubleval($this->getValue ($offset));
    }

    function value_alphanumeric( $offset ) {
        return preg_replace("*[^A-Za-z0-9]*", "", $this->getValue ($offset));
    }

    function value_unfiltered( $offset ) {
        return $this->getValue( $offset );
    }

}

?>


0 commentaires

0
votes

J'aime cette approche suivante pour les variables entière: xxx


0 commentaires