class.IP2Proxy.php
protected function lookup($ip, $fields = null, $asNamed = true) {
    // extract IP version and number
    list($ipVersion, $ipNumber) = self::ipVersionAndNumber($ip);
    // perform the binary search proper (if the IP address was invalid, binSearch will return false)
    $pointer = $this->binSearch($ipVersion, $ipNumber);

    // apply defaults if needed
    if (null === $fields) {
      $fields = $this->defaultFields;
    }

    // turn fields into an array in case it wasn't already
    $ifields = (array) $fields;
    // add fields if needed
    if (in_array(self::ALL, $ifields)) {
      $ifields[] = self::REGION_NAME;
      $ifields[] = self::CITY_NAME;
      $ifields[] = self::ISP;
      $ifields[] = self::IS_PROXY;
      $ifields[] = self::PROXY_TYPE;
      $ifields[] = self::COUNTRY;
      $ifields[] = self::IP_ADDRESS;
      $ifields[] = self::IP_VERSION;
      $ifields[] = self::IP_NUMBER;
    }
    // turn into a uniquely-valued array the fast way
    // (see: http://php.net/manual/en/function.array-unique.php#77743)
    $afields = array_keys(array_flip($ifields));
    // sorting them in reverse order warrants that by the time we get to
    // SINGULAR fields, its MULTIPLE counterparts, if at all present, have
    // already been retrieved
    rsort($afields);

    // maintain a list of already retrieved fields to avoid doing it twice
    $done    = [
        self::COUNTRY_CODE => false,
        self::COUNTRY_NAME => false,
        self::REGION_NAME  => false,
        self::CITY_NAME    => false,
        self::ISP          => false,
        self::IS_PROXY     => false,
        self::PROXY_TYPE   => false,
        self::COUNTRY      => false,
        self::IP_ADDRESS   => false,
        self::IP_VERSION   => false,
        self::IP_NUMBER    => false,
    ];
    // results are empty to begin with
    $results = [];

    // treat each field in turn
    foreach ($afields as $afield) {
      switch ($afield) {
        // purposefully ignore self::ALL, we already dealt with it
        case self::ALL: break;
        //
        case self::COUNTRY:
          if (!$done[self::COUNTRY]) {
            list($results[self::COUNTRY_NAME], $results[self::COUNTRY_CODE]) = $this->readCountryNameAndCode($pointer);
            $done[self::COUNTRY]      = true;
            $done[self::COUNTRY_CODE] = true;
            $done[self::COUNTRY_NAME] = true;
          }
          break;
        case self::COUNTRY_CODE:
          if (!$done[self::COUNTRY_CODE]) {
            $results[self::COUNTRY_CODE] = $this->readCountryNameAndCode($pointer)[1];
            $done[self::COUNTRY_CODE]    = true;
          }
          break;
        case self::COUNTRY_NAME:
          if (!$done[self::COUNTRY_CODE]) {
            $results[self::COUNTRY_CODE] = $this->readCountryNameAndCode($pointer)[0];
            $done[self::COUNTRY_CODE]    = true;
          }
          break;
        case self::REGION_NAME:
          if (!$done[self::REGION_NAME]) {
            $results[self::REGION_NAME] = $this->readRegionName($pointer);
            $done[self::REGION_NAME]    = true;
          }
          break;
        case self::CITY_NAME:
          if (!$done[self::CITY_NAME]) {
            $results[self::CITY_NAME] = $this->readCityName($pointer);
            $done[self::CITY_NAME]    = true;
          }
          break;
        case self::ISP:
          if (!$done[self::ISP]) {
            $results[self::ISP] = $this->readIsp($pointer);
            $done[self::ISP]    = true;
          }
          break;
    case self::PROXY_TYPE:
          if (!$done[self::PROXY_TYPE]) {
            $results[self::PROXY_TYPE] = $this->readProxyType($pointer);
            $done[self::PROXY_TYPE]    = true;
          }
          break;
    case self::IS_PROXY:
          if (!$done[self::IS_PROXY]) {
      // px1
      if ($this->type == 0) {
        $countryCode = $this->readCountryNameAndCode($pointer)[1];

        $results[self::IS_PROXY] = ($countryCode == '-') ? 0 : 1;

        if (strlen($countryCode) > 2) {
          $results[self::IS_PROXY] = -1;
        }
      }
      else{
        $proxyType = $this->readProxyType($pointer);

        $results[self::IS_PROXY] = ($proxyType == '-') ? 0 : (($proxyType == 'DCH') ? 2 : 1);

        if (strlen($proxyType) > 3) {
          $results[self::IS_PROXY] = -1;
        }
      }

            $done[self::IS_PROXY]    = true;
          }
          break;
        case self::IP_ADDRESS:
          if (!$done[self::IP_ADDRESS]) {
            $results[self::IP_ADDRESS] = $ip;
            $done[self::IP_ADDRESS]    = true;
          }
          break;
        case self::IP_VERSION:
          if (!$done[self::IP_VERSION]) {
            $results[self::IP_VERSION] = $ipVersion;
            $done[self::IP_VERSION]    = true;
          }
          break;
        case self::IP_NUMBER:
          if (!$done[self::IP_NUMBER]) {
            $results[self::IP_NUMBER] = $ipNumber;
            $done[self::IP_NUMBER]    = true;
          }
          break;
        //
        default:
          $results[$afield] = self::FIELD_NOT_KNOWN;
      }
    }

    // If we were asked for an array, or we have multiple results to return...
    if (is_array($fields) || count($results) > 1) {
      // return array
      if ($asNamed) {
        // apply translations if needed
        $return = [];
        foreach ($results as $key => $val) {
          if (array_key_exists($key, static::$names)) {
            $return[static::$names[$key]] = $val;
          } else {
            $return[$key] = $val;
          }
        }
        return $return;
      } else {
        return $results;
      }
    } else {
      // return a single value
      return array_values($results)[0];
    }
  }
protected function lookup($ip, $fields = null, $asNamed = true) {
    // extract IP version and number
    list($ipVersion, $ipNumber) = self::ipVersionAndNumber($ip);
    // perform the binary search proper (if the IP address was invalid, binSearch will return false)
    $pointer = $this->binSearch($ipVersion, $ipNumber);

    // apply defaults if needed
    if (null === $fields) {
      $fields = $this->defaultFields;
    }

    // turn fields into an array in case it wasn't already
    $ifields = (array) $fields;
    // add fields if needed
    if (in_array(self::ALL, $ifields)) {
      $ifields[] = self::REGION_NAME;
      $ifields[] = self::CITY_NAME;
      $ifields[] = self::ISP;
      $ifields[] = self::IS_PROXY;
      $ifields[] = self::PROXY_TYPE;
      $ifields[] = self::COUNTRY;
      $ifields[] = self::IP_ADDRESS;
      $ifields[] = self::IP_VERSION;
      $ifields[] = self::IP_NUMBER;
    }
    // turn into a uniquely-valued array the fast way
    // (see: http://php.net/manual/en/function.array-unique.php#77743)
    $afields = array_keys(array_flip($ifields));
    // sorting them in reverse order warrants that by the time we get to
    // SINGULAR fields, its MULTIPLE counterparts, if at all present, have
    // already been retrieved
    rsort($afields);

    // maintain a list of already retrieved fields to avoid doing it twice
    $done    = [
        self::COUNTRY_CODE => false,
        self::COUNTRY_NAME => false,
        self::REGION_NAME  => false,
        self::CITY_NAME    => false,
        self::ISP          => false,
        self::IS_PROXY     => false,
        self::PROXY_TYPE   => false,
        self::COUNTRY      => false,
        self::IP_ADDRESS   => false,
        self::IP_VERSION   => false,
        self::IP_NUMBER    => false,
    ];
    // results are empty to begin with
    $results = [];

    // treat each field in turn
    foreach ($afields as $afield) {
      switch ($afield) {
        // purposefully ignore self::ALL, we already dealt with it
        case self::ALL: break;
        //
        case self::COUNTRY:
          if (!$done[self::COUNTRY]) {
            list($results[self::COUNTRY_NAME], $results[self::COUNTRY_CODE]) = $this->readCountryNameAndCode($pointer);
            $done[self::COUNTRY]      = true;
            $done[self::COUNTRY_CODE] = true;
            $done[self::COUNTRY_NAME] = true;
          }
          break;
        case self::COUNTRY_CODE:
          if (!$done[self::COUNTRY_CODE]) {
            $results[self::COUNTRY_CODE] = $this->readCountryNameAndCode($pointer)[1];
            $done[self::COUNTRY_CODE]    = true;
          }
          break;
        case self::COUNTRY_NAME:
          if (!$done[self::COUNTRY_CODE]) {
            $results[self::COUNTRY_CODE] = $this->readCountryNameAndCode($pointer)[0];
            $done[self::COUNTRY_CODE]    = true;
          }
          break;
        case self::REGION_NAME:
          if (!$done[self::REGION_NAME]) {
            $results[self::REGION_NAME] = $this->readRegionName($pointer);
            $done[self::REGION_NAME]    = true;
          }
          break;
        case self::CITY_NAME:
          if (!$done[self::CITY_NAME]) {
            $results[self::CITY_NAME] = $this->readCityName($pointer);
            $done[self::CITY_NAME]    = true;
          }
          break;
        case self::ISP:
          if (!$done[self::ISP]) {
            $results[self::ISP] = $this->readIsp($pointer);
            $done[self::ISP]    = true;
          }
          break;
    case self::PROXY_TYPE:
          if (!$done[self::PROXY_TYPE]) {
            $results[self::PROXY_TYPE] = $this->readProxyType($pointer);
            $done[self::PROXY_TYPE]    = true;
          }
          break;
    case self::IS_PROXY:
          if (!$done[self::IS_PROXY]) {
      // px1
      if ($this->type == 0) {
        $countryCode = $this->readCountryNameAndCode($pointer)[1];

        $results[self::IS_PROXY] = ($countryCode == '-') ? 0 : 1;

        if (strlen($countryCode) > 2) {
          $results[self::IS_PROXY] = -1;
        }
      }
      else{
        $proxyType = $this->readProxyType($pointer);

        $results[self::IS_PROXY] = ($proxyType == '-') ? 0 : (($proxyType == 'DCH') ? 2 : 1);

        if (strlen($proxyType) > 3) {
          $results[self::IS_PROXY] = -1;
        }
      }

            $done[self::IS_PROXY]    = true;
          }
          break;
        case self::IP_ADDRESS:
          if (!$done[self::IP_ADDRESS]) {
            $results[self::IP_ADDRESS] = $ip;
            $done[self::IP_ADDRESS]    = true;
          }
          break;
        case self::IP_VERSION:
          if (!$done[self::IP_VERSION]) {
            $results[self::IP_VERSION] = $ipVersion;
            $done[self::IP_VERSION]    = true;
          }
          break;
        case self::IP_NUMBER:
          if (!$done[self::IP_NUMBER]) {
            $results[self::IP_NUMBER] = $ipNumber;
            $done[self::IP_NUMBER]    = true;
          }
          break;
        //
        default:
          $results[$afield] = self::FIELD_NOT_KNOWN;
      }
    }

    // If we were asked for an array, or we have multiple results to return...
    if (is_array($fields) || count($results) > 1) {
      // return array
      if ($asNamed) {
        // apply translations if needed
        $return = [];
        foreach ($results as $key => $val) {
          if (array_key_exists($key, static::$names)) {
            $return[static::$names[$key]] = $val;
          } else {
            $return[$key] = $val;
          }
        }
        return $return;
      } else {
        return $results;
      }
    } else {
      // return a single value
      return array_values($results)[0];
    }
  }
This function will look the given IP address up in the database and return the result(s) asked for

If a single, SINGULAR, field is specified, only its mapped value is returned.
If many fields are given (as an array) or a MULTIPLE field is specified, an
array whith the returned singular field names as keys and their corresponding
values is returned.

@access protected
@param string $ip  IP address to look up
@param int|array $fields  Field(s) to return
@param boolean $asNamed  Whether to return an associative array instead
@return mixed|array|boolean