用DZ做的论坛,如何实现来路网址的最近三个的显示? [复制链接]

moqu8 9天前

44 0

要在Discuz!论坛中实现显示访问者最近三个来路网址,可以按照以下步骤操作。这涉及到获取来路网址、存储这些信息,并在页面上显示最近的三条记录。下面将详细解答你的三个问题:

### 1. 如何知道来我网址的人是从哪个网址来的

在Web开发中,可以通过HTTP请求头中的`HTTP_REFERER`字段获取访问者的来路网址。不过需要注意的是:

- **可靠性**:`HTTP_REFERER`并非总是存在,有些浏览器或防火墙可能会禁用它,或者用户可能直接输入网址访问,这时`HTTP_REFERER`将为空。
- **安全性**:`HTTP_REFERER`可以被伪造,因此不应依赖它进行安全验证。

在Discuz!中,可以通过PHP代码获取`HTTP_REFERER`。例如,在模板文件中,你可以这样获取:

```php
<?php
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
?>
```

### 2. 如何显示来路网址

要在页面上显示来路网址,首先需要将获取到的`HTTP_REFERER`存储起来,然后在模板中进行显示。以下是具体步骤:

#### a. 存储来路网址

你需要创建一个数据库表来存储来路网址。假设你已经熟悉Discuz!的数据库结构,可以按照以下步骤操作:

1. **创建数据库表**

   在Discuz!的数据库中创建一个新表,用于存储来路网址。例如,创建一个名为`pre_referer_log`的表:

   ```sql
   CREATE TABLE `pre_referer_log` (
     `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
     `referer` varchar(255) NOT NULL DEFAULT '',
     `dateline` int(10) unsigned NOT NULL DEFAULT '0',
     PRIMARY KEY (`id`),
     KEY `dateline` (`dateline`)
   ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
   ```

   > **注意**:`pre_`前缀应与你的Discuz!安装前缀一致。

2. **记录来路网址**

   在访问者每次访问页面时,将`HTTP_REFERER`插入到`pre_referer_log`表中。为了避免表过大,可以限制记录的数量,例如只保留最近的100条记录。

   在Discuz!的模板文件(如`forumdisplay.htm`或其他适合的位置)中添加以下代码:

   ```php
   <?php
   // 确保在Discuz!的公共函数加载后执行
   if(!defined('IN_DISCUZ')) {
       exit('Access Denied');
   }

   $referer = isset($_SERVER['HTTP_REFERER']) ? daddslashes($_SERVER['HTTP_REFERER']) : '';
   if(!empty($referer)) {
       // 检查是否已经存在相同的来路(可选)
       $count = C::t('referer_log')->count_by_referer($referer);
       if($count == 0) {
           // 插入新记录
           C::t('referer_log')->insert(array(
               'referer' => $referer,
               'dateline' => $_G['timestamp']
           ), false, true);

           // 限制记录数量,例如最多保留100条
           C::t('referer_log')->query("DELETE FROM ".DB::table('referer_log')." WHERE id NOT IN (SELECT id FROM ".DB::table('referer_log')." ORDER BY dateline DESC LIMIT 100)");
       }
   }
   ?>
   ```

   > **注意**:
   > - `C::t('referer_log')` 假设你已经创建了一个数据表模型。如果没有,需要先在Discuz!的插件或自定义模块中定义该模型。
   > - 上述代码中的`count_by_referer`和插入逻辑需要根据实际情况调整,或者通过其他方式确保不重复插入相同的来路网址。

#### b. 显示最近三条来路网址

在需要显示来路网址的模板文件中(如页脚或其他适当位置),添加以下代码:

```php
<?php
// 确保在Discuz!的公共函数加载后执行
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}

// 查询最近三条来路网址
$recent_referers = C::t('referer_log')->fetch_all_by_order('dateline DESC', 0, 3);

if(!empty($recent_referers)) {
    echo '<div class="recent-referers">';
    echo '<h3>最近访问来源:</h3>';
    echo '<ul>';
    foreach($recent_referers as $referer) {
        // 对URL进行解码并显示
        $decoded_referer = dhtmlspecialchars(urldecode($referer['referer']));
        echo '<li><a href="'.$referer['referer'].'" target="_blank">'.$decoded_referer.'</a></li>';
    }
    echo '</ul>';
    echo '</div>';
} else {
    echo '<div class="recent-referers">';
    echo '<p>暂无访问来源记录。</p>';
    echo '</div>';
}
?>
```

> **注意**:
> - `C::t('referer_log')->fetch_all_by_order('dateline DESC', 0, 3);` 这行代码假设你已经为`referer_log`表创建了相应的数据表模型,并且支持按`dateline`排序和限制数量。如果没有,需要手动编写SQL查询,例如:
>   ```php
>   $recent_referers = DB::fetch_all("SELECT * FROM ".DB::table('referer_log')." ORDER BY dateline DESC LIMIT 3");
>   ```

### 3. 要显示最近三条

如上所述,在显示最近来路网址的代码中,已经通过`LIMIT 3`限制了只显示最近的三条记录。确保在查询时使用类似以下的方法:

```php
// 使用数据表模型(假设已定义)
$recent_referers = C::t('referer_log')->fetch_all_by_order('dateline DESC', 0, 3);

// 或者手动编写SQL
$recent_referers = DB::fetch_all("SELECT * FROM ".DB::table('referer_log')." ORDER BY dateline DESC LIMIT 3");
```

然后在循环中遍历这3条记录并显示。

### 完整示例

假设你已经创建了`pre_referer_log`表,并且有一个数据表模型`referer_log`,以下是一个完整的实现示例:

#### a. 创建数据表模型(如果尚未创建)

在Discuz!的插件或自定义模块中,添加以下模型定义(例如在`source/plugin/your_plugin/model/referer_log_model.class.php`):

```php
<?php
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}

class table_referer_log extends discuz_table {
    public function __construct() {
        $this->_table = 'referer_log';
        $this->_pk = 'id';
        parent::__construct();
    }

    public function fetch_all_by_order($order = 'dateline DESC', $start = 0, $limit = 3) {
        return DB::fetch_all("SELECT * FROM %t ORDER BY {$order} LIMIT {$start}, {$limit}", array($this->_table));
    }
}
```

> **注意**:上述模型仅为示例,具体实现可能需要根据Discuz!的模型规范进行调整。

#### b. 记录来路网址

在适当的模板文件中(如`forumdisplay.htm`),添加以下代码:

```php
<?php
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}

$referer = isset($_SERVER['HTTP_REFERER']) ? daddslashes($_SERVER['HTTP_REFERER']) : '';
if(!empty($referer)) {
    // 检查是否已存在(简单示例,实际可能需要更复杂的去重逻辑)
    $exists = DB::result_first("SELECT COUNT(*) FROM ".DB::table('referer_log')." WHERE referer = %s", array($referer));
    if($exists == 0) {
        DB::insert('referer_log', array(
            'referer' => $referer,
            'dateline' => $_G['timestamp']
        ));
        
        // 限制记录数量
        DB::query("DELETE FROM ".DB::table('referer_log')." WHERE id NOT IN (SELECT id FROM ".DB::table('referer_log')." ORDER BY dateline DESC LIMIT 100)");
    }
}
?>
```

#### c. 显示最近三条来路网址

在需要显示的位置(如页脚模板`footer.htm`),添加以下代码:

```php
<?php
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}

// 查询最近三条来路网址
$query = DB::query("SELECT * FROM ".DB::table('referer_log')." ORDER BY dateline DESC LIMIT 3");
$recent_referers = array();
while($referer = DB::fetch($query)) {
    $recent_referers[] = $referer;
}

if(!empty($recent_referers)) {
    echo '<div class="recent-referers">';
    echo '<h3>最近访问来源:</h3>';
    echo '<ul>';
    foreach($recent_referers as $referer) {
        $decoded_referer = dhtmlspecialchars(urldecode($referer['referer']));
        echo '<li><a href="'.$referer['referer'].'" target="_blank">'.$decoded_referer.'</a></li>';
    }
    echo '</ul>';
    echo '</div>';
} else {
    echo '<div class="recent-referers">';
    echo '<p>暂无访问来源记录。</p>';
    echo '</div>';
}
?>
```

### 注意事项

1. **性能考虑**:频繁的数据库插入和删除操作可能影响性能,尤其是在高访问量的论坛上。可以考虑使用缓存机制,定期批量处理记录,或者限制插入频率(如每分钟只记录一次)。

2. **数据清理**:定期清理旧的记录,避免表过大影响性能。可以在插件中添加定时任务,定期执行清理操作。

3. **安全性**:确保对`HTTP_REFERER`进行适当的过滤和转义,防止XSS攻击。上述代码中使用了`dhtmlspecialchars`和`urldecode`进行处理。

4. **隐私问题**:记录用户的来路网址可能涉及隐私问题,确保遵守相关法律法规,并在必要时告知用户。

### 总结

通过以上步骤,你可以在Discuz!论坛中实现记录并显示访问者最近三个来路网址的功能。这涉及到获取`HTTP_REFERER`、将其存储到数据库,并在模板中进行展示。务必注意性能优化和安全性,以确保功能的稳定性和用户数据的安全。

他们看过
  • time
  • 996素材网996n2.com
  • 青提
  • zo
  • Vibe
最新回复 (0)
  • Vibe
    2

返回
支持中心
邮箱:winkill2012@qqcom
新站优化中!部分功能尚未完善,敬请谅解!
支持中心