Le code HTML contient quelques erreurs et le formulaire utilisé pour rechercher des campings ne soumet aucune donnée, probablement en raison de certaines erreurs dans le code HTML. Un ul
l'élément peut avoir li
éléments comme enfants uniquement - mais ceux li
les éléments peuvent avoir un autre contenu (généralement pas la meilleure façon de le faire à l'OMI dans ce cas) et former des éléments d'entrée de n'importe quel type doivent avoir un attribut de nom et généralement une valeur. Dans le cas du formulaire de réservation fire
,electric
et sewer
doit être nommé comme tel avec une valeur de 1 (voir question précédente). Les sélecteurs de date doivent avoir des noms, donc au lieu d'un ID ou en plus, nommez-les startdate
et enddate
car le script php les attend dans le tableau POST.
Si le formulaire a réussi à soumettre les données et que la requête sql s'est déroulée correctement, où les résultats apparaîtraient-ils ? Je peux voir que l'action du formulaire est includes/reserve.inc.php
qui est la deuxième partie du code ( PHP ) mais qui ne produit aucun contenu.
La modification du code HTML dans le navigateur pour ajouter des attributs aux différents éléments du formulaire et la modification de leurs valeurs avant de soumettre le formulaire ont généré les paramètres POST suivants sur la page en direct...
startdate=01%2F03%2F2018&enddate=01%2F17%2F2018&fire=1&electric=1&sewer=1&submit1=
Alors qu'avant seul le submit1
apparaissait. Cependant, aucun résultat n'a été renvoyé.
Comme vous avez déjà jQuery
sur la page pour diverses tâches, peut-être que la chose à faire serait d'utiliser ajax pour POSTER les données sur le script PHP backend et d'utiliser le rappel pour ajouter le contenu HTML à la page actuelle ? Certainement quelque chose à penser peut-être.
<?php
@session_start();
require_once("includes/dbh.inc.php");
?>
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#login-trigger').click(function(){
$(this).next('#login-content').slideToggle();
$(this).toggleClass('active');
if ($(this).hasClass('active')) $(this).find('span').html('▲')
else $(this).find('span').html('▼')
})
});
$(document).ready(function(){
$('#reserve-trigger').click(function(){
$(this).next('#reserve-content').slideToggle();
$(this).toggleClass('active');
})
});
$('#reserve-trigger').on('focusout', function () {
$(this).toggleClass('active');
});
$('#login-trigger').on('focusout', function () {
$(this).toggleClass('active');
});
</script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js">
<script>
$(document).ready(function() { $("#startdate").datepicker(); });
$(document).ready(function() { $("#enddate").datepicker(); });
</script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<header>
<div class='container'>
<div id='branding'>
<h1><span class='highlight'>Whispering</span> Winds Park</h1>
</div>
<nav>
<ul>
<li class='current'><a href='index.php'>Home</a></li>
<li><a href='mission.php'>Our Mission</a></li>
<li><a href='donate.php'>Donate</a></li>
<li><a id='reserve-trigger' href='#'>Camping</a>
<div id='reserve-content' tabindex='-1'>
<form action='includes/reserve.inc.php' method='POST'>
<fieldset>
<!--
child elements of a `ul` should be `li` only
so you required a few more `<li></li>` around
certain items here
Form input elements require a name attribute and a type for the datepickers
-->
<ul>
<li><input type='text' id='startdate' name='startdate' placeholder='Start Date' /></li>
<li><input type='text' id='enddate' name='enddate' placeholder='End Date'/></li>
<!--
The checkboxes require a name attribute otherwise they will not appear
in the POST array data. Set the value to `1` as it is a bit stored in
the db anyway
-->
<li><label for='fire'>Fire Pit: </label><input type='checkbox' name='Fire' value=1></li>
<li><label for='electric'>Electricity: </label><input type='checkbox' name='Electric' value=1></li>
<li><label for='sewer'>Sewage: </label><input type='checkbox' name='Sewer' value=1></li>
<li><button type='submit' class='button3' name='submit1'>Find a Reservation</button></li>
</ul>
</fieldset>
</form>
</div>
</li>
<!-- /*login button*/ -->
<?php
if( isset( $_SESSION["u_uid"] ) ) {
echo '
<li>
<form action="includes/logout.inc.php" method="POST">
<button type="submit" class="button_1" name="Submit">Logout</button>
</form>
</li>';
} else {
echo
'<li id="login">
<a id="login-trigger" href="#">
<button class="button_1">Log in <span>▼</span></button>
</a>
<div id="login-content" tabindex="-1">
<form action="includes/login.inc.php" method="POST">
<fieldset id="inputs">
<input type="text" name="uid" placeholder="Username" required>
<input type="password" name="pwd" placeholder="Password" required>
<button type="submit" class="button3" name="Submit">Log In</button>
</fieldset>
</form>
</div>
</li>
<li id="signup">
<a href="signup.php"><button class="button_1">Sign up</button></a>
</li>';
}
if( isset( $_SESSION["u_admin"] ) ) {
echo '
<li id="signup">
<a href="admin.php"><button class="button_1">Admin</button></a>
</li>';
}
?>
</ul>
</nav>
</div>
</header>
</body>
</html>
Passons au script backend.
Avez-vous des tables nommées campsite
et campsites
? Les instructions sql ont toutes des variables intégrées qui, malgré l'utilisation de mysqli_real_escape_string
, laisse votre code potentiellement vulnérable à l'injection SQL, vous devez donc utiliser des prepared statements
chaque fois que vous utilisez une entrée fournie par l'utilisateur. Il suffit d'un champ qui peut être exploité pour compromettre l'ensemble du système ! Je ne pouvais pas tout à fait suivre une partie de la logique avec ce qui se passait là-bas (pas assez de caféine probablement encore), donc ce qui suit peut être loin de la marque
<?php
session_start();
/* Prevent direct access to this script in the browser */
if ( realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
/* could send a 403 but Not Found is probably better */
header( 'HTTP/1.0 404 Not Found', TRUE, 404 );
die( header( 'location: /index.php' ) );
}
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['submit1'], $_POST['startdate'], $_POST['enddate'], $_POST['fire'], $_POST['electric'], $_POST['sewer'] ) ) {
if ( empty( $_POST['startdate'] ) || empty( $_POST['enddate'] ) ) {
exit( header( 'Location: ../index.php?index=empty_dates' ) );
}
/* results from search query will be stored in this array for later use */
$output=array();
require_once('dbh.inc.php');
/*
Do startdate and enddate need to be session variables???
*/
$startdate = filter_input( INPUT_POST,'startdate',FILTER_SANITIZE_SPECIAL_CHARS );
$enddate = filter_input( INPUT_POST,'enddate',FILTER_SANITIZE_SPECIAL_CHARS );
$fire = filter_var( filter_input( INPUT_POST,'fire', FILTER_SANITIZE_NUMBER_INT ), FILTER_VALIDATE_INT );
$electric = filter_var( filter_input( INPUT_POST,'electric', FILTER_SANITIZE_NUMBER_INT ), FILTER_VALIDATE_INT );
$sewer = filter_var( filter_input( INPUT_POST,'sewer', FILTER_SANITIZE_NUMBER_INT ), FILTER_VALIDATE_INT );
/*
Dates from the DatePicker are in mm/dd/yyyy
but typically we would want to use yyyy/mm/dd
in the database.
*/
$startdate=DateTime::createFromFormat( 'm/d/Y', $startdate )->format('Y-m-d');
$enddate=DateTime::createFromFormat( 'm/d/Y', $enddate )->format('Y-m-d');
if( $fire > 1 or $fire < 0 or is_string( $fire ) ) $fire=0;
if( $electric > 1 or $electric < 0 or is_string( $electric ) ) $electric=0;
if( $sewer > 1 or $sewer < 0 or is_string( $sewer ) ) $sewer=0;
$sql='select `site_id`,`uid`,`startdate`,`enddate`,`s_price` from `campsite`
where `water`=? and `fire`=? and `electric`=? and `site_id` not in (
select `site_id`
from `reservation`
where `startdate` >= ? and `startdate` <= ?
)';
$stmt=$conn->prepare( $sql );
if( $stmt ){
$stmt->bind_param('iiiss', $sewer, $fire, $electric, $startdate, $enddate );
$result = $stmt->execute();
$rows = $result->num_rows;
if( $result && $rows > 0 ){
$stmt->store_result();
$stmt->bind_result( $id, $uid, $start, $end, $price );
while( $stmt->fetch() ){
$output[]=array(
'site_id' => $id,
'uid' => $uid,
'startdate' => $start,
'enddate' => $end,
's_price' => $price
);
}
$stmt->free_result();
$stmt->close();
$conn->close();
/*
Now we should have an array with the recordset data from the search
Depending upon form submission method ( standard or ajax ) you need to
do something with that data. Typically you would let the user know the
results of the search ( otherwise what is the point of letting them search? )
So, you could format the results here as HTML or send back json etc
*/
foreach( $output as $index => $site ){
echo "
<pre>
{$site['site_id']}
{$site['uid']}
{$site['startdate']}
{$site['enddate']}
{$site['s_price']}
</pre>";
}
} else {
exit( header('Location: /index.php?error=no_available_camps') );
}
} else {
echo "Failed to prepare sql query";
}
}
?>
" ; } } else { exit( header('Location:/index.php?error=no_available_camps') ); } } else { echo "Échec de la préparation de la requête sql" ; } }?> Il y avait d'autres déclarations sql là-dedans, mais comme je l'ai dit, je ne pouvais pas tout à fait suivre la logique, donc ce qui précède est probablement incomplet/faux, mais devrait au moins aider un peu avec les déclarations préparées.
Autres remarques
Vous avez une erreur non gérée sur le campground.php
page qui révèle
includes/reserve.php
et /reserve.php
les deux donnent un 404-Not Found
erreur
Peut-être utiliser un .htaccess
fichier dans les images
répertoire pour empêcher les liens directs ou la navigation dans les répertoires.
Il y a des images époustouflantes mais certaines sont, pour être honnête, absolument énormes et malgré la majorité des personnes ayant un haut débit rapide, le téléchargement d'un jpg de 3,7 Mo dans le cadre du flux HTML ralentit quelque peu les choses - alors peut-être qu'une optimisation de l'image serait un bon idée aussi. Cela dit, j'adorerais y aller moi-même !