Composition de requête avec PDO
Bonjour,
J'ai une fonction de requête avec PDO. Les critères de requêtes proviennent d'un formulaire. Je n'ai pas voulu alourdir en mettant le code du formulaire mais si vous en avez besoin, je vous le donnerai.
J'ai deux soucis:
- La valeur 0 lorsqu'elle est toute seule n'est pas prise en compte dans le code postal ce qui est gênant pour les pays où les codes postaux sont affectés géographiquement.
- Les critères de sélection de plage (min et max) ne fonctionnent pas. Si l'un des deux critères est renseigné le résultat de la requête est vide.
Voici la fonction de traitement du formulaire:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function thisFilter() {
$_POST = array_map('strip_tags', $_POST);
$criteria = empty($_POST) ? []: $_POST;
// Elimination des champs qui ne sont pas des critères de sélection
foreach ($criteria as $key=>$value) {
if (in_array($key, ['filter', 'home'])) unset($criteria[$key]);
}
unset($key, $value);
// Suppression des critères vides
foreach ($criteria as $key=>&$value) {
if ( empty($criteria[$key]) ) { unset($criteria[$key]); }
}
return getAddresses($criteria);
} |
Et la composition de la requête:
Code:
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
| function getAddresses($criteria = []) {
global $db, $language;
$countryCol = $language.'_name';
$select = "
SELECT a.id, nom, prenom, $countryCol AS pays, cp, ville,
courriel, tel_domicile, tel_portable
FROM dat_addresses a
LEFT JOIN lst_countries c
ON a.pays=c.id
";
// Composition de la clause WHERE et du tableau des paramètres
print_r($criteria); echo '<br/>';
$addClauses[0] = "id_user=:id_user";
$params['id_user'] = $_SESSION['user']['id_user'];
if ($criteria) {
if ( !empty($criteria['min']) and empty($criteria['max']) ) {
$criteria['max'] = '%';
}
if ( !empty($criteria['max']) and empty($criteria['min']) ) {
$criteria['min'] = '_';
}
if ( isset($criteria['min'], $criteria['max']) ) {
$addClauses[] = "nom BETWEEN :min AND :max";
$params['min'] = $criteria['min'];
$params['max'] = $criteria['max'];
}
if ( !empty($criteria['pays']) ) {
$addClauses[] = "pays=:pays";
$params['pays']= $criteria['pays'];
}
if ( !empty($criteria['cp']) ) {
$addClauses[] = "cp LIKE :cp";
$params['cp']= $criteria['cp'].'%';
}
if ( !empty($criteria['ville']) ) {
$addClauses[] = "ville LIKE :ville";
$params['ville']= $criteria['ville'].'%';
}
print_r($addClauses); echo '<br/>';
}
$strWhere = "WHERE " . implode(' AND ', $addClauses);
// Requête globale
$query = $select . $strWhere . " ORDER BY nom, prenom";
echo $query, '<br/>';
print_r($params); echo '<br/>';
// Traitement
$result = $db->prepare($query);
$result->execute($params);
return $result->fetchAll();
} |
Bilan provisoire de cette discussion
Je fais un bilan de cette discussion depuis #8.
Tout d'abord merci pour l'aide que vous m'avez apportée. J'ai testé entièrement le code proposé par rawsrc.
Ma question est résolue à 80% (4 critères sur 5) puisque j'ai toujours un problème avec la borne de fin (champ 'max'). Voir aussi #10. La valeur saisie dans ce champ n'est pas prise en compte dans la plage de résultats malgré le '=' de '<='. :aie:
J'ai appris à utiliser les fonctions array_diff et array_filter même si j'ai encore des difficultés avec les fonctions de rappel. Si j'ai bien compris, le paramètre de la fonction de rappel, représente tour à tour chacun des éléments du tableau. Est-ce bien cela?
Ton code comporte une erreur à la dernière ligne ($exec est un booléen).
Si quelqu'un pouvait m'aider à résoudre le point restant ce serait super.
EDIT: J'ai provisoirement résolu ce dernier point en ajoutant le dernier caractère de la table ASCII (254) à la variable $values['max'] mais c'est du bricolage et je ne sais pas ce que cela peut donner avec l'encodage UTF-8.