How do I change a value in PHP and mysqli DB depending on user input?

This doesn’t seem to work. Basically, every authorized user has a unique download code. They enter it in a form and submit. If the code exists in the DB, a file is automatically downloaded. This works with the awesome help of @PHPNob. Now I want to extend it so if the code is found in the DB, it downloads as usual, but also then changes the code to something else so the user won’t go around spreading the link and code.

Here is what I have. It doesn’t do anything except refresh the page and the validation ($error) is also now broken. :frowning:

Can I get some pointers? :smile: Thanks!!

if (isset($_GET['code']) && !empty($_GET['code'])) {

	$stmt = $db_donate->prepare('SELECT * FROM donations WHERE code = ?');
    $stmt->bind_param('s', $code);
	$stmt->execute();
    $stmt->store_result();
    
    if($stmt->num_rows>0) {	
		if ($stmt = $db_donate->prepare('UPDATE donations SET code = ?')) {				
				$newcode = 'downloaded';
				$stmt->bind_param('ss', $newcode, $_GET['code']);
				$stmt->execute();
                run code
		}
	} else {
		$error = "<span class='error_msg'>Download code not found or file already downloaded!</span>";
	}
}

what I can think of, is generating a new token/code each time a user clicks download and updating it in the related table, once the file is downloaded you will null the token/code again.

1 Like

Okay it’s working! I also added a location: command, but I understand that it won’t work after “readfile”. Is there a work around? Thanks!

the token column should be generated dynamically, each time a user clicks download it generates a new token and updates it in the table, you allow 10 minutes to let the browser retry for example and then null this token out. Probably you need 2 tables

(1 table that will store like id, file_name, file_ext, view_name )

(2nd table will have a few columns like: id, file_id from first table, token and active_time)

so each time a user click download, you are inserting in the 2nd table
(file_id) is the id of the file from 1st table
(token) => is generated dynamically there are different functions available,
active_time => accepts the time you want each token to be active, for example you want each token to be available for 1 hour only then it would be something like this

time() + 1 * 60 * 60

now when a user downloads you are checking if the token already found then if current time is greater than active_time column , you are printing “token expired”.

Hence you can have a cron job to clear all the expired tokens day by day.

1 Like

Sounds cool, but I don’t really know how to do any of that. Just a simple way to thank the user for donating and a “download complete” would work. Using the DB should bypass the readfile issue?

It’s not possible to echo anything after readfile as far as I know because in the proceeding part We have already used headers, However You may have a hidden paragraph by default and once they click download you show it with JS and a counter for example:

Thank you for donating, Download will start in 10 seconds

Okay, here’s what I came up with. Everything works, except it won’t display the hidden div on click (or at all for that matter). The $error var is part of the validation and is triggered when someone inputs an incorrect code. I also tried "(!isset($error)). Can you help? :smile:

<form action="download.php" method="post">
<input type="text" name="code" size="10" required autofocus /><br>
<?php if (isset($error)): ?><?php echo $error; ?><?php endif ?>
<br><input type="submit" value="Download" onclick="document.getElementById('my_id').style.display = 'block' ;" /></form>
<?php if ((empty($error)) && (isset($code))): ?>
<div style="display:none;" id="my_id"><span style=" color:#00ff00;font-size:17px;">Download succesful! Enjoy!</span></div>
<?php endif ?>

That’s how I would do it:

Your download.php file should only validate the code but it should not contain the headers for yet.

If code is validated then you can save the file id in a session then you are redirecting to another page for example ‘verified.php’ and here you are printing anything to the user also in your script tag you will have debouncer function to redirect to the handler file after for example 5 seconds

Finally your handler.php contains the headers for the download.

It’s just what I can think of now , You probably can do better than that

1 Like

Ah, coolness. So I’d save the filename and path in a session, then retrieve this in the other PHP file and the user gets the download after the denounce delay?

Only save the file id in a session and then fetch any other details later from the db because the name or the path can be changed anytime.

Here is a tutorial that does same sorta thing but more advanced and using ajax

1 Like

Worked perfectly, thanks very much!! :smile:

Sponsor our Newsletter | Privacy Policy | Terms of Service