美文网首页
PHP 扩展 - 获取当前请求 IP 地址

PHP 扩展 - 获取当前请求 IP 地址

作者: Bun_Wong | 来源:发表于2016-07-05 23:27 被阅读330次

    在 PHP 中获取 IP 地址通常都是来自 $_SERVER 全局变量中,比如

    $_SERVER['HTTP_CLIENT_IP'];
    // OR
    $_SERVER['HTTP_X_FORWARDED_FOR'];
    // OR
    $_SERVER['HTTP_X_REAL_IP'];  // 更多自定义的 key
    // OR
    $_SERVER['REMOTE_ADDR'];
    

    也有可能在被前端 Web server 或 load balance 附加到请求头上,如 nginx 中可能设置了

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    

    根据上面的逻辑,我简单实现了如下的一个方法

    // azalea.h
    PHP_FUNCTION(azalea_ip);
    
    // azalea.c
    
    /* {{{ azalea_getmodel
     */
    PHP_FUNCTION(azalea_ip)
    {
        zval *server, *field;
        zend_string *ip = NULL;
    
        server = zend_hash_str_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER") - 1);
        if (Z_TYPE_P(server) == IS_ARRAY) {
            if ((field= zend_hash_str_find(Z_ARRVAL_P(server), "HTTP_CLIENT_IP", sizeof("HTTP_CLIENT_IP") - 1)) &&
                    Z_TYPE_P(field) == IS_STRING) {
                ip = Z_STR_P(field);
            } else if ((field = zend_hash_str_find(Z_ARRVAL_P(server), "HTTP_X_FORWARDED_FOR", sizeof("HTTP_X_FORWARDED_FOR") - 1)) &&
                    Z_TYPE_P(field) == IS_STRING) {
                ip = Z_STR_P(field);
            } else if ((field = zend_hash_str_find(Z_ARRVAL_P(server), "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1)) &&
                    Z_TYPE_P(field) == IS_STRING) {
                ip = Z_STR_P(field);
            }
        }
        if (ip) {
            zend_string_copy(ip);
        } else {
            ip = zend_string_init("0.0.0.0", sizeof("0.0.0.0") - 1, 0);  // 默认值
        }
        RETURN_STR(ip);
    }
    /* }}} */
    

    当然了,PHP 通过 $_SERVER 甚至 request header 来获取 IP 都不是绝对靠谱的方法,还得看架构和运行环境。

    相关文章

      网友评论

          本文标题:PHP 扩展 - 获取当前请求 IP 地址

          本文链接:https://www.haomeiwen.com/subject/kpfkjttx.html