Catching the weather API remote data
msg, you're showing in your question is basically the result from the weather API. And it says, that there's no data available for your location.
The first thing you want to do is some research in the Codex and the "WP HTTP API".
The right/WP way to grab remote data
After you've learned about the WP HTTP API, you'll see that the common way to do it is (simplified like this):
$response = wp_remote_request( 'http://example.com?some=parameter', array(
'ssl_verify' => true
If there's an error (as shown in your example), then you'll be able to catch it using the
is_wp_error( $response ) AND printf(
'There was an ERROR in your request.<br />Code: %s<br />Message: %s',
Then it's time to get the appropriate data. This will show
OK, if everything on the remote side worked out. IMPORTANT: The remote data will likely follow no standard than their internal one. So there can be errors, but you will still get the positive
200/OK message back from them.
$response_code = wp_remote_retrieve_response_code( $response );
$response_status = wp_remote_retrieve_response_message( $response );
Get the result
Finally it's time to inspect the result. First, we get rid of leading/trailing white space(s). In the following sample, you see how to use the WP HTTP API to check the header. If we caught
JSON, then we go with
json_decode() and if we got
XML, then we go with PHPs native
// Prepare the data:
$content = trim( wp_remote_retrieve_body( $response ) );
// Convert output to JSON
if ( strstr( wp_remote_retrieve_header( $response, 'content-type' ), 'json' ) )
$content = json_decode( $content );
// … else, after a double check, we simply go with XML string
elseif ( strstr(
wp_remote_retrieve_header( $response, 'content-type' ),
// Lets make sure it is really an XML file
// We also get cases where it's "<?XML" and "<?xml"
if ( '<?xml' !== strtolower( substr( $content, 0, 5 ) ) )
// Also return stuff wrapped up in <![CDATA[Foo]]>
$content = simplexml_load_string( $content, null, LIBXML_NOCDATA );
// If both didn't work out, then we maybe got a CSV, or something else...
In case of a CSV file, you'll have to find a custom solution or search for a PHP class on the interwebs. But honestly: If they're using CSV, it's easier to search for another service.
Cache the data with a Transient
The Transient API offers a pretty nice way to do this:
// Set Transient
$transient = set_transient(
'Your cache key',
You should then be able to catch the transient with
An often encountered error is that the SSL verification doesn't work. Gladly you can turn it on/off pretty easy:
add_filter( 'https_ssl_verify', '__return_true' );
add_filter( 'https_ssl_verify', '__return_false' );
There's one pretty funny thing, as you'll find out when inspecting the appropriate core file: Core also got a filter for local requests. But don't get fooled by this one. This filter is only meant to get used in case you're A) providing a remote service from within your WP install and B) also consuming it yourself! I know, this can be quite a
#WTF?! moment that this isn't a switch for you to use different SSL verification settings between your local install and your production environment/server, but it also has an idea behind it: It's to test services that you provide yourself as I also explained to the WP G+ community here.
// Debug your own service without SSL verification.
add_filter( 'https_local_ssl_verify', '__return_false' );
Debugging the request & its results
Without diggin' too deep into the update process, but the WP HTTP API uses the WP_HTTP class. It also offers a nice thing: A debug hook.
do_action( 'http_api_debug', $response, 'response', $class, $args, $url );
$response can also be a
WP_Error object that maybe tells you more.
Note: From a brief test, this filter seems to only (for some reason) work if you place it as close to where you're actually doing the request. So maybe you need to call it from within a callback on one of the below filters.
Y NO CURL?
Easy. All the funkiness of the "WP HTTP API", that I've shown above, is basically a function based wrapper for the
WP_HTTP class internals, which acts as base class (and will be extended for different scenarios). The extending
WP_HTTP_* classes are
Encoding. If you hook a callback to the
'http_api_debug'-action, then the third argument will tell you which class was used for your request. You don't have to call the classes directly. Just use the functions.
For most remote/HTTP API requests, it's the
WP_HTTP_curl class, which is a wrapper for PHPs native
WP_HTTP_curl Class, you'll find the
request() method. This method offers two filters to intercept the SSL behavior: One for local requests
'https_local_ssl_verify' and one for remote requests
'https_ssl_verify'. WP will likely define
localhost and what you get in
get_option( 'siteurl' );.