0

I'm developing a Wordpress plugin and am trying to use the following function to return a variable called $user_country that can be accessed in other functions in the same file. The code works when I nest it inside another function, but when I make it its own function, I can't access the variable $user_countryfrom other functions.

(I'm still new to PHP / coding and trying to learn and wouldn't be surprised if I'm making an obvious newbie mistake.)

function get_user_country() {
    if (!class_exists('GeoIP')) {
    include_once("geoip.inc");
    }

    if (empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        $ip_address = $_SERVER["REMOTE_ADDR"];
    } else {
        $ip_address = $_SERVER["HTTP_X_FORWARDED_FOR"];
    }

    if (!filter_var($ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === FALSE) {     
        $gi = \LSMIGeoIP\geoip_open(WP_PLUGIN_DIR . "/location-specific-menu-items/GeoIP.dat", GEOIP_STANDARD);
        $user_country = \LSMIGeoIP\geoip_country_code_by_addr($gi, $ip_address);
        \LSMIGeoIP\geoip_close($gi);
    } elseif (!filter_var($ip_address, FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) === FALSE) {
        $gi = \LSMIGeoIP\geoip_open(WP_PLUGIN_DIR . "/location-specific-menu-items/V6GeoIP.dat", GEOIP_STANDARD);
        $user_country = \LSMIGeoIP\geoip_country_code_by_addr($gi, $ip_address);
        \LSMIGeoIP\geoip_close($gi);
    } else {
        $user_country = "Can't locate IP: " . $ip_address;              
    }
    return $user_country;
}
8
  • use global $user_country inside a function to use global variables. Commented Feb 12, 2016 at 5:36
  • You really shouldn't be using globals though. Commented Feb 12, 2016 at 5:37
  • I added global $user_country; but no change. Commented Feb 12, 2016 at 5:39
  • Where is the class located and what is the php file called? include_once("geoip.inc"); does not seem right. It should have a .php extension. Commented Feb 12, 2016 at 6:29
  • Also class_exists(GeoIP) should have quotes: class_exists('GeoIP') Commented Feb 12, 2016 at 6:30

2 Answers 2

1

Forgetting about bad design and bad code (try to avoid coupling arbitrary functions to some global variable. Then again, your using Wordpress you are already ballz deep in bad bad code), there are at least three ways you can achieve what you want.

  1. Use a global:
$global = 88;
function foo() {
  global $global;
  $global = 527;
}
print $global; // prints 88;
foo();
print $global; // prints 527;
  1. Pass by reference:
function foo(&$myRef) {
 $myRef = 527;
}
$x = 88;
foo($x); // now $x has the value 527. But you still need to pass it to the next function.
  1. Classes. The global namespace is kind of like a global anonymous class that everything is contained in. But its better to define classes to contain variables and the functions that share the variables:
class MySetOfArbitraryStaitcFunctions {
  private static $myVar;
  public static function foo() {
    $myVar = 527;
  }
  public static function printMyVar() {
    print self::$myVar();
  }

Then of course you have ways where you store your var in some third party globally accessible storage like sessions or a database. But essentially your doing the same thing as sharing a global variable by sharing the thing the variable is stored in.

Sign up to request clarification or add additional context in comments.

Comments

1

What you may want to be using is a class inside a function, something like:

class   GetUserGeo
    {
        protected   $ip;

        protected   function getIpv()
            {
                return (filter_var($this->ip, FILTER_VALIDATE_IP,FILTER_FLAG_IPV4) !== false);
            }

        protected   function getRemoteAddress()
            {
                $this->ip   =   (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];
                return $this;
            }

        public  function getUserCountry()
            {
                if (!class_exists('GeoIP'))
                    include_once("geoip.inc");

                $ipv4       =   $this->getRemoteAddress()->getIpv();
                $path       =   WP_PLUGIN_DIR.'/location-specific-menu-items';
                $gPath      =   ($ipv4)? '/GeoIP.dat' : '/V6GeoIP.dat';
                $gi         =   \LSMIGeoIP\geoip_open($path.$gPath, GEOIP_STANDARD);
                $country    =   \LSMIGeoIP\geoip_country_code_by_addr($gi, $this->ip);
                \LSMIGeoIP\geoip_close($gi);

                return (empty($country))? 'Could not retrieve your location' : $country;
            }
    }

function get_user_country()
    {
        $co =   new GetUserGeo();
        return $co->getUserCountry();
    }

2 Comments

Ok, I try this. What part of the include path looks off? The file lives in the root of the plugin. In any event, it's working!
Ok I looked at the naming convention of the .inc it's just a different naming convention but your server has to be configured to parse it as php so that is legit. I will modify mine back to that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.