8791 sujets

Développement web côté serveur, CMS

Bonsoir à tous,

Avant d'exécuter une requête SQL, je cherche à faire en sorte qu'elle ne s’exécute que si le $_GET['key'] est compris entre 1 et le nombre maximum de lignes présentes dans la table ville. En effet, celle-ci est ammenée à souvent évoluer car certains utilisateurs peuvent ajouter des lignes à travers un CMS.

Existe-t-il une fonction SQL qui compte le nombre de lignes d'une table ?

Merci pour votre coup de pouce ! Smiley smile


require_once ('include/inc_connexion.php');

if ((isset ($_GET['key'])) AND ($_GET['key']>=1) AND ($_GET['key']< *Nb max de lignes* ))
{
$id = $_GET['key'];

$result = $bdd -> prepare('SELECT villes_nom, ville_texte FROM villes WHERE id=?') or die (print_r($bdd -> errorInfo()));
$result -> execute (array($id));

$row = $result -> fetch ();

	$nom = $row['villes_nom'];
	$texte = $row['ville_texte'];
}
else
{
?><p><a href="index.php"><?php echo 'Retour à la page d\'accueil';?></a></p><?php
exit;
}

Bonsoir,
La fonction est count(*)

Mais je pense que tu t'y prend mal. Vérifie plutôt que ta requête retourne oui ou non un résultat.
Bonsoir ,Benj,

Merci pour ta réponse.

Finalement, la fonction count() ne convenait pas car avec le CMS, l'utilisateur peut à loisir ajouter une entrée ou en supprimer. Cela créé des "trous" dans les ID.

Par exemple on peut avoir id : 1, 2,3, 8,9

Les entrées avec l'id 4, 5,6,7 ont été supprimés par l'utilisateur.

Au final, j'ai fait une requête SELECT, puis créer un array $table pour ensuite vérifier si le $_GET['key'] fait partie de l'Array. De cette façon, même si l'utilisateur bidouille URL, la page d'accueil s'affiche.


require_once ('include/inc_connexion.php');

$count = $bdd -> query ('SELECT id, villes_nom FROM villes');
while ($row = $count -> fetch ())
{
$table[$row['villes_nom']]=$row['id'];
}

$count ->closeCursor();

if ((isset ($_GET['key'])) AND (in_array($_GET['key'],$table)))
{
$id = htmlspecialchars($_GET['key']); //protection contre les injections XSS

$result = $bdd -> prepare('SELECT villes_nom, ville_texte FROM villes WHERE id=?') or die (print_r($bdd -> errorInfo()));
$result -> execute (array($id));

$row = $result -> fetch ();

	$nom = $row['villes_nom'];
	$texte = $row['ville_texte'];
}
Salut,

quel est l'intérêt de faire deux requêtes du coup? Tu peux tout faire en une seule, le WHERE id = $id est suffisant pour conditionner l'existence ou non de l'id, si l'id n'existe pas tu n'auras pas de retour et c'est fini, si ça existe et bien tu auras tes données. Cela me parait lourd la première requête, si la table villes fait des millions de ligne tu vas le sentir. Tu peux cependant vérifier que l'id donné est bien un entier.
Bon courage Smiley smile
Merci Floreo ! Effectivement je n'avais pas pensé à la lourdeur du script.

Finalement, j'ai fait ceci :


if (isset ($_GET['key']))
{
$id = htmlspecialchars($_GET['key']); //protection contre les injections XSS

$result = $bdd -> prepare('SELECT id,villes_nom, ville_texte FROM villes WHERE id=?') or die (print_r($bdd -> errorInfo()));
$result -> execute (array($id));
$row = $result -> fetch ();

$identifiant = $row['id'];

	if(isset ($identifiant))//vérifie que l'id est bien dans la table
	{

	$nom = $row['villes_nom'];
	$texte = $row['ville_texte'];
	
	}
	else 
	{
	?><p><a href="index.php"><?php echo 'Retour à la page d\'accueil';?></a></p><?php
	exit;
	}
}
else
{
?><p><a href="index.php"><?php echo 'Retour à la page d\'accueil';?></a></p><?php
	exit;
}


Le $identifiant me permet de vérifier que l'id est bien dans la table. Comme cela même si je modifie la variable $_GET dans l'URL, le script s'arrête et il s'affiche le lien Retour à la page d'accueil.
Le htmlspecialchars ne te sert à rien ici. [s]Les requêtes préparées protège déjà contre les injections xss[/s]. Comme l'indique floreo tu peut par contre vérifier l'id.

Aussi ton test de l’existence des donnée n'est pas parfait.

Voici le code :


$id = intval($_GET['key']);

$result = $bdd -> prepare('SELECT id,villes_nom, ville_texte FROM villes WHERE id=?') or die $result -> execute (array($id));
if ($result  -> fetchColumn() > 0) {
    $row = $result -> fetch ();
    $nom = $row['villes_nom'];
    $texte = $row['ville_texte'];

} else  {
    // Pas de résultat
}

Modifié par benj (05 Jan 2015 - 21:05)
Les requêtes préparées protègent des injections SQL, pas XSS (pas "directement"), à la rigueur dans ce cas avec un bindParam en précisant le type int serait encore plus sécurisé.
Oups Smiley eek , merci @floreo. J'ai lu et écrit de travers. Dur dur ce début d'année.

Bon de toute façon le htmlspecialchars n'a rien à faire ici et ne protège rien du tous.
Il sera utilisé au moment de l'affichage (echo) sur toute les données manipulées par l'utilisateur.

ok pour bindParam.
Salut à tous,

Pour information, on parle d'injection SQL dans le cas de l'altération d'une requête SQL.
Les failles XSS concernent l'altération du HTML/JS ce qui est bien différent mais tout aussi dangereux.

Voici une petite présentation rapide des principes de sécurité web :
http://fr.slideshare.net/nwx/securite-web
Bonjour à tous,

Effectivement, vous avez raison , htmlspecialchars n'avait aucun effet (j'ai fait des tests ! ). Finalement je l'ai remplacé par strip_tags qui retire bien les chevrons du code html ou JS.

Merci à Arnolem pour le lien ... j'y vais de ce pas.