[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

using curl() instead of fopen()

Posted on 2006-06-07
20
Medium Priority
?
1,409 Views
Last Modified: 2013-12-13
I have the line:
// Attempt to load the page  
$gm = fopen('http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js','r');        

At the moment when using this I get the error message:
Warning: fopen(): URL file-access is disabled in the server configuration in................

I was told that this was something that needed to be changed in php.ini on the server side.

Having contacted my hosting company I have now received this reply:
the fopen() function is enabled but only works for local address's it is disabled for remote address's for security reasons and unfortunately this can not be changed. Some developers have found the curl() function to be a suitable replacement as this is enabled on our servers.

could someone tell me more about this curl() function in 'english' rather that that of php.net and tell me whether it could be used as a replacement for the line above.

Many thanks

Simon
0
Comment
Question by:scm0sml
  • 11
  • 9
20 Comments
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16850851
Hi scm0sml,


CURL is a mechanism to allow PHP to work like a browser in terms of getting and sending data to web sites.

It is an external library that would need to be included by removing the ; from the ;ext=php_curl.dll line in your php.ini (or equivalent).

It is a fairly complex system (consider all the ways you can get and send data - CURL has to deal with all of this).

Try ...

<?php
$s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';
$r_curl = curl_init();
curl_setopt($r_curl, CURLOPT_URL, $s_URL);
curl_setopt($r_curl, CURLOPT_RETURNTRANSFER, 1);
$gm = curl_exec($r_curl);
curl_close($r_curl);

// $gm should not contain the data.
?>



Regards,

Richard Quadling.
0
 

Author Comment

by:scm0sml
ID: 16850884
the line is part of the function below:

function get_lat_long($q)
{
    // Attempt to load the page  
    $gm = fopen('http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js','r');        

    if ( $gm )
    {
        echo "temp:true";        
        $tmp = @fread($gm,30000);
        fclose($gm);
    }
    else
    {    
      echo "temp:false";      
      return false;
    }
   
    // Extract the data from the returned page
    $x = preg_replace ("/.*,viewport\: \{center\: \{lat\: (-?\d+\.\d+),lng: (-?\d+\.\d+)\},.*/", "|$1|$2|", nl2br(trim($tmp)));

    // Make sure all of the required elements are there
    if ( count ( explode ("|",$x ) ) >= 3 )
    {
        list ($dmy,$lat_value, $lng_value) = explode ("|",$x );
    }
    else
    {
        return false;
    }

    return(array('latitude'=>$lat_value,'longitude'=>$lng_value));
}

with your suggestion would this function still work?

As you can probably gather I am just trying to get the lat/long for a uk post code from a google map...........

any ideas?
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16850901
Once you've got the data, you can do what you like with it ...

Try this ...

<?php
function get_long_lat($q)
      {
      $s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';
      $r_curl = curl_init();
      curl_setopt($r_curl, CURLOPT_URL, $s_URL);
      curl_setopt($r_curl, CURLOPT_RETURNTRANSFER, 1);
      $gm = curl_exec($r_curl);
      curl_close($r_curl);

      // $gm should not contain the data.

      // Extract the data from the returned page
      $x = preg_replace ("/.*,viewport\: \{center\: \{lat\: (-?\d+\.\d+),lng: (-?\d+\.\d+)\},.*/", "|$1|$2|", nl2br(trim($tmp)));

      // Make sure all of the required elements are there
      if ( count ( explode ("|",$x ) ) >= 3 )
            {
            list ($dmy,$lat_value, $lng_value) = explode ("|",$x );
            }
      else
            {
            return false;
            }
      
      return(array('latitude'=>$lat_value,'longitude'=>$lng_value));
      }
?>
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:scm0sml
ID: 16850910
OK looks good but I won't be able to upload it and test until I get home from work.

I'll get back to you then if thats ok?

Cheers again

Simon
0
 

Author Comment

by:scm0sml
ID: 16853999
this is what i have at the mo:

function get_lat_long($q)
{
  $s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';
  $r_curl = curl_init();
  curl_setopt($r_curl, CURLOPT_URL, $s_URL);
  curl_setopt($r_curl, CURLOPT_RETURNTRANSFER, 1);
  $gm = curl_exec($r_curl);
  curl_close($r_curl);

  // $gm should not contain the data.

  // Extract the data from the returned page
  $x = preg_replace ("/.*,viewport\: \{center\: \{lat\: (-?\d+\.\d+),lng: (-?\d+\.\d+)\},.*/", "|$1|$2|", nl2br(trim($tmp)));

  // Make sure all of the required elements are there
  if ( count ( explode ("|",$x ) ) >= 3 )
  {    
    list ($dmy,$lat_value, $lng_value) = explode ("|",$x );
   
  }
  else
  {
    return false;
  }

  return(array('latitude'=>$lat_value,'longitude'=>$lng_value));
}


$simonspcode = "CF83 3HH";

$q = str_replace ( " ", "", trim ($simonspcode) );

$tmp = get_lat_long($q); //$tmp will be a 2 member array containing latitude and longitude

if ( $tmp === false )
{
    echo $addressData;

    if ( strlen ( trim ( $simonspcode ) ) > 0 )
    {
        echo "<br><a href=\"http://www.multimap.com/map/browse.cgi?&title=" . urlencode ( $simonspcode ) . "&pc=" . urlencode( $simonspcode ) . "\" target=\"_blank\">View Map</a>";      
    }
}
else
{
........display map using api

the link View Map is being displayed so the get_lat_long function doesn't seem to be returning anything...

I'm slightly bafled as to what your doing in the function.....any idea why this would be happening?

cheers
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16859188
Baffled in what way ...

Line by line explanation ...

// Define the URL containing the data we want to receive. This is the same if you were using file_get_contents(), fopen, curl, sockets, etc.
  $s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';

// Create a CURL resource. This will allow us to talk CURL.
  $r_curl = curl_init();

// Set an option which tells CURL what the URL is that we wish to connect to.
  curl_setopt($r_curl, CURLOPT_URL, $s_URL);

// Set an option which tells CURL we want to get the data back rather than send it to a file or to the client or somewhere else.
  curl_setopt($r_curl, CURLOPT_RETURNTRANSFER, 1);

// Execute the curl statement. This uses the URL and returns the data to the $gm variable.
  $gm = curl_exec($r_curl);

// Close our CURL session. This tells the other end that we have finished and that end can free its resources.
  curl_close($r_curl);

// Now $gm will contain the HTML of the URL requested.




0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16859216
Let's add some simple debugging.

1 - What is the URL we are talking to ...

Change ...

$s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';

to

$s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';
echo <<< END_A
<h1>We want to get the data from <a href="{$s_URL}">{$s_URL}</a><hr /></h1>
END_A;

2 - Did we get any data back?

Change ...

$gm = curl_exec($r_curl);

to ...

$gm = curl_exec($r_curl);
echo '<h1>This is the HTML in response to the CURL request.<hr /></h1>' . htmlentities($gm);


3 - Where you make the call to the function change ...

$a_answer = get_lat_long($q);

to ...

$a_answer = get_lat_long($q);
echo '<h1>This is the response we got from the get_lat_long().<hr /></h1><pre>' . var_export($a_answer, True) . '</pre>';

You will need to substitute $a_answer and $q here for the appropriate variables you are using.



Obviously, this is going to make a mess of the page, so maybe create an alternative page. I am trying to see EXACTLY what URL CURL is using (Not just what you think it SHOULD be but what it ACTUALLY is - a common issue!!!!!) and to see EXACTLY what is returned.



0
 

Author Comment

by:scm0sml
ID: 16859294
ok excellent.

Again I'm in work now and aren't allowed to ftp so I'll make the changes and upload when I get home.........

looks like a long running saga ;)

I'll let you know how I get on.

Cheers
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16859396
NP.

Are you on broadband at home?

If so, try out a program like VNC. This will allow you to remote control your pc from work. Using email you could send the files to your home pc and then upload them using FTP.

Another thing you may want to try is to create an uploader for your site.

You would create a zip file with a password and then use normal HTTP File uploading get the file on the server and then unzip it to the correct location.

As the file is encrypted, anyone attempting to upload an unencrypted file would fail.
0
 

Author Comment

by:scm0sml
ID: 16859822
Yeah thats a good point actually, never even thought of it............

I'll get on it!!

cheers!
0
 

Author Comment

by:scm0sml
ID: 16862414
right then......

the url is is reading from is:
http://maps.google.com/maps?q=CF833HH&output=js

It is returning the full html as far as i can see:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/><title>CF833HH - Google Maps</title><script type="text/javascript">//<![CDATA[ function onLoad() {window.parent.loadVPage({title: "CF833HH - Google Maps",vartitle: "",url: "/maps?q=CF833HH",urlViewport: false,form: {selected: "q",q: {q: "CF833HH"},l: {q: "",near: "CF833HH"},d: {saddr: "",daddr: "CF833HH"}},viewport: {center: {lat: 51.584097,lng: -3.220547},span: {lat: 0.002700,lng: 0.004345},mapType: null},overlays: {markers: [{id: 'A',lat: 51.584097,lng: -3.220547,image: '/mapfiles/arrow.png',icon: function() { return parent.G_ADDR_ICON; },infoWindow: function() {this.openInfoWindowTabsHtml([new parent.GInfoWindowTab('Address','<div class=\"iw\"><div class=\"title\">Address:</div><div class=\"basics\">CF83 3HH<br/>UK<br/><div class=\"sloc\"><div id=\"setas\"><a href=\"/maps?output=setprefs&near=CF83+3HH,+UK\" onclick=\"return setDefaultLocation(this)\">Make this my default location</a></div><div id=\"setasconfirm\" style=\"width: 20em; display:none\">The map will start on <b>CF833HH</b> next time you visit the site.</div></div><div class=\"dir\" style=\"padding-top:0.7em\">Directions:&#160;<span class=\"tab\" tab=\"dir:to\">To here</span>&#160;-&#160;<span class=\"tab\" tab=\"dir:from\">From here</span><div class=\"card\" tab=\"dir:from\" tabload=\"this.e(\'iwdaddr\').value = this.e(\'iwsaddr\').value;this.e(\'iwdaddr\').select();acinit(\'iwdaddr\');spinit(\'iwdaddr\')\"><form onsubmit=\"prepareForm(this,\'\')\" action=\"/maps\" target=\"vp\"><input value=\"CF83 3HH, UK @51.584097,-3.220547\" name=\"saddr\" type=\"hidden\"/><div class=\"label\">End address</div><div><input class=\"inpt\" id=\"iwdaddr\" name=\"daddr\" type=\"text\" value=\"\"/></div><div><input type=\"submit\" value=\"Get Directions\"/></div></form></div><div class=\"card\" tab=\"dir:to\" tabload=\"this.e(\'iwsaddr\').value = this.e(\'iwdaddr\').value;this.e(\'iwsaddr\').select();acinit(\'iwsaddr\');spinit(\'iwsaddr\')\"><form onsubmit=\"prepareForm(this,\'\')\" action=\"/maps\" target=\"vp\"><input value=\"CF83 3HH, UK @51.584097,-3.220547\" name=\"daddr\" type=\"hidden\"/><div class=\"label\">Start address</div><div><input class=\"inpt\" id=\"iwsaddr\" name=\"saddr\" type=\"text\" value=\"\"/></div><div><input type=\"submit\" value=\"Get Directions\"/></div></form></div></div></div></div>' )], { maxWidth: 325 });}}],polylines: [],polygons: []}},document.getElementById("state"));}//]]></script></head><body onload="onLoad()"><input id="state" type="text" value=""/></body></html>


I'm not really sure what bar_export is doing........but i get:
This is the response we got from the get_lat_long().

false

So at least the html is being read ok.......from there I'm not sure.

What do you see in all this?
0
 

Author Comment

by:scm0sml
ID: 16862429
i mean var_export*
0
 
LVL 40

Accepted Solution

by:
Richard Quadling earned 2000 total points
ID: 16868223
What is $tmp?

Shouldn't that be $gm?

So ...

Try this ...

// Extract the data from the returned page
preg_match ('`.*{lat: (-?\d+\.\d+),lng: (-?\d+\.\d+)}.*`sim', $gm, $a_matches);
return array
      (
      'latitude' => $a_matches[1][0],
      'longitude' => $a_matches[2][0],
      );

Proof ...

<?php
$gm = <<< END_GM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><title>CF833HH - Google Maps</title><script type="text/javascript">//<![CDATA[
function onLoad() {window.parent.loadVPage({title: "CF833HH - Google Maps",vartitle: "",url: "/maps?q=CF833HH",urlViewport: false,form: {selected: "q",q: {q: "CF833HH"},l: {q: "",near: "CF833HH"},d: {saddr: "",daddr: "CF833HH"}},viewport: {center: {lat: 51.584097,lng: -3.220547},span: {lat: 0.002700,lng: 0.004345},mapType: null},overlays: {markers: [{id: 'A',lat: 51.584097,lng: -3.220547,image: '/mapfiles/arrow.png',icon: function() { return parent.G_ADDR_ICON; },infoWindow: function() {this.openInfoWindowTabsHtml([new parent.GInfoWindowTab('Address','<div class=\"iw\"><div class=\"title\">Address:</div><div class=\"basics\">CF83 3HH<br/>UK<br/><div class=\"sloc\"><div id=\"setas\"><a href=\"/maps?output=setprefs&near=CF83+3HH,+UK\" onclick=\"return setDefaultLocation(this)\">Make this my default location</a></div><div id=\"setasconfirm\" style=\"width: 20em; display:none\">The map will start on <b>CF833HH</b> next time you visit the site.</div></div><div class=\"dir\" style=\"padding-top:0.7em\">Directions:&#160;<span class=\"tab\" tab=\"dir:to\">To here</span>&#160;-&#160;<span class=\"tab\" tab=\"dir:from\">From here</span><div class=\"card\" tab=\"dir:from\" tabload=\"this.e(\'iwdaddr\').value = this.e(\'iwsaddr\').value;this.e(\'iwdaddr\').select();acinit(\'iwdaddr\');spinit(\'iwdaddr\')\"><form onsubmit=\"prepareForm(this,\'\')\" action=\"/maps\" target=\"vp\"><input value=\"CF83 3HH, UK @51.584097,-3.220547\" name=\"saddr\" type=\"hidden\"/><div class=\"label\">End address</div><div><input class=\"inpt\" id=\"iwdaddr\" name=\"daddr\" type=\"text\" value=\"\"/></div><div><input type=\"submit\" value=\"Get Directions\"/></div></form></div><div class=\"card\" tab=\"dir:to\" tabload=\"this.e(\'iwsaddr\').value = this.e(\'iwdaddr\').value;this.e(\'iwsaddr\').select();acinit(\'iwsaddr\');spinit(\'iwsaddr\')\"><form onsubmit=\"prepareForm(this,\'\')\"  action=\"/maps\" target=\"vp\"><input value=\"CF83 3HH, UK @51.584097,-3.220547\" name=\"daddr\" type=\"hidden\"/><div class=\"label\">Start address</div><div><input class=\"inpt\" id=\"iwsaddr\" name=\"saddr\" type=\"text\" value=\"\"/></div><div><input type=\"submit\" value=\"Get Directions\"/></div></form></div></div></div></div>' )], { maxWidth: 325 });}}],polylines: [],polygons: []}},document.getElementById("state"));}//]]></script></head><body onload="onLoad()"><input id="state" type="text" value=""/></body></html>
END_GM;

preg_match ('`.*{lat: (-?\d+\.\d+),lng: (-?\d+\.\d+)}.*`sim', $gm, $a_matches);
print_r(array
      (
      'latitude' => $a_matches[1],
      'longitude' => $a_matches[2],
      ));
?>

outputs ...

Array
(
    [latitude] => 0.002700
    [longitude] => 0.004345
)
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16868234
preg_match ('`@([-\.0-9]*),([-\.0-9]*)`sim', $gm, $a_matches);


Might be better.

This returns ...

Array
(
    [latitude] => 51.584097
    [longitude] => -3.220547
)

Which looks better.

0
 

Author Comment

by:scm0sml
ID: 16868530
// Extract the data from the returned page
$x = preg_replace ("/.*,viewport\: \{center\: \{lat\: (-?\d+\.\d+),lng: (-?\d+\.\d+)\},.*/", "|$1|$2|", nl2br(trim($tmp)));

At this line yeah your right $tmp should be $gm.

$tmp is the array that is returned by the function get_lat_long.

That obviously wouldnt have helped and could have been the prob on it's own.

Again I'll have to try it when I get home. Cheers again!

p.s think of the job satisfaction when we get it working lol ;)
0
 

