doumen6532
2014-06-04 08:42
浏览 676
已采纳

如何将变量作为cURL数组中的url参数传递给CURLOPT_URL

I have this php code using cURL to parse an xml feed from Indeed.com. I'm passing server information such as REMOTE_ADDR and HTTP_USER_AGENT into the parameters of the url but they are not being passed.

Check this part of the code below. '.geoCheckIP($_SERVER['REMOTE_ADDR']).'

This is the correct way to do it. Just not sure if it is the correct way to do it when it is part of an array in CURLOPT_URL =>

What is the proper way to pass these server snippets into the url parameters when using an array in cURL like in the below function in CURLOPT_URL =>?

The below php code is the entire code on my page so you can get a better idea of what is going on.

I'm trying to detect the users city, state when they arrive at my site to display job listings in their local area. The php code works and I can echo the city state on the web page, but it is just not passing that same info to the function curl_request() in the array. Please help.

<?php
// Convert IP into city state country (Geo Location function)
function geoCheckIP($ip){
if(!filter_var($ip, FILTER_VALIDATE_IP))
{
throw new InvalidArgumentException("IP is not valid");
}

$response=@file_get_contents('http://www.netip.de/search?query='.$ip);
if (empty($response))
{
throw new InvalidArgumentException("Error contacting Geo-IP-Server");
}

$patterns=array();
$patterns["domain"] = '#Domain: (.*?)&nbsp;#i';
$patterns["country"] = '#Country: (.*?)&nbsp;#i';
$patterns["state"] = '#State/Region: (.*?)<br#i';
$patterns["town"] = '#City: (.*?)<br#i';

$ipInfo=array();

foreach ($patterns as $key => $pattern)
{

$ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : 'not found';
}
/*I've included the substr function for Country to exclude the abbreviation (UK, US, etc..)
To use the country abbreviation, simply modify the substr statement to:
substr($ipInfo["country"], 0, 3)
*/
$ipdata = $ipInfo["town"]. ", ".$ipInfo["state"]/*.", ".substr($ipInfo["country"], 4)*/;
return $ipdata;
}


// Indeed php function
function curl_request(){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://api.indeed.com/ads/apisearch?publisher=&q=computer+repair&l='.geoCheckIP($_SERVER['REMOTE_ADDR']).'&sort=&radius=25&st=&jt=&start=&limit=&fromage=&highlight=1&filter=1&latlong=0&co=us&chnl=computer+help+wanted&userip='.$_SERVER['REMOTE_ADDR'].'&useragent='.$_SERVER['HTTP_USER_AGENT'].'&v=2',
));
$resp = curl_exec($curl);
curl_close($curl);
return $resp;
}

function xmlToArray($input, $callback = null, $recurse = false) {
$data = ((!$recurse) && is_string($input))? simplexml_load_string($input, 'SimpleXMLElement', LIBXML_NOCDATA): $input;
if ($data instanceof SimpleXMLElement) $data = (array) $data;
if (is_array($data)) foreach ($data as &$item) $item = xmlToArray($item, $callback, true);
return (!is_array($data) && is_callable($callback))? call_user_func($callback, $data): $data;
}
?>

FUNCTION CALL

This is how the function is called in the body

    <ol>
  <?php

for($i=0;$i<10;$i++){    // using for loop to show number of  jobs

$resp=curl_request($i);

$arrXml = xmlToArray($resp);

$results=$arrXml['results'];

?>
  <li>
    <p><strong>Job :</strong> <a href="<?php echo $results['result'][$i]['url']; ?>" target="_blank"><?php echo $results['result'][$i]['jobtitle']; ?></a></p>
    <p><strong>Company:</strong> <?php echo $results['result'][$i]['company']; ?></p>
    <p><strong>Location:</strong> <?php echo $results['result'][$i]['formattedLocationFull']; ?></p>
    <p><strong>Date Posted :</strong> <?php echo $results['result'][$i]['formattedRelativeTime'];?> on <?php echo $results['result'][$i]['date'];?></p>
    <p><strong>Description :</strong> <?php echo $results['result'][$i]['snippet']; ?></p>
  </li>
  <?php } ?>
</ol>

What works

This code above works only if I remove the variables from the CURLOPT_URL

This works

CURLOPT_URL => 'http://api.indeed.com/ads/apisearch?publisher=&q=computer+repair&l=city,state&sort=&radius=25&st=&jt=&start=&limit=&fromage=&highlight=1&filter=1&latlong=0&co=us&chnl=computer+help+wanted&userip=111.111.111.111&useragent=mozila&v=2',

This does not work

CURLOPT_URL => 'http://api.indeed.com/ads/apisearch?publisher=&q=computer+repair&l='.geoCheckIP($_SERVER['REMOTE_ADDR']).'&sort=&radius=25&st=&jt=&start=&limit=&fromage=&highlight=1&filter=1&latlong=0&co=us&chnl=computer+help+wanted&userip='.$_SERVER['REMOTE_ADDR'].'&useragent='.$_SERVER['HTTP_USER_AGENT'].'&v=2',
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • doutan3463 2014-06-13 21:25
    已采纳

    Using cURL is not needed for this and was loading very slow. Here is a very simple way to get the results of the xml document in pure php with the geoCheckIP function fully working with it.

    <?php
    
    // Convert IP into city state country (Geo Location function)
    function geoCheckIP($ip){
        if(!filter_var($ip, FILTER_VALIDATE_IP))
        {
        throw new InvalidArgumentException('IP is not valid');
        }
    
        $response=@file_get_contents('http://www.netip.de/search?query='.$ip);
        if (empty($response))
        {
        throw new InvalidArgumentException('Error contacting Geo-IP-Server');
        }
    
        $patterns=array();
        $patterns["domain"] = '#Domain: (.*?)&nbsp;#i';
        $patterns["country"] = '#Country: (.*?)&nbsp;#i';
        $patterns["state"] = '#State/Region: (.*?)<br#i';
        $patterns["town"] = '#City: (.*?)<br#i';
    
        $ipInfo=array();
    
        foreach ($patterns as $key => $pattern)
        {
    
        $ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : 'not found';
        }
        /*I've included the substr function for Country to exclude the abbreviation (UK, US, etc..)
        To use the country abbreviation, simply modify the substr statement to:
        substr($ipInfo["country"], 0, 3)
        */
        $ipdata = $ipInfo["town"]. ", ".$ipInfo["state"]/*.", ".substr($ipInfo["country"], 4)*/;
        return $ipdata;
    }
    
    
    // Indeed.com API URL parameters
    $url = 'http://api.indeed.com/ads/apisearch'.'?';
    $publisher = 'YOUR PUB NUMBER GOES HERE';
    $q = 'title:(java or java+programmer or java+programming)';
    $l = geoCheckIP($_SERVER['REMOTE_ADDR']);
    $sort = 'date';
    $radius = '20';
    $st = '';
    $jt = '';
    $start = '0';
    $limit = '25';
    $fromage = '';
    $highlight = '0';
    $filter = '1';
    $latlong = '0';
    $co = 'us';
    $chnl = 'YOUR CHANNEL NAME';
    $userip = $_SERVER['REMOTE_ADDR'];
    $useragent = isset($_SERVER['HTTP_USER_AGENT']) ? ($_SERVER['HTTP_USER_AGENT']) : 'unknown';
    $v = '2';
    

    Then the rest of the code you see below will go below the <body> tag of your page where you want the output to show up at.

        <!-- BEGIN INDEED ORDERED LIST-->
        <ol class="jobs">
          <?php
    
        $xml = simplexml_load_file($url."publisher=".$publisher."&q=".$q."&l=".$l."&sort=".$sort."&radius=".$radius."&st=".$st."&jt=".$jt."&start=".$start."&limit=".$limit."&fromage=".$fromage."&highlight=".$highlight."&filter=".$filter."&latlong=".$latlong."&co=".$co."&chnl=".$chnl."&userip=".$userip."&useragent=".$useragent."&v=".$v);
    
        foreach($xml->results->result as $result) { ?>
          <li class="job">
            <div id="jobtitle"><strong><a onmousedown="<?php echo $result->onmousedown;?>" rel="nofollow" href="<?php echo $result->url;?>" target="_blank"><?php echo $result->jobtitle;?></a></strong></div>
            <div id="company"><?php echo $result->company;?></div>
            <div id="snippet">
              <?php echo $result->snippet;?>
            </div>
            <div id="location"><strong>Location:</strong> <?php echo $result->formattedLocationFull;?></div>
            <div id="date"><span class="posted">Posted <?php echo $result->formattedRelativeTime;?></span></div>
          </li>
          <?php } ?>
        </ol>
        <!-- END INDEED ORDERED LIST -->
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dongxiaoshe0737 2014-06-04 08:44

    There is a proper explanation here: passing arrays as url parameter

    You can just take the syntax from there and use it with curl!

    example for a function which should help you create a url-param in array-form:

    public function createArrParam($key, $values) {
        return implode('&amp;' . $key . '[]=', array_map('urlencode', $values));
    }
    

    after that you just take your url and concatenate it with the result:

    $values = array(1, 2, 3, 4, 5);
    $url = 'http://stackoverflow.com?bla=blupp' . createArrParam('myArr', $values);
    
    评论
    解决 无用
    打赏 举报
  • dql7588 2014-06-04 09:05

    Like so;

    function curl_request()
    {
        // Get cURL resource
        $curl = curl_init();
        // Set some options
        $curl_config = array(
            CURLOPT_URL => 'http://api.indeed.com/ads/apisearch',
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_POSTFIELDS => array(
                "publisher" => "",
                "q" => "computer+repair",
                "l" => $user_location,
                "sort" => "",
                "radius" => 25,
                "st" => "",
                "jt" => "",
                "start" => "",
                "limit" => "",
                "fromage" => "",
                "highlight" => 1,
                "filter" => 1,
                "latlong" => 0,
                "co" => "us",
                "chnl" => "computer+help+wanted",
                "userip" => $user_ip,
                "useragent" => $user_agent,
                "v" => 2
            )
        );
        curl_setopt_array($curl, $curl_config);
        // Send the request & save response to $resp
        $resp = curl_exec($curl);
        // Close request to clear up some resources
        curl_close($curl);
        return $resp;
    }
    

    EDIT There may be 1, possibly 2 reasons why this isn't working for you;

    1. your not passing in the variables you've defined outside the function (neither did I in my first answer). To fix this you either need to pass them in like so function curl_request($user_ip, $user_agent, $user_location) in your function definition and as well when calling the function. Or change how you enter them in the URL string;

    curl_setopt_array($curl, array(
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => 'http://api.indeed.com/ads/apisearch?publisher=&q=computer+repair&l='.geoCheckIP($_SERVER['HTTP_USER_AGENT']).'&sort=&radius=25&st=&jt=&start=&limit=&fromage=&highlight=1&filter=1&latlong=0&co=us&chnl=computer+help+wanted&userip='.$$_SERVER['REMOTE_ADDR'].'&useragent='.$_SERVER['HTTP_USER_AGENT'].'&v=2'
    ));
    

    $_SERVER is a global variable so it does not need passing into the function as a parameter to work like this.

    2. The api your calling does not accept POST requests only GET in which case my first example wont work, and your first example should work, once you pass through the variables as outlined in point 1.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题