首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于IP地址- mysql数据库与在线用户合作

基于IP地址- mysql数据库与在线用户合作
EN

Stack Overflow用户
提问于 2015-06-15 01:09:39
回答 1查看 97关注 0票数 0

现在,我有一个框(页脚),其中我显示在线用户基于三种类型的url位置,用户类型和他的Ip地址。

我使用单个查询来删除、插入和显示在线用户,但我确实需要更多的性能,因为我不确定这是否是最快的方法。如果有人在我的代码里看到任何不好的做法。

我们开始:

网址的类型:

  1. 空url ( www.example.com )
  2. 网址: www.example.com/forum/123/
  3. 网址: www.example.com/topic/123/

用户类型:

  1. 来访者
  2. 注册用户

我就是这样获得用户IP地址的:

代码语言:javascript
复制
$ip_lookup = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
foreach($ip_lookup as $server_param)
{
    if(isset($_SERVER[$server_param]) && filter_var($_SERVER[$server_param], FILTER_VALIDATE_IP))
    {
        if(filter_var($_SERVER[$server_param], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
        {
            define('dpd_ip_type','v6');
        }
        else
        {
            define('dpd_ip_type','v4');
        }
        define('dpd_ip',inet_pton($_SERVER[$server_param]));
        break;
    }
}
if(!defined('dpd_ip') || dpd_ip === false) { error('error_ip'); exit(); }

这里有一个数组(其中一个基于url类型或用户类型):

代码语言:javascript
复制
$online['dpd_ip'] = dpd_ip; /* The ip (ipv4 or ipv6) - this was converted as binary width inet_pton */
$online['dpd_ip_type'] = dpd_ip_type; /* The ip type (ipv4 or ipv6) */
$online['dpd_time'] = dpd_time; /* The current time in Unix Timestamp format */
$online['url'] = ''; /* The url location - Empty by default */
$online['user_id'] = ''; /* The user id - Empty by default */
$online['user_name'] = ''; /* The user name - Empty by default */
$online['get_online_users_where'] = ''; /* The where clause used for for output records - empty by default */
$online['online_clear_where'] = ''; /* The where clause used for deleting records - empty by default */

if(is_user())
{
    $online['user_id'] = user_id; /* Set user_id because we talk about an registered user */
    $online['user_name'] = user_name; /* Set user_name because we talk about an registered user */
    $online['online_clear_where'] = " OR online_user_id = ".user_id; /* Set where clause for deleting this user before insert him again */
}

if(defined('url_1') && defined('url_2') && (url_1 == 'topic' || url_1 == 'forum'))
{
    $online['url'] = url_1.'/'.url_2; /* The url is a section like forum/123/ or topic/123 */
    $online['get_online_users_where'] = " WHERE online_url = '".url_1.'/'.url_2."'"; /* Output the user that are accessed this url location */
}

在这里,我开始使用数据库:

代码语言:javascript
复制
pdo('begin');

/* Delete records from database if:
    - The records are bigger than 15 minutes ( dpd_footer_online_time is set to 900 seconds )
    - This is the actual user 
*/
$online_clear = pdo("DELETE FROM online WHERE online_timestamp < ".(dpd_time - dpd_footer_online_time)." OR online_ip_".$online['dpd_ip_type']." = '".$online['dpd_ip']."'" . $online['online_clear_where']);

/* Insert the user into database */
$online = pdo("
    INSERT INTO
        online
        (
            online_user_id,
            online_user_name,
            online_ip_".$online['dpd_ip_type'].",
            online_timestamp,
            online_url
        )
    VALUES
    (
        '".$online['user_id']."',
        '".$online['user_name']."',
        '".$online['dpd_ip']."',
        '".$online['dpd_time']."',
        '".$online['url']."'
    )
    "
);

/* Output the users from the last 15 minutes */
$get_online_users = pdo("SELECT online_user_id, online_user_name, online_timestamp FROM online".$online['get_online_users_where']);
pdo('commit');

当然,这就是表( online_ip_v4和online_ip_v6是统一的):

欢迎任何建议..。

EN

回答 1

Stack Overflow用户

发布于 2015-06-16 00:28:34

请提供SHOW CREATE TABLE online;以便我们可以看到您有哪些索引(如果有的话),等等。

使用赋值语句,而不是define(...)

使用绑定,而不是连接--您很容易受到"SQL注入“的影响。

将删除拆分为两个(或三个)删除-- OR的两边各删除一个。(或者没有很好地优化。)

你可能需要

代码语言:javascript
复制
INDEX(online_timestamp)
UNIQUE(online_ip_v4)
UNIQUE(online_ip_v6)
INDEX(user_id)

对于既没有IPv4又没有IPv6的站点,您做什么?

请提供“显示在线用户”的查询/查询。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30843906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档