2012-07-23 111 views
2

好吧,我试图建立一个安全的下载系统,其中一个特定的许可证号码的买家可以访问下载,他可以在他的许可解除前下载两次。为了做到这一点,我在同一行中的'product_id'和'license_number'列旁边有'count'列。当我的paypal ipn脚本确认时,产品ID和许可证号码会自动生成并传递给买方。脚本运行两次?

现在问题是:当他们访问带有正确变量的下载页面时,count会被+1更新,但由于某种原因,这个sql查询会运行两次,实际上我的数据库中会得到+2。我已经改变了一点,先检查一下这个值,然后相应地改变(看看是否修复了这个错误),但错误仍然没有被修复。

我个人认为也许我调用一个文件下载会使脚本运行两次,或者我错了吗?

这是代码:

<?php 

include ('../storescripts/connect_to_mysql.php'); 

// Looks first if the post variables have been set 

if(!isset($_GET['id']) && ($_GET['lcn'])){ 

    // Error output 
    echo 'The big PHP monster will not accept you into his cave without bringing an offering of variables!'; 

} else { 

    // Set the variables 
    $id = $_GET['id']; 
    $license_number = $_GET['lcn']; 

    // Check if there is such a thing (Yes, aliens) as the given id and license number 
    $sql = mysql_query("SELECT * FROM secure_downloads WHERE product_id ='$id' AND license_number ='$license_number' LIMIT 1"); 

    $result = mysql_num_rows($sql); 

    if($result > 0){ 



     // Now update the download count 
     // Check first if the count is 0 

     // Make a variable from the count sql 
     $sql_count = mysql_query("SELECT * FROM secure_downloads WHERE product_id='$id' AND license_number='$license_number' LIMIT 1"); 

     while($row = mysql_fetch_assoc($sql_count)){ 
       $count = $row['count']; 
      } 

     // Check if the count is above two 
     if ($count >= 2){ 
     // Download has already been downloaded 2 times, do not allow download 
     echo 'The download limit for this file has been reached.'; 
     exit(); 

    } else if ($count = 0) { 
     // Everything is alright, start downloading 

     // Force the file download 
     $file = 'test.jpg'; 
     // Change the count to 1 
     mysql_query("UPDATE secure_downloads SET count=1 WHERE product_id = '$id' AND license_number = '$license_number'"); 
     readfile($file); 
     exit(); 

     } else if ($count = 1) { 

     // Everything is alright, start downloading 

     // Force the file download 
     $file = 'test.jpg'; 
     // Change the count to 2 
     mysql_query("UPDATE secure_downloads SET count=2 WHERE product_id = '$id' AND license_number = '$license_number'"); 
     header('Content-Description: File Transfer'); 
     header('Content-Type: application/octet-stream'); 
     header('Content-Disposition: attachment; filename='.basename($file)); 
     header('Content-Transfer-Encoding: binary'); 
     header('Expires: 0'); 
     header('Cache-Control: must-revalidate'); 
     header('Pragma: public'); 
     header('Content-Length: ' . filesize($file)); 
     ob_clean(); 
     flush(); 
     readfile($file); 


    exit(); 


    } 


    } else { 


     // It doesn't exist, tell the user either the variables were wrong or the 
     // download limit has been reached 
     echo 'Cannot download the file, either the link is wrong or the download limit has been reached'; 
    } 

} 

?> 
+0

IPN是否将其帖子发送到相同的脚本? – yoavmatchulsky 2012-07-23 16:32:55

+0

这就是为什么您应该使用POST进行可以更改服务器状态的操作的一个原因。浏览器可以自由地假设GET请求不会导致任何可观察的状态变化,因此如果他们愿意,他们可以自由地多次请求这些页面。 – cdhowie 2012-07-23 16:33:12

+0

@yoavmatchulsky它会,但现在这只是一个独立的脚本即时测试 – 2012-07-23 16:51:38

回答

3
} else if ($count = 0) { 

将其改为==。看起来像是在每个循环中将0分配给变量count,这可能是您的困境的原因。

这里有另外一个问题:

} else if ($count = 1) { 

确保所有的if报表使用==(或===)进行比较,而不是=分配。

+0

修好了!不能相信我忽略了这一点! – 2012-07-23 17:41:33

+1

然后我可以得到快乐的绿色勾号吗? :D – dunc 2012-07-23 20:33:41

+1

哦对不起,哈哈,新在这里:) – 2012-10-02 14:58:41

1

看看服务器日志,看看是否你实际上是在下载URL获得两个请求?我已经看到某些浏览器(特别是移动浏览器)在实际进行GET之前实际发出HEAD请求的情况。如果你的代码不能区分这两种请求类型,它将执行两次。

+1

+1我有同样的问题,并且浏览器不断向/favicon.ico文件发出第二个请求,这个文件不存在。但是,因为我用mod_rewrite重写所有index.php我得到重复请求。 – Ignas 2012-07-23 16:34:05

0

在我的情况下,它是favicon.ico ie上缺少的路径引用。 href =“/ favicon.ico”(好)vs href =“favicon.ico”(坏)。

迈克的回答下面的Ignas评论有帮助,但它在日志中得到证实。缺少的路径引用导致Apache2 mod_rewrite将/ controller/view/id映射为/controller/view/favicon.ico,这当然会导致日志中出现大量PHP错误,如“PHP Notice:Undefined index:bar in foo.php线83“。我知道索引的存在,我可以看到在我面前打印的价值。

一些帮助他人调试/确认问题的工具。

<?php error_log($_SERVER['REQUEST_URI']); ?> 

使用命令行来跟踪错误。例如。

$ tail -F /var/log/apache2/error.log 

刷新,你会在你的日志中看到类似的东西两次(也许更多?)。

例子:

[Thu Jan 11 03:20:44.211993 2018] [:error] [pid 21161] [client 192.168.0.1:34254] /controller/view/11, referer: http://localhost/controller/view/11 

**NOTE: NO ERRORS HERE** 

[Thu Jan 11 03:20:44.211993 2018] [:error] [pid 21161] [client 192.168.0.1:34254] /controller/view/favicon.ico, referer: http://localhost/controller/view/11 

**NOTE: ERRORS START HERE** The line above is the culprit. 

[Thu Jan 11 03:20:44.211993 2018] [:error] [pid 21161] [client 192.168.0.1:34254] PHP Notice: Undefined index: bar in foo.php line 83 

[Thu Jan 11 03:20:44.211993 2018] [:error] [pid 21161] [client 192.168.0.1:34254] PHP Notice: Undefined index: bar2 in foo.php line 84 

[Thu Jan 11 03:20:44.211993 2018] [:error] [pid 21161] [client 192.168.0.1:34254] PHP Notice: Undefined index: bar3 in foo.php line 85 

这是一个愚蠢的错误,但是这不好玩修复。用于在处理代码时加载日志文件+1。感谢Ignas和Mike。这是一个较老的问题,但它是Google上唯一的Stack答案,“php脚本执行两次”,所以我认为我会贡献并扩展其他两个想法。