iarp Posted August 13, 2014 Share Posted August 13, 2014 <?php require_once('init.php'); $results = $db->prepare('SELECT file_location, file_type, file_size, id as media_id WHERE id = ? LIMIT 1;'); $results->execute(array($_GET['id'])); while ($row = $results->fetch()) { header('Content-Type: ' . $row['file_type']); header('Content-Length: ' . $row['file_size']); $media_ins = $db->prepare('UPDATE media SET total_clicks = total_clicks + 1 WHERE id = ?'); $media_ins->execute(array($row['id'])); readfile($row['file_location']); } For some reason, putting the header('Content-Type....') causes the UPDATE statement to trigger twice increasing the total_clicks by 2. Commenting out the content-type line causes a single update to occur. init.php contains nothing more than session_start and the database connection. When i comment-out the content-type line the page is blank with no errors or messages. I'm not sure why this is occurring. Quote Link to comment Share on other sites More sharing options...
iarp Posted August 13, 2014 Author Share Posted August 13, 2014 Doing a tad more research. Turns out it's Chrome sending two separate requests. I've checked $_GET, $_POST, $_SERVER to determine if there is anyway I can stop the update from occurring on this secondary request and everything is identical Quote Link to comment Share on other sites More sharing options...
LIRANT Posted August 13, 2014 Share Posted August 13, 2014 (edited) EDIT: NVM Edited August 13, 2014 by LIRANT Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 13, 2014 Share Posted August 13, 2014 Are you sure this is your code? The query to select the file isn't even syntactically valid (there's no FROM clause). Besides that, why is there a limit when you select a row by its ID? Shouldn't the ID be unique anyway? And why do you call fetch() in a loop when you've just double-checked that you never get more than one row? Why not just fetch this row? Passing any content type that happens to reside in the database right to the client also isn't a good idea. In fact, it's a serious vulnerability. Anybody who can set the type has the power to change the meaning of the file. For example, a harmless image may be turned into a malicious HTML document to attack your users. You need a whitelist of acceptable types. I'm sure (or at least I hope) you already have that for the upload, so just reuse it here. Quote Link to comment Share on other sites More sharing options...
jazzman1 Posted August 13, 2014 Share Posted August 13, 2014 @Jacques1, the select statement is invalid not because of lack of FROM clause in the string (it's optional) but because of WHERE one @iarp, it's time to start to think like a programmer. You need to learn more about debugging process. Just google it Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 13, 2014 Share Posted August 13, 2014 @Jacques1, the select statement is invalid not because of lack of FROM clause in the string (it's optional) but because of WHERE one You do realize that the WHERE statement is actually important here, right? Quote Link to comment Share on other sites More sharing options...
jazzman1 Posted August 13, 2014 Share Posted August 13, 2014 (edited) What me or you or somebody else think, it doesn't really matter. For the sql parser, this is a syntactically invalid query returning a fatal error. @iarp, I don't think that you are able to execute global variables directly to the db server using a prepared method like in your example. Edited August 13, 2014 by jazzman1 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 13, 2014 Share Posted August 13, 2014 For the sql parser, this is a syntactically invalid query returning a fatal error. ... which is what I just said. What's your point? What are you trying to tell us? Did you want to remind us that MySQL supports SELECT queries with no clauses? Thanks, but this is neither new nor relevant here. The problem is that iarp has forgotten the FROM clause. @iarp, I don't think that you are able to execute global variables directly to the db server using a prepared method like in your example. Of course you can, try it out. Or rather: What makes you think it's not possible? PDO doesn't care where the value comes from. Quote Link to comment Share on other sites More sharing options...
jazzman1 Posted August 13, 2014 Share Posted August 13, 2014 Did you want to remind us that MySQL supports SELECT queries with no clauses? No, I did not say that! I was my fault. I've just forgot that the sql parser (in most db servers just for query performance) start reading a query first from where condition before to go further on. So, the parser like in the example above doesn't even know that this is a select statement. Of course you can, try it out I will try later on, when I get home. Are you thinking that I'm here wasting my time arguing with you or somebody else? Quote Link to comment Share on other sites More sharing options...
iarp Posted August 13, 2014 Author Share Posted August 13, 2014 (edited) Oh wow. OK so to clear up some confusion, the query I use has 2 other tables joined in. For simplicity sakes i removed the joins and just wrote out the query to use the media table, the FROM is in my query as it should be. Google Chrome, the first time you ever visit a website that has not been cached chrome sends out two requests at the same time. I have seen two to three other explanations as to why this occurs namely: It sends one request for the favicon to save into cache, and the other request to get the actual page data It sends two simultaneous connections, if one dies and the other works it just seamlessly flips to the working connection. What I am serving is not typically a page, but rather media. Chrome sends one connection requesting a page and once it figures out its media it sends another requesting the media itself. To fix this I have had to wrap the UPDATE statements in an if statement checking for an existing and non-empty $_SERVER['HTTP_RANGE']. I saved the $_SERVER array information for both requests and compared the data. One request was sent for the media, the other for page data. I found that whenever HTTP_REFERER existed that it always asked for page data and when HTTP_RANGE existed that it was looking for the media itself. Edited August 13, 2014 by iarp Quote Link to comment Share on other sites More sharing options...
iarp Posted August 13, 2014 Author Share Posted August 13, 2014 Here is a comparison of the only differences between the two $_SERVER arrays. Array ( [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch ) Array ( [HTTP_ACCEPT] => */* [HTTP_ACCEPT_ENCODING] => identity;q=1, *;q=0 [HTTP_REFERER] => https://mydomain/linker/l/123 [HTTP_RANGE] => bytes=0- ) All I care about is counting whenever the media itself has been delivered. So watching for the HTTP_RANGE I think should work just fine. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.