首页 > 解决方案 > 有时在脚本执行中数据库正在更新

问题描述

我编写的 URL 较短脚本有一些奇怪的问题,直到前几天我才注意到这些问题,它的执行非常基本,但它在实际不时有效的 aprt 中失败了,我将发布整个代码,因为它只有 1 页,以防在问题发生的地方出现故障。

代码:

<?php
    $pdo = new PDO(sprintf('%s:host=%s;dbname=%s', 'mysql', 'ip', 'db'), 'user', 'pass');
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
?>

<?php

if (!empty($_GET['u'])) {

    $urlShort = trim($_GET['u']);       

    try {
    
        // Update the hit count ...
        $u = $pdo->prepare('
            UPDATE  `urls`
            SET     `url_hits` = `url_hits`+1
            WHERE   `url_short` = :urlShort
        ');         
        $u->execute([
            ':urlShort' => $urlShort
        ]); 
        
        // Log the referrer ...
        if (!empty($_SERVER['HTTP_REFERER'])) {     
            $i = $pdo->prepare('
                INSERT INTO `refs` (`ref_owner`, `ref_ref`, `ref_date`)
                VALUES (:r_o, :r_r, :r_d)
            ');         
            $i->execute([
                ':r_o' => $urlShort,
                ':r_r' => $_SERVER['HTTP_REFERER'],
                ':r_d' => date('Y-m-d H:i:s')
            ]);     
        }   
        
        //die(print_r($u) + print_r($i));   
        
        // Get the short code to redirect to ...
        $r = $pdo->prepare('
            SELECT  `url_link`
            FROM    `urls`
            WHERE   `url_short` = :urlShort
        ');         
        $r->execute([
            ':urlShort' => $urlShort
        ]);
        
        $redirect    = $r->fetch();

        header('HTTP/1.1 301 Moved Permanently');
        header('Location: ' . trim($redirect['url_link']));         
        
    } catch(exception $ex) {        
        //die($ex);
    }               
    
} 

?>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
    <title><?= $_SERVER['HTTP_HOST']; ?> | URL Shortner</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="FREE URL Shortner services, shorten your URLs on all your social accounts easily ..." />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
</head>
<body>

    <div class="container">

        <h3 class="text-center">&nbsp;</h3>
        
            <?php
            
            if (isset($_POST['submit_shortner'])) {
    
                    // TODO: Fix.
                    if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $_POST['301_url'])) { ?>
                        <hr style="border-top: 1px solid #ccc;">
                        <div class="container">
                            <div class="alert alert-danger" role="alert"><i class="fas fa-exclamation-triangle"></i> Your URL looks <strong>invalid</strong>!</div>
                        </div>
                    <?php }
                    
                    $short = "";
                    if (!empty($_POST['301_customize'])) {
                        // Check if the short code is already in the database ...
                        $dupes = $pdo->prepare("SELECT `url_short` FROM `urls` WHERE `url_short`='{$_POST['301_customize']}'");
                        $dupes->execute();
                        if ($dupes->rowCount() > 0) { ?>
                        <hr style="border-top: 1px solid #ccc;">
                        <div class="container">
                            <div class="alert alert-danger" role="alert"><i class="fas fa-exclamation-triangle"></i> Please choose another <strong>custom</strong> name!</div>
                        </div>
                        <?php } else {
                            $short = $_POST['301_customize'];   
                        }               
                    } else {
                        $short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5);               
                    }
                    
                    function get_real_ip() {
                        try {
                            if (!empty($_SERVER['HTTP_CLIENT_IP']))
                            {
                              $ip = $_SERVER['HTTP_CLIENT_IP'];
                            } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
                            {
                              $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                            } else
                            {
                              $ip = $_SERVER['REMOTE_ADDR'];
                            }
                            return $ip;
                        } catch(Exception $e) {
                            echo $e->getMessage();      
                        }
                    }                   
                    
                    if (!empty($short)) {                       
                        $pdo->prepare('
                            INSERT  INTO `urls` (`url_link`, `url_short`, `url_ip`, `url_hits`, `url_member_id` ,`url_date`)
                            VALUES  (:url, :urlShort, :ip, :hits, :memberId, :date)
                        ')->execute([
                            ':url' => $_POST['301_url'],
                            ':urlShort' => $short,
                            ':ip' => get_real_ip(),
                            ':hits' => '0',
                            ':memberId' => '0',
                            ':date' => date('Y-m-d H:i:s')
                        ]);     
                        
                        // redirect
                        $redirect = "?s={$short}";
                        header('Location: '.$redirect); 
                        die;                    
                    }           
                    
            }
            
            ?>

            <form method="post" action="<?= $_SERVER['PHP_SELF']; ?>">
            
               <hr style="border-top: 1px solid #ccc;">
            
               <div class="form-group">
                <label for="301_url">Link to shorten</label>
                <input type="301_url" class="form-control" name="301_url" id="301_url" aria-describedby="emailHelp" placeholder="http(s)://..." required>
                <small id="emailHelp" class="form-text text-muted">Paste your long URL here.</small>
               </div>
              
               <div class="form-group">
                <label for="301_customize">Customize your short link (optional)</label>
                <input type="301_customize" class="form-control" name="301_customize" id="301_customize" placeholder="">
                <small id="emailHelp" class="form-text text-muted">Here we use a keyword (case sensitive) instead of a cryptic string. Example: <strong>https://<?= $_SERVER['HTTP_HOST']; ?>/u/keyword</strong></small>
               </div>
              
               <div class="form-group">
                <button type="submit" name="submit_shortner" class="btn btn-success btn-sm btn-block"><i class="fas fa-external-link-alt"></i> Make Wee!</button>
               </div>
               
            </form>
            
    <?php if (!empty($_GET['s'])) { ?>
    
              <hr style="border-top: 1px solid #ccc;">
              
              <div class="form-group">
                <label for="301_customize"><strong>Short URL</strong></label>
                <input type="301_customize" class="form-control" id="301_copyInput" value="<?= 'https://'; ?><?= $_SERVER['HTTP_HOST']; ?>/u/<?= $_GET['s']; ?>/">
                <small id="emailHelp" class="form-text text-muted">Click the icon to copy to clipboard <a href="<?= 'https://'; ?><?= $_SERVER['HTTP_HOST']; ?>/u/<?= $_GET['s']; ?>/" onClick="return copyFunction()" data-toggle="Copy URL to clipboard"><i class="fas fa-copy"></i></a></small>
              </div>
              
              <hr style="border-top: 1px solid #ccc;">

    <?php } ?>

    <p class="text-center">&copy<?= date('Y'); ?> <a href="https://<?= $_SERVER['HTTP_HOST']; ?>">https://<?= $_SERVER['HTTP_HOST']; ?></a></p>
    
    </div>

    <script>
    $(document).ready(function(){
        $('[data-toggle="tooltip"]').tooltip({
            placement : 'bottom'
        });
    });
    </script>

    <script>
    function copyFunction() {
      var copyText = document.getElementById("301_copyInput");
      copyText.select();
      document.execCommand("copy");
      alert("Copied URL to clipboard!");  
      return false;
    } 
    </script>

