Net_Geo
[ class tree: Net_Geo ] [ index: Net_Geo ] [ all elements ]

Source for file Geo.php

Documentation is available at Geo.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Graeme Merrall <graeme@inetix.com.au>                       |
  17. // |          Darren Ehlers <darren@ehlersconsulting.net>                 |
  18. // |                                                                      |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: Geo.php 304669 2010-10-24 01:54:39Z clockwerx $
  22.  
  23. require_once 'PEAR.php';
  24. require_once 'Cache/Function.php';
  25.  
  26. /**
  27.  * NetGeo - determine geographic information on an internet address
  28.  *
  29.  * Can accept input of an AS number, an IP address or a host name
  30.  * Input can be individual or an array of addresses
  31.  *
  32.  * $geo = new Net_Geo();
  33.  * $geo->getRecord("php.net");
  34.  * $geo->getRecord(array("php.net", "google.com"));
  35.  *
  36.  * Results returned are a single array of results if a string is passed in
  37.  * or in the case of an array, a multi-dim array with the as the key
  38.  *
  39.  * Query service type (CAIDA or localizer) is not available as a constructer
  40.  * to retain compatibility with existing CAIDA NetGeo classes (perl + java)
  41.  *
  42.  * CHANGES -- 2006-03-16 Darren Ehlers <darren@ehlersconsulting.net>
  43.  * |
  44.  * - Added support for the HostIP service, which still retaining the same
  45.  *   existing functionality (by default).  To use the HostIP service, simply
  46.  *   add the setService() call as in the following example:
  47.  *
  48.  *   > $geo = new Net_Geo();
  49.  *   > $geo->setService('hostip');
  50.  *   > $geo->getRecord("php.net");
  51.  *
  52.  * - Fixed a number of minor bugs, specifically related to providing
  53.  *   alternate URLs.
  54.  *
  55.  * - Fixed code to allow changing the current service via the setService call,
  56.  *   without having to create a new object.
  57.  *
  58.  * - Added RAWDATA result array item which contains the complete returned
  59.  *   array data.  The rest of the result array for the HostIP service is
  60.  *   setup to match the existing CAIDA result array.
  61.  * |
  62.  * CHANGES -- 2006-03-16 Darren Ehlers <darren@ehlersconsulting.net>
  63.  *
  64.  * @version 1.0.4
  65.  * @package NetGeo
  66.  * @author Darren Ehlers <darren@ehlersconsulting.net>
  67.  * @author Graeme Merrall <graeme@inetix.com.au>
  68.  */
  69.  
  70. define('NETGEO_INPUT_ERROR''INPUT_ERROR');
  71. define('NETGEO_HTTP_ERROR''HTTP_ERROR');
  72. define('NETGEO_NO_MATCH''NO MATCH');
  73. define('NETGEO_NO_COUNTRY''NO_COUNTRY');
  74. define('NETGEO_LIMIT_EXCEEDED''NETGEO_LIMIT_EXCEEDED');
  75.  
  76. class Net_Geo
  77. {
  78.  
  79.     /**
  80.      * Path to local cache file.
  81.      * Caching is compulsory to reduce load on CAIDA server
  82.      *
  83.      * @var string 
  84.      * @access public
  85.      */
  86.     var $cache_path "/tmp/";
  87.  
  88.     /**
  89.      * How long to wait befire rechecking cached entries in *days*
  90.      * This should be something nice and high
  91.      *
  92.      * @var in 
  93.      * @access public
  94.      */
  95.     var $cache_ttl = 30;
  96.  
  97.      /**
  98.      * CAIDA only
  99.      *
  100.      * Maximum length of time, in seconds, which will be allowed during a whois
  101.      * lookup by the NetGeo server.
  102.      * The actual default value is maintained by the server.
  103.      *
  104.      * @var int 
  105.      * @access public
  106.      */
  107.     var $default_timeout = 60;
  108.  
  109.     /**
  110.      * CAIDA only
  111.      *
  112.      * Location of the default netgeo server
  113.      * If port not specified, defaults to 80
  114.      *
  115.      * @var string 
  116.      * @access public
  117.      */
  118.     var $default_caida_server "http://netgeo.caida.org/perl/netgeo.cgi";
  119.  
  120.     /**
  121.      * HostIP only
  122.      *
  123.      * Location of the default hostip server
  124.      * If port not specified, defaults to 80
  125.      *
  126.      * @var string 
  127.      * @access public
  128.      */
  129.     var $default_hostip_server "http://api.hostip.info/";
  130.  
  131.     /**
  132.      * localizer only
  133.      *
  134.      * Location of the localizer data file
  135.      *
  136.      * @var string 
  137.      * @access public
  138.      */
  139.     var $localizer_data "./demo.csv";
  140.  
  141.     /**
  142.      * Type of service to use. May be either 'caida' or 'localizer'
  143.      * Default is 'caida'
  144.      *
  145.      * @var string 
  146.      @ @access private
  147.      */
  148.     var $service;
  149.  
  150.     /**
  151.      * Cache filename prefix
  152.      *
  153.      * @var string 
  154.      * @access private
  155.      */
  156.      var $cache_prefix "netgeo";
  157.  
  158.     /**
  159.      * CAIDA only
  160.      *
  161.      * User Agent string.
  162.      *
  163.      * @var string 
  164.      * @access private
  165.      */
  166.     var $useragent "PHP/NetGeo";
  167.  
  168.     /**
  169.      * CAIDA only
  170.      *
  171.      * Class version
  172.      *
  173.      * @var string 
  174.      * @access private
  175.      */
  176.     var $useragent_version "1.0";
  177.  
  178.     /**
  179.      * CAIDA only
  180.      *
  181.      * How many targets can be read in at once
  182.      * Should be enough for most everyone
  183.      *
  184.      * @var string 
  185.      * @access private
  186.      */
  187.     var $array_limit = 100;
  188.  
  189.     /**
  190.      * Function cache object
  191.      *
  192.      * @var object 
  193.      * @access private
  194.      */
  195.      var $cache;
  196.  
  197.     /**
  198.      * Name of global var for copying $this when calling function cache
  199.      * This is needed for the cache function to operate correctly
  200.      *
  201.      * @var string 
  202.      * @access private
  203.      */
  204.      var $netgeo_global "netgeo_global";
  205.  
  206.     /**
  207.      * Complete User Agent string + version
  208.      *
  209.      * @var string 
  210.      * @access private
  211.      */
  212.      var $useragent_string;
  213.  
  214.     /**
  215.      * Location of the default server
  216.      * If port not specified, defaults to 80
  217.      *
  218.      * @var string 
  219.      * @access private
  220.      */
  221.      var $default_server;
  222.  
  223.     /**
  224.      * Value of last "target" lookup
  225.      *
  226.      * @var string 
  227.      * @access private
  228.      */
  229.      var $last_target;
  230.  
  231.     /**
  232.      * Constructor
  233.      * Both $applicationName and $alternateServerUrl are for compatibility
  234.      * with the perl and java netgeo classes.
  235.      * I don't guarantee to use these variables
  236.      *
  237.      * @param string $applicationName    Application using the NetGeo class.
  238.      * @param string $alternateServerUrl Alternate NetGeo server url
  239.      * @return bool 
  240.      * @access public
  241.      */
  242.     function Net_Geo($applicationName=""$alternateServerUrl="")
  243.     {
  244.         $this->applicationName $applicationName;
  245.         $this->alternateServerUrl $alternateServerUrl;
  246.  
  247.         // init cache object
  248.         $this->cache = new Cache_Function('file',
  249.                                           array('cache_dir' => $this->cache_path,
  250.                                                 'filename_prefix' => $this->cache_prefix
  251.                                                ),
  252.                                           $this->cache_ttl * 86400
  253.                                          );
  254.  
  255.         return true;
  256.     }
  257.  
  258.     /**
  259.      * Sets the service to use to lookup data (defaults to 'caida')
  260.      *
  261.      * @param string $service Service to use (caida, hostip or localizer)
  262.      * @return bool 
  263.      * @access public
  264.      */
  265.     function setService($service "caida")
  266.     {
  267.         if ($service == "localizer"{
  268.  
  269.             if (@localizer_read($this->localizer_dataFALSE== FALSE{
  270.                 PEAR::raiseError("Can't read localizer data file ".$this->localizer_data);
  271.                 return false;
  272.             }
  273.  
  274.         elseif ($service == "caida"{
  275.  
  276.             // check to see if an alternate server URL is used
  277.             if (!empty($this->alternateServerUrl)) {
  278.                 $this->default_server $this->alternateServerUrl;
  279.             }
  280.             else {
  281.                 $this->default_server $this->default_caida_server;
  282.             }
  283.  
  284.             $this->useragent_string sprintf("%s %s"$this->useragent,
  285.                                                     $this->useragent_version
  286.                                       );
  287.  
  288.             // set the custom user agent
  289.             if (!empty($this->applicationName)) {
  290.                 // trim whitespace
  291.                 $this->applicationName trim($this->applicationName);
  292.  
  293.                 // also set the agent name
  294.                 $this->useragent_string sprintf("%s/%s"$this->applicationName,
  295.                                                             $this->useragent
  296.                                           );
  297.             }
  298.  
  299.         elseif ($service == "hostip"{
  300.  
  301.             // check to see if an alternate server URL is used
  302.             if (!empty($this->alternateServerUrl)) {
  303.                 $this->default_server $this->alternateServerUrl;
  304.             }
  305.             else {
  306.                 $this->default_server $this->default_hostip_server;
  307.             }
  308.  
  309.             $this->useragent_string sprintf("%s %s"$this->useragent,
  310.                                                         $this->useragent_version
  311.                                       );
  312.  
  313.             // set the custom user agent
  314.             if (!empty($this->applicationName)) {
  315.                 // trim whitespace
  316.                 $this->applicationName trim($this->applicationName);
  317.  
  318.                 // also set the agent name
  319.                 $this->useragent_string sprintf("%s/%s"$this->applicationName,
  320.                                                             $this->useragent
  321.                                           );
  322.             }
  323.  
  324.         else {
  325.  
  326.             // return error
  327.             return new PEAR_Error("No service specified");
  328.  
  329.         }
  330.  
  331.         $this->service $service;
  332.         return true;
  333.     }
  334.  
  335.     /**
  336.      * Gets a complete record for an address
  337.      * Returns either a single or multidimentional arrray
  338.      * if input is a string or an array respectively
  339.      *
  340.      * @param mixed $target Single or list of addresses
  341.      * @return array 
  342.      * @access public
  343.      */
  344.     function getRecord($target)
  345.     {
  346.         return $this->_execute("getRecord"$target);
  347.     }
  348.  
  349.     /**
  350.      * Returns the 2-letter ISO 3166 country code
  351.      * Returns NO_MATCH if the AS number has been looked up
  352.      * but nothing was found in the whois lookups.
  353.      * Returns NO_COUNTRY if the lookup returned a record
  354.      * but no country could be found.
  355.      * Returns an empty string if nothing was found in the database
  356.      *
  357.      * @param string $target single address
  358.      * @return array 
  359.      * @access public
  360.      */
  361.     function getCountry($target)
  362.     {
  363.         $result $this->_execute("getCountry"$target);
  364.         if (is_array($result)) {
  365.             return $result["COUNTRY"];
  366.         }
  367.  
  368.         return $result;
  369.     }
  370.  
  371.     /**
  372.      * Returns an array with keys LAT, LONG, LAT_LONG_GRAN, and STATUS.
  373.      * Lat/Long will be (0,0) if the target has been looked up but there was no
  374.      * match in the whois lookups, or if no address could be parsed from the
  375.      * whois record, or if the lat/long for the address is unknown.
  376.      * Returns an empty string if nothing was found in the database
  377.      *
  378.      * @param string $target single address
  379.      * @return array 
  380.      * @access public
  381.      */
  382.     function getLatLong($target)
  383.     {
  384.         return $this->_execute("getLatLong"$target);
  385.     }
  386.  
  387.     /**
  388.      * Included here to make the NetGeo class as similar as possible to
  389.      * the NetGeoClient.java interface.
  390.      * It's probably just as easy for the user to extract lat and long directly
  391.      * from the array.
  392.      *
  393.      * @param string $target single address
  394.      * @return double 
  395.      * @access public
  396.     */
  397.     function getLat($latLongRef)
  398.     {
  399.         if (is_array($latLongRef)) {
  400.             $lat $latLongRef["LAT"];
  401.         else {
  402.             $lat = 0;
  403.         }
  404.  
  405.         return sprintf("%.2f"$lat);
  406.     }
  407.  
  408.     /**
  409.      * Included here to make the NetGeo class as similar as possible to
  410.      * the NetGeoClient.java interface.
  411.      * It's probably just as easy for the user to extract lat and long directly
  412.      * from the array
  413.      *
  414.      * @param string $target single address
  415.      * @return double 
  416.      * @access public
  417.      */
  418.     function getLong($latLongHashRef)
  419.     {
  420.         if (is_array($latLongHashRef)) {
  421.             $long $latLongHashRef["LONG"];
  422.         else {
  423.             $long = 0;
  424.         }
  425.  
  426.         return sprintf("%.2f"$long);
  427.     }
  428.  
  429.     /**
  430.      * Interface to the public functions
  431.      *
  432.      * @param string $methodName Lookup method
  433.      * @param mixed  $target     Address(es) to lookup
  434.      * @return array 
  435.      * @access private
  436.      */
  437.     function _execute($methodName$input)
  438.     {
  439.         // if we haven't got a service set, then do it now
  440.         if (empty($this->service)) {
  441.             $this->setService();
  442.         }
  443.  
  444.         // Test the target strings in the input array.  Any targets not in
  445.         // an acceptable format will have their STATUS field set to INPUT_ERROR.
  446.         // This method will also store the standardized target into the array
  447.         // for use as a key in the cache table.
  448.         $inputArray $this->_verifyInputFormatArray($methodName$input);
  449.         if (PEAR::isError($inputArray)) {
  450.             return $inputArray;
  451.         }
  452.  
  453.         $resultArray $this->_processArray($methodName$inputArray);
  454.  
  455.         // if there is only one array, move the whole thing up one
  456.         if (count($resultArray== 1{
  457.             $resultArray $resultArray[0];
  458.         }
  459.  
  460.         return $resultArray;
  461.     }
  462.  
  463.     /**
  464.      * Verify the type of the target argument and verify types of array elements
  465.      * Also converts the input array into the start of the output array
  466.      *
  467.      * @param string $methodName Lookup method
  468.      * @param mixed  $inputArray Address(es) to lookup
  469.      * @return array or pear error object on failure
  470.      * @access private
  471.      */
  472.     function _verifyInputFormatArray($methodName$inputArray)
  473.     {
  474.         // makes sure that the input is an array
  475.         // if length is > than ARRAY_LIMIT_LENTH then bomb ou
  476.         if (count($inputArray$this->array_limit{
  477.             // raise an error
  478.             $error = new PEAR_Error("Too many entries. Limit is ".$this->array_limit);
  479.             return $error;
  480.         }
  481.  
  482.         // convert into a useable array
  483.         $inputArray $this->_convertInputArray($inputArray);
  484.         return $inputArray;
  485.     }
  486.  
  487.     /**
  488.      * Utility function to check what the input array
  489.      * and to convert to a correct array format for processing
  490.      *
  491.      * @param mixed $inputArray Address array
  492.      * @return array 
  493.      * @access private
  494.      */
  495.     function _convertInputArray($inputArray)
  496.     {
  497.         // first check the darn thing is actually an array
  498.         if (!is_array($inputArray)) {
  499.             $inputArray = array($inputArray);
  500.         }
  501.  
  502.         // now convert to the correct array form
  503.         foreach ($inputArray as $entry{
  504.             $returnArray[]["TARGET"$entry;
  505.         }
  506.  
  507.         return $returnArray;
  508.     }
  509.  
  510.  
  511.     /**
  512.      * Main function that processes addresses
  513.      *
  514.      * It might be a good idea to move the caching up one level?
  515.      *
  516.      * @param string $methodName Lookup method
  517.      * @param array  $inputArray Formatted address array
  518.      * @return array 
  519.      * @access private
  520.      */
  521.     function _processArray($methodName$inputArray)
  522.     {
  523.         $i = 0;
  524.         foreach ($inputArray as $entry{
  525.             $entry $this->_verifyInputFormat($entry);
  526.  
  527.             if (isset($entry["TARGET"]&& !isset($entry["INPUT_ERROR"])) {
  528.  
  529.                 $this->last_target $entry["TARGET"];
  530.  
  531.                 // set up the cache work around
  532.                 $GLOBALS[$this->netgeo_global=$this;
  533.  
  534.                 if ($this->service == "localizer"{
  535.  
  536.                     $response $this->cache->call('localizer_search'$entry["TARGET"]);
  537.  
  538.                 elseif ($this->service == 'hostip'{
  539.  
  540.                     if (ip2long($entry["TARGET"]=== false{
  541.  
  542.                          $ip gethostbyname($entry["TARGET"]);
  543.                      else {
  544.  
  545.                          $ip $entry["TARGET"];
  546.                      }
  547.  
  548.                     $url sprintf("%s?ip=%s"$this->default_server,
  549.                                                $ip
  550.                                   );
  551.  
  552.                     $response =$this->cache->call($this->netgeo_global.'->_executeHttpRequest'$url);
  553.  
  554.                 else {
  555.  
  556.                     // else do the HTTP request
  557.                     $url sprintf("%s?method=%s&target=%s"$this->default_server,
  558.                                                              $methodName$entry["TARGET"]
  559.                                   );
  560.  
  561.                     $response =$this->cache->call($this->netgeo_global.'->_executeHttpRequest'$url);
  562.  
  563.                 }
  564.  
  565.                 if (!isset($response)) {
  566.                     $entry["STATUS"NETGEO_HTTP_ERROR;
  567.                 }
  568.  
  569.                 // parse it all into something useful
  570.                 // at this point we should look for NETGEO_LIMIT_EXCEEDED as well
  571.                 $dataArray[$i$this->_processResult($response);
  572.  
  573.             else {
  574.                 $dataArray[$i$entry;
  575.             }
  576.  
  577.             $i++;
  578.         }
  579.  
  580.         if (is_array($dataArray)) {
  581.             return $dataArray;
  582.         else {
  583.             return array("STATUS"=>NETGEO_HTTP_ERROR);
  584.         }
  585.     }
  586.  
  587.     /**
  588.      * Test the input and make sure it is in an acceptable format.  The input
  589.      * can be an AS number (with or without a leading "AS"), an IP address in
  590.      * dotted decimal format, or a domain name.  Stores the standardized targe
  591.      * string into the hash if input target is valid format, otherwise stores
  592.      * undef into hash.
  593.      *
  594.      * @param array  $inputArray Address(es) to lookup
  595.      * @return array 
  596.      * @access private
  597.      */
  598.     function _verifyInputFormat($inputArray)
  599.     {
  600.         $target trim($inputArray["TARGET"]);
  601.  
  602.         // look for AS|as
  603.         if (preg_match('/^(?:AS|as)?\s?(\d{1,})$/'$target$matches)) {
  604.  
  605.             // check the AS number. Btwn 1 and 65536
  606.             if ($matches[1>= 1 && $matches[1< 65536{
  607.                 $standardizedTarget $matches[0];
  608.             else {
  609.                 $inputArray["INPUT_ERROR"NETGEO_INPUT_ERROR;
  610.                 // raise some error tex
  611.                 // Bad format for input. AS number must be between 1 and 65536
  612.                 return $inputArray;
  613.             }
  614.  
  615.         // IP number
  616.         elseif (preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/'$target$matches)) {
  617.  
  618.             if ($matches[1<= 255 && $matches[2<= 255 && $matches[3<= 255 && $matches[4<= 255{
  619.                 $standardizedTarget $target;
  620.             else {
  621.                 $inputArray["INPUT_ERROR"NETGEO_INPUT_ERROR;
  622.                 // raise some error tex
  623.                 // Bad format for input. each octet in IP address must be between 0 and 255
  624.                 return $inputArray;
  625.             }
  626.  
  627.         // TLD
  628.         elseif (preg_match('/^(?:[\w\-]+\.)*[\w\-]+\.([A-Za-z]{2,3})$/'$target$matches)) {
  629.  
  630.             $tld $matches[1];
  631.  
  632.             // TLD length is either 2 or 3.  If length is 2 we just accept it,
  633.             // otherwise we test the TLD against the list.
  634.             if (strlen($tld== 2 || preg_match('/^(com|net|org|edu|gov|mil|int)/i'$tld)) {
  635.                 $standardizedTarget $target;
  636.             else {
  637.                 $inputArray["INPUT_ERROR"NETGEO_INPUT_ERROR;
  638.                 // raise some error tex
  639.                 // Bad TLD in domain name. 3-letter TLDs must be one of com,net,org,edu,gov,mil,in
  640.                 return $inputArray;
  641.             }
  642.  
  643.         else {
  644.  
  645.             $inputArray["INPUT_ERROR"NETGEO_INPUT_ERROR;
  646.             // raise some error text
  647.             // unrecognized format for input
  648.             return $inputArray;
  649.  
  650.         }
  651.  
  652.         return $inputArray;
  653.     }
  654.  
  655.     /**
  656.      * Executes a request to the netgeo server
  657.      *
  658.      * @param array $inputArray Address(es) to lookup
  659.      * @return string Response from netgeo server
  660.      * @access private
  661.      */
  662.     function _executeHttpRequest($url)
  663.     {
  664.         $response "";
  665.  
  666.         if (function_exists('curl_init')) {
  667.             $ch = curl_init($url);
  668.             curl_setopt($chCURLOPT_RETURNTRANSFER1);
  669.             $response = curl_exec($ch);
  670.             curl_close($ch);
  671.         else {
  672.             // split the server url
  673.             $urlinfo parse_url($url);
  674.             if (!isset($urlinfo["port"])) {
  675.                 $urlinfo["port"= 80;
  676.             }
  677.  
  678.             $sp @fsockopen($urlinfo["host"]$urlinfo["port"]$errno$errstr$this->default_timeout);
  679.             if (!$sp{
  680.                 return false;
  681.             }
  682.  
  683.             fputs($sp"GET " $urlinfo["path"."?"$urlinfo["query"" HTTP/1.0\r\n");
  684.             fputs($sp"User-Agent: " $this->useragent_string "\r\n\r\n");
  685.             while (!feof($sp)) {
  686.                 $response .= fgets($sp,128);
  687.             }
  688.             fclose ($sp);
  689.         }
  690.  
  691.         return $response;
  692.     }
  693.  
  694.     /**
  695.      * Parses the results from the server into an array
  696.      *
  697.      * @param string $response Response from netgeo server
  698.      * @return array 
  699.      * @access private
  700.      */
  701.     function _processResult($response)
  702.     {
  703.         // process the localizer result differently
  704.         // since we already have an array
  705.         if ($this->service == "localizer"{
  706.  
  707.             foreach ($response as $key=>$val{
  708.  
  709.                 $retarray[strtoupper($key)$val;
  710.             }
  711.  
  712.         elseif ($this->service == "caida"{
  713.  
  714.             $lineArray preg_split("/\n/"$response);
  715.             $line array_shift($lineArray);
  716.  
  717.             // first check for anything icky from the server
  718.             if (preg_match("/".NETGEO_HTTP_ERROR."/"$line|| preg_match('/^\s*$/'$response)) {
  719.  
  720.                 // empty empty empty
  721.                 if (preg_match('/^\s*$/'$text)) {
  722.                     $text "Empty content string";
  723.                     return array("STATUS"=>$text);
  724.                 }
  725.  
  726.             elseif (preg_match("/".NETGEO_LIMIT_EXCEEDED."/"$line)) {
  727.                 $text 'Query limit exceeded';
  728.                 return array("STATUS"=>$text);
  729.             }
  730.  
  731.             // now loop through. This should being us out at TARGET
  732.             while (isset($line&& !preg_match("/^TARGET:/"$line)) {
  733.                 $line array_shift($lineArray);
  734.             }
  735.  
  736.             // keep going
  737.             while (isset($line)) {
  738.                 if (preg_match("/^TARGET:\s+(.*\S)\s*<br>/"$line$matches)) {
  739.                     $retval["TARGET"$matches[1];
  740.                 elseif (preg_match("/^STATUS:\s+([\w\s]+\S)\s*<br>/"$line$matches)) {
  741.                     $retval["STATUS"$matches[1];
  742.                 elseif (preg_match("/^(\w+):\s+(.*\S)\s*<br>/"$line$matches)) {
  743.                     $retval[$matches[1]] $matches[2];
  744.                 }
  745.                 $line array_shift($lineArray);
  746.             }
  747.  
  748.             $retarray $retval;
  749.             $retarray['RAWDATA']    $retval;
  750.  
  751.         elseif ($this->service == "hostip"{
  752.  
  753.             $options = array(    'addDecl'            => TRUE,
  754.                                    'encoding'             => 'ISO-8859-1',
  755.                                    'indent'             => '  ',
  756.                                    'indentAttributes'     => '_auto',
  757.                                    'rootName'             => __CLASS__,
  758.                                    'defaultTagName'     => 'members',
  759.                                    'typeHints'         => TRUE
  760.                             );
  761.  
  762.             require_once 'XML/Unserializer.php';
  763.             $hUnserializer = new XML_Unserializer($options);
  764.  
  765.             $status $hUnserializer->unserialize($response);
  766.             if (PEAR::isError($status))
  767.             {
  768.                 return array("STATUS" => $status->getMessage());
  769.             }
  770.  
  771.             $retval $hUnserializer->getUnserializedData();
  772.  
  773.             $cityState     explode(','$retval['gml:featureMember']['Hostip']['gml:name']);
  774.             $latLong    explode(','$retval['gml:featureMember']['Hostip']['ipLocation']['gml:PointProperty']['gml:Point']['gml:coordinates']);
  775.  
  776.             $retarray = array('TARGET'    => $this->last_target,
  777.                               'CITY'    => trim($cityState[0]),
  778.                               'STATE'    => trim($cityState[1]),
  779.                               'COUNTRY'    => trim($retval['gml:featureMember']['Hostip']['countryAbbrev']),
  780.                               'LAT'        => trim($latLong[1]),
  781.                               'LONG'    => trim($latLong[0]),
  782.                               'STATUS'    => 'OK',
  783.                               'RAWDATA'    => $retval                );
  784.         }
  785.  
  786.         return $retarray;
  787.  
  788.     }
  789.  
  790. }
  791.  
  792. ?>

Documentation generated on Mon, 11 Mar 2019 15:40:19 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.