要在Discuz!论坛中实现显示访问者最近三个来路网址,可以按照以下步骤操作。这涉及到获取来路网址、存储这些信息,并在页面上显示最近的三条记录。下面将详细解答你的三个问题:
### 1. 如何知道来我网址的人是从哪个网址来的
在Web开发中,可以通过HTTP请求头中的`HTTP_REFERER`字段获取访问者的来路网址。不过需要注意的是:
- **可靠性**:`HTTP_REFERER`并非总是存在,有些浏览器或防火墙可能会禁用它,或者用户可能直接输入网址访问,这时`HTTP_REFERER`将为空。
- **安全性**:`HTTP_REFERER`可以被伪造,因此不应依赖它进行安全验证。
在Discuz!中,可以通过PHP代码获取`HTTP_REFERER`。例如,在模板文件中,你可以这样获取:
```php
```
### 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
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
fetch_all_by_order('dateline DESC', 0, 3);
if(!empty($recent_referers)) {
echo '';
echo '最近访问来源:';
echo '';
foreach($recent_referers as $referer) {
// 对URL进行解码并显示
$decoded_referer = dhtmlspecialchars(urldecode($referer['referer']));
echo '
[url=]'.$decoded_referer.'[/url]';
}
echo '
';
echo '';
} else {
echo '';
echo '暂无访问来源记录。
';
echo '';
}
?>
```
> **注意**:
> - `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
_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
$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
';
echo '最近访问来源:';
echo '';
foreach($recent_referers as $referer) {
$decoded_referer = dhtmlspecialchars(urldecode($referer['referer']));
echo '