</body>
</html>

我已经取出顶部的凭据,问题是,如果我将其设置回顶部以在 3 个主要浏览器 IE、Chrome 和 FF 中的每一个中进行点击测试,$pdo顶部的点击次数不会一直增加0它会增加 1 罚款,它不会更高,但是如果我注释掉这部分:die(print_r($u) + print_r($i))然后测试,它应该增加(但仅使用 IE),同样奇怪的是,这部分的重定向:header('Location: trim($redirect['url_link']));是工作正常,所以它应该从上到下执行脚本。

由于某种原因,在点击计数之后的引荐来源代码永远不会被执行。

没有错误显示,另一个奇怪的问题,它有时会更新命中计数,有时不会,我.htaccess的设置如下:

RewriteEngine on
# Force www:
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Force SSL: 
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,NE]
# URL Rewrite links.
RewriteRule ^u/([^/]*)\/$ /?u=$1 [L]

使用 likesiteused.com/u/test而不是siteused.com/?u=test这是某种问题吗?我不认为每次我调试u值总是通过绝对好。

我不确定还有什么要调试的,有什么明显的我错过或没有正确完成吗?任何帮助,将不胜感激。

标签: php

解决方案


这是由于301重定向。header('HTTP/1.1 301 Moved Permanently'); 因此,一旦浏览器获得任何 URL 的 301 状态代码,例如A -> B,它就会在内部“记住”翻译,因此在随后的点击中使用它所以当用户在地址栏中键入 A 或单击 A 的链接时,实际上永远不会点击 A

您更需要的是302 header('HTTP/1.1 302 Found');,因为浏览器不会缓存它,并且您的路线每次都会受到打击


推荐阅读