web-dev-qa-db-fra.com

Entrée filtrant un tableau d'entiers, mots

C’est un problème qui m’a posé des problèmes depuis plusieurs années - Joomla a fourni JRequest, puis JInput pour accéder aux données filtrées à partir de la demande entrante. Vous pouvez demander des chaînes filtrées, des entiers, des mots, etc. Vous pouvez également demander un tableau (soit en utilisant simplement getVar avec le nom de la variable et en supposant/vérifiant que la valeur renvoyée est un tableau, ou en forçant le sujet en fournissant un quelques paramètres supplémentaires à cela).

Mais vous ne pouvez pas demander un tableau d'entiers, mots, etc.

Est-ce que je manque quelque chose?

Par exemple, mes données POST pourraient inclure:

stuff[abc]=1
stuff[def]=75
stuff[123]=<script src="http://imanaughtysite.com/muahahaha.js"/>

Comment puis-je demander à JInput '' stuff '' sous forme de tableau d'entiers?

6
John Rix

OK, regardons quelles options sont disponibles. Les exemples ci-dessous utilisent JInput et ont été testés dans Joomla 3.3.

Je suis publiant les données suivantes sur Joomla:

stuff[abc]=1
stuff[def]=75
stuff[123]=<script src="http://imanaughtysite.com/muahahaha.js"/>

Je veux obtenir un tableau propre de nombres entiers, donc le résultat attendu est:

$expectedResult = array(
    'abc' => 1,
    'def' => 75,
    '123' => 0,
);

Option 1 - JInput :: get () avec le filtre ARRAY

$a1 = $app->input->get('stuff', array(), 'ARRAY');

Résultat:

array (size=3)
  'abc' => string '1' (length=1)
  'def' => string '75' (length=2)
  123 => string '<script src="http://imanaughtysite.com/muahahaha.js"/>' (length=54)

BAD IDEA - Comme vous pouvez le constater, nous obtenons nos données, mais elles ne sont ni filtrées ni nettoyées!

Option 2 - JInput :: getArray () sur post

$a2 = $app->input->post->getArray();

Résultat:

array (size=1)
  'stuff' => 
    array (size=3)
      'abc' => string '1' (length=1)
      'def' => string '75' (length=2)
      123 => string '' (length=0)

Nous avons maintenant le tableau entier POST, nettoyé. Mais il s’agit de plus d’informations que nous voulions et il ne s’agit toujours pas d’un tableau d’entiers.

Option 3 - JInput :: getArray () spécifiant les paramètres attendus et leur filtre respectif:

$a3 = $app->input->getArray(array(
    'stuff' => array(
        'abc' => 'INT',
        'def' => 'INT',
        '123' => 'INT'
    )
));

Résultat:

array (size=1)
  'stuff' => 
    array (size=3)
      'abc' => int 1
      'def' => int 75
      123 => int 0

C'est en fait la première version qui fournit ce dont nous avons besoin. Nous pouvons spécifier individuellement le filtre et obtenir le résultat. stuff doit être extrait du tableau résultant et avec une fonction PHP comme array_values _ nous pouvons également extraire uniquement les valeurs, en réinitialisant les clés.

Option 4 - Amélioration de JInput :: getArray ()

Bien que l'option 3 puisse bien fonctionner, il existe certains problèmes:

  • Que se passe-t-il si nous ne connaissons pas à l’avance le nom des champs?
  • Et si j'ai plus de 100 champs, je ne veux pas écrire chacun d'eux

Pour résoudre ce problème, nous devons le faire en plusieurs étapes:

// Get the data unfiltered
$unfilteredData = $app->input->get('stuff', array(), 'ARRAY');

// Pre-filling all parameters with the INT filter.
$a4 = $app->input->getArray(array(
    'stuff' => array_fill_keys(array_flip($unfilteredData), 'INT')
));

Le résultat est:

array (size=1)
  'stuff' => 
    array (size=4)
      'abc' => int 1
      'def' => int 75
      123 => int 0

Problème de sécurité possible si vous avez besoin des clés: nous filtrons les valeurs, mais pas les clés!

Quelques traitements simples:

$finalArray = array_values($a4['stuff']);

array (size=4)
  0 => int 1
  1 => int 75
  2 => int 0

REPONSE IS ICI: -> Code complet pour obtenir un tableau avec n-paramètres sous forme d'entiers à partir d'une demande POST (convient idéalement ceci dans une méthode):

// Get the data unfiltered
$unfilteredData = $app->input->get('stuff', array(), 'ARRAY');

// Check to see if array is empty.
if (! empty($unfilteredData))
{
    $a4 = $app->input->getArray(array(
        'stuff' => array_fill_keys(array_flip($unfilteredData), 'INT')
    ));

    $result = array_values($a4['stuff']);
}
else
{
    $result = array();
}
7
Valentin Despa

Joomla ne prend pas en charge plusieurs types en tant que filtres.

Cela ne peut être fait ni avec JRequest ni avec JInput.

Aucune solution de contournement n'est disponible dans Joomla jusqu'à présent. Vous devez gérer plusieurs filtres dans votre code uniquement.

7
Nick

Vous ne manquez certainement pas quelque chose. Si vous constatez que vous le faites régulièrement, vous pouvez créer un plug-in système pour étendre la classe JRequest existante et ajouter un nouveau type de filtre à celle-ci.

4
Jeremy Proffitt