Need help with prepare statement

Hello, i’m stuck for a day now on transforming my “unsafe normal query” to a safe one using the prepare statement.
Really need some help and will be very thankfull if someone is willing to read through my code:

 <?php

 	include('includes/sessionstart.php');
	include 'dbh.php';

	$date1_raw = $_POST['selected_date1'];
    $date2_raw = $_POST['selected_date2'];

 if (!empty($date1_raw) && !empty($date2_raw))  {
 	if ($stmt = mysqli_prepare($conn, "SELECT * FROM costs WHERE ? BETWEEN ? AND ? AND userid=? ORDER BY ?")) {
 		
 		$stmt->bind_param("sssis", $costdate, $date1_raw, $date2_raw, $session_id, $costdate);

 		$stmt->execute();

 		$result = $stmt->get_result();

 		$num_of_rows = $result->num_rows;

 		while($row = $result->fetch_assoc()) { ?>
			<tr>
				<td><?php echo $row['subcategory']; ?></td>
				<td><?php echo $row['costname']; ?></td>
                <!-- Added "€" sign infront of price !-->
				<td><?php echo "€ " . $row['price']; ?></td>
				<td><?php echo $row['info']; ?></td>
                <!-- Added Date Function to convert format !-->
				<td><?php echo date( "d/m/y",strtotime ($row['costdate'])); ?></td>
			</tr>;
	<?php }}} ?>
	<form action="test.php" method="post">
        <input type="date" name="selected_date1" value="<?php echo date('d-m-Y'); ?>" />
        <input type="date" name="selected_date2" value="<?php echo date('d-m-Y'); ?>" />
        <input type="submit" name="filter_date" value="Filter">
    </form>

Can’t user parameters for column names, parameters are only for values.

What do you mean by that?

Could you give an example?

ORDER BY ? ORDER BY is followed by a column name, not a value.

changed it and the result as followed:

<?php

 	include('includes/sessionstart.php');
	include 'dbh.php';

	$date1_raw = $_POST['selected_date1'];
    $date2_raw = $_POST['selected_date2'];

 if (!empty($date1_raw) && !empty($date2_raw))  {
 	if ($stmt = mysqli_prepare($conn, "SELECT * FROM costs WHERE ? BETWEEN ? AND ? AND userid=? ORDER BY costdate")) {
 		
 		$stmt->bind_param("sssi", $costdate, $date1_raw, $date2_raw, $session_id);

 		$stmt->execute();

 		$result = $stmt->get_result();

 		$num_of_rows = $result->num_rows;

 		while($row = $result->fetch_assoc()) { 
				 echo $row['subcategory']; 
				 echo $row['costname']; 
                // Added "€" sign infront of price !-->
				 echo "€ " . $row['price']; 
				 echo $row['info']; 
                // Added Date Function to convert format !-->
				 echo date( "d/m/y",strtotime ($row['costdate'])); 
	 }}} ?>
	<form action="test.php" method="post">
        <input type="date" name="selected_date1" value="<?php echo date('d-m-Y'); ?>" />
        <input type="date" name="selected_date2" value="<?php echo date('d-m-Y'); ?>" />
        <input type="submit" name="filter_date" value="Filter">
    </form>

only thing is i get no echo’s any idea on how to check this?

Try echoing $num_of_rows to see if your query resulted in any records.

Do you think the ? here represents a value or or a column name? You already had help with the order by column name. Try to apply the same thought process to other column names.

It returns 0 if i select the dates so i assume there is no data stored in the query? :sa:

I really don’t know if the code is wrong that i entered i get no errors tho…

<?php

 	include('includes/sessionstart.php');
	include 'dbh.php';

	$date1_raw = $_POST['selected_date1'];
    $date2_raw = $_POST['selected_date2'];

 if (!empty($date1_raw) && !empty($date2_raw))  {
 	if ($stmt = mysqli_prepare($conn, "SELECT * FROM costs WHERE ? BETWEEN ? AND ? AND userid=? ORDER BY costdate")) {
 		
 		$stmt->bind_param("sssi", $costdate, $date1_raw, $date2_raw, $session_id);

 		$stmt->execute();

 		$result = $stmt->get_result();

 		$num_of_rows = $result->num_rows;

 		echo $num_of_rows;
 		/*while($row = $result->fetch_assoc()) { 
				 echo $row['subcategory']; 
				 echo $row['costname']; 
                // Added "€" sign infront of price !-->
				 echo "€ " . $row['price']; 
				 echo $row['info']; 
                // Added Date Function to convert format !-->
				 echo date( "d/m/y",strtotime ($row['costdate'])); 
	 }}} ?>*/
	 }} ?>
	<form action="test.php" method="post">
        <input type="date" name="selected_date1" value="<?php echo date('d-m-Y'); ?>" />
        <input type="date" name="selected_date2" value="<?php echo date('d-m-Y'); ?>" />
        <input type="submit" name="filter_date" value="Filter">
    </form>

I changed it to:

if ($stmt = mysqli_prepare($conn, "SELECT * FROM costs WHERE costdate BETWEEN ? AND ? AND userid=? ORDER BY costdate")) {

I assume this is right then?
Still don’t get a result tho other then 0.

Yep. Now the question is what format are your date strings. Look like you have day/month/year while I suspect your database expects year/month/day. Might consider firing up a mysql console window and executing the query by hand until you know you have the correct format.

I don’t understand my normal query:

$sql_datefilter = "SELECT * FROM costs WHERE costdate BETWEEN '$date1_raw' AND '$date2_raw' AND userid='".$_SESSION['id']."'ORDER BY costdate";

Works fine and selects what i need.
But the prepare statement query:

if ($stmt = mysqli_prepare($conn, "SELECT * FROM costs WHERE costdate BETWEEN ? AND ? AND userid=? ORDER BY costdate")) {
 		
 		$stmt->bind_param("ssi", $date1_raw, $date2_raw, $session_id);

 		$stmt->execute();

 		$stmt->store_result();

 		printf("Number of rows: %d.\n", $stmt->num_rows);

Prints: Number of rows: 0.
also my loop to echo says this:
Fatal error: Call to a member function fetch_assoc() on null in location on line 20

 		while($row = $result->fetch_assoc()) { 
				 echo $row['subcategory']; 
				 echo $row['costname']; 
                // Added "€" sign infront of price !-->
				 echo "€ " . $row['price']; 
				 echo $row['info']; 
                // Added Date Function to convert format !-->
				 echo date( "d/m/y",strtotime ($row['costdate'])); 
	 }

So i’m just clueless on why this doesn’t work…

did you define $result anywhere?

Is $_SESSION['id'] an Integer? i.e. 0 to 9 only and no fractional portion.

No, forgot to change that since i was experimenting but that still shouldn’t make: printf("Number of rows: %d.\n", $stmt->num_rows);

Echo 0 should it?

Yes it is an integer in this case: 25 in the database

I must be getting tired. I just noticed you’re mixing procedural syntax with OOP syntax.

I don’t know as doing that would cause the problem because I’ve never mixed syntax like that, but I’m guessing it must.

that’s very weird since i watched dozens of videos explaining both PDO and OOP and they all did it like this for OOP
Also followed the official documentation on the php website that explained it like this for OOP…

mysqli_prepare is procedural
OOP would be $mysqli->prepare

http://php.net/manual/en/mysqli-stmt.num-rows.php

I must admit I always get a bit confused by this, but would passing the session_id value in as an integer tie in with the fact that the working query has it surrounded by single-quotes? That is, should it be passed in using an ‘s’ mask instead? I’m not familiar with mysqli.

Not according to this example
http://php.net/manual/en/mysqli.prepare.php

$mysqli->prepare("SELECT District FROM City WHERE Name=?")

Unless maybe if the fields datatype isn’t numeric.