Author Comment

by:scm0sml
ID: 16883704
hoooorah!!

http://www.ukcaravanfinder.co.uk/searchResults/detailedDescription/gm.php

finally working..........

many thanks for all your advice!!

top class.
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16884233
Can you include the final working code?
0
 

Author Comment

by:scm0sml
ID: 16884245
yeah no probs............

I'll tidy it up first when i get home and then post it here.
0
 

Author Comment

by:scm0sml
ID: 16900618
The function looks like:
function get_lat_long($q)
{
  $s_URL = 'http://maps.google.com/maps?q=' . str_replace(' ','+',$q) . '&output=js';

  $r_curl = curl_init();
  curl_setopt($r_curl, CURLOPT_URL, $s_URL);
  curl_setopt($r_curl, CURLOPT_RETURNTRANSFER, 1);
 
  $gm = curl_exec($r_curl);
 
  //echo '<h1>This is the HTML in response to the CURL request.<hr /></h1>' . htmlentities($gm);

  curl_close($r_curl);

  // Extract the data from the returned page
  $x = preg_replace ("/.*,viewport\: \{center\: \{lat\: (-?\d+\.\d+),lng: (-?\d+\.\d+)\},.*/", "|$1|$2|", nl2br(trim($gm)));

  // Make sure all of the required elements are there
  if ( count ( explode ("|",$x ) ) >= 3 )
  {    
    list ($dmy,$lat_value, $lng_value) = explode ("|",$x );
   
  }
  else
  {
    return false;
  }

  return(array('latitude'=>$lat_value,'longitude'=>$lng_value));
}

and the other code is:
$postcode = $caravan->Postcode;

$q = str_replace ( " ", "", trim ($postcode) );

$tmp = get_lat_long($q); //$tmp will be a 2 member array containing latitude and longitude

if ( $tmp === false )
{
    echo $addressData;

    if ( strlen ( trim ( $postcode ) ) > 0 )
    {
        echo "<br><a href=\"http://www.multimap.com/map/browse.cgi?&title=" . urlencode ( $postcode ) . "&pc=" . urlencode( $postcode ) . "\" target=\"_blank\">View Map</a>";      
    }
}
else
{
..........display map.
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 16903298
Excellent.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
This article discusses four methods for overlaying images in a container on a web page
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question