J'essaie d'utiliser la méthode get_transient()
dans Wordpress, j'ai lu le document et j'ai l'impression de faire ce qui a été décrit dans la documentation.
Je dois afficher la météo sur mon site Web et j'utilise une API météo tierce mise à jour toutes les 6 heures.
Nous sommes en train de créer un cache local de météo afin que l'API ne soit appelée qu'après l'expiration. (Autre raison: limitation du débit de l'API)
Ceci est mon code:
$country = 'India';
$API_Key = 'xxxxxxxxxxxxxx';
$url = 'http://weatherAPI.com/feed/weather.ashx?q='.$latlong.'&format=json&num_of_days=4&key='.$API_Key;
$weather = get_transient($location);
if (false === $weather) {
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
$weather = curl_exec($ch);
curl_close($ch);
set_transient($location, $weather, 60*60*6);
}
Lorsque j'envoie un emplacement pour obtenir la météo (say delhi
) et s'il n'y en a pas dans la mémoire cache, je m'attendais à ce qu'il retourne false
pendant qu'il me renvoie chaîne suivante
'{ "data": { "error": [ {"msg": "Unable to find any matching weather location to the query submitted!" } ] }}'
J'ai utilisé var_dump($weather);
pour vérifier la valeur de $weather
Quelqu'un peut-il me corriger là où je me trompe?
La msg
, vous indiquez dans votre question le résultat de l’API météo. Et il est dit qu'il n'y a pas de données disponibles pour votre emplacement.
La première chose à faire est de faire une recherche sur le Codex et "l'API HTTP WP" .
Une fois que vous avez appris à propos de l'API HTTP WP, vous verrez que la façon habituelle de le faire est (simplifiée comme ceci):
$response = wp_remote_request( 'http://example.com?some=parameter', array(
'ssl_verify' => true
) );
S'il y a une erreur (comme indiqué dans votre exemple), vous pourrez l'attraper à l'aide de la classe WP_Error
:
is_wp_error( $response ) AND printf(
'There was an ERROR in your request.<br />Code: %s<br />Message: %s',
$response->get_error_code(),
$response->get_error_message()
);
Ensuite, il est temps d'obtenir les données appropriées. Ceci affichera 200
et OK
, si tout ce qui se trouve du côté distant a fonctionné. IMPORTANT: Les données distantes ne suivront probablement aucune norme que leur norme interne. Donc, il y a peut des erreurs, mais vous obtiendrez toujours le message positif 200/OK
.
$response_code = wp_remote_retrieve_response_code( $response );
$response_status = wp_remote_retrieve_response_message( $response );
Enfin, il est temps d'inspecter le résultat. Premièrement, nous nous débarrassons des espaces blancs de début/fin. Dans l'exemple suivant, vous voyez comment utiliser l'API HTTP WP pour vérifier l'en-tête. Si nous avons attrapé JSON
, alors nous allons avec json_decode()
et si nous avons XML
, alors nous allons avec PHP native SimpleXML
classe.
// 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' ),
'application/xhtml+xml'
) )
{
// 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 ) ) )
return false;
// 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...
Dans le cas d'un fichier CSV, vous devrez trouver une solution personnalisée ou rechercher une classe PHP sur les interwebs. Mais honnêtement: s’ils utilisent le format CSV, il est plus facile de rechercher un autre service.
L'API Transient offre une belle façon de faire cela:
// Set Transient
$transient = set_transient(
'Your cache key',
$content,
60*60*6
);
Vous devriez alors pouvoir attraper le transitoire avec get_transient()
.
Une erreur fréquente est que la vérification SSL ne fonctionne pas. Volontiers, vous pouvez l'activer/le désactiver assez facilement:
// ON:
add_filter( 'https_ssl_verify', '__return_true' );
// OFF:
add_filter( 'https_ssl_verify', '__return_false' );
Comme vous le constaterez lors de l'inspection du fichier core approprié, Core dispose également d'un filtre pour local . Mais ne vous laissez pas berner par celui-ci. Ce filtre est uniquement destiné à être utilisé dans le cas où vous: A) fournissez un service distant à partir de votre WP installation et B) le consommez vous-même! Je sais que cela peut être un assez #WTF?!
moment où ce n’est pas un commutateur pour que vous utilisiez différents paramètres de vérification SSL entre votre installation locale et votre environnement/serveur de production, mais cela a aussi une idée derrière cela: c’est de tester des services qui vous vous fournissez comme je aussi expliqué à la WP communauté G + ici .
// Debug your own service without SSL verification.
add_filter( 'https_local_ssl_verify', '__return_false' );
Sans entrer trop dans le processus de mise à jour, mais l'API HTTP WP utilise la classe WP_HTTP. Il offre également une bonne chose: un crochet de débogage.
do_action( 'http_api_debug', $response, 'response', $class, $args, $url );
Où $response
peut également être un objet WP_Error
qui en dit peut-être plus.
Remarque: D'un bref test, ce filtre ne semble fonctionner (pour une raison quelconque) que si vous le placez aussi près que vous le souhaitez de la demande. Alors peut-être devez-vous l'appeler à partir d'un rappel sur l'un des filtres ci-dessous.
Facile. Tous les aspects amusants de "l'API HTTP WP", que je viens de montrer ci-dessus, sont fondamentalement des encapsuleurs basés sur des fonctions pour les éléments internes de la classe WP_HTTP
, qui agissent comme classe de base (et seront étendus pour différents scénarios). Les classes WP_HTTP_*
extensibles sont Fsockopen
, Streams
, Curl
, Proxy
, Cookie
, Encoding
. Si vous associez un rappel à l'action 'http_api_debug'
-, le troisième argument vous indiquera quelle classe a été utilisée pour votre demande. _ {Il n'est pas nécessaire d'appeler directement les classes. Il suffit d'utiliser les fonctions.
Pour la plupart des requêtes d'API HTTP/distantes, il s'agit de la classe
WP_HTTP_curl
, qui encapsule la bibliothèquecurl
native PHP.
Dans la classe WP_HTTP_curl
, vous trouverez la méthode request()
. Cette méthode propose deux filtres pour intercepter le comportement SSL: un pour les requêtes locales 'https_local_ssl_verify'
et un pour les requêtes distantes 'https_ssl_verify'
. WP définira probablement local
comme localhost
et ce que vous obtenez dans return
à partir de get_option( 'siteurl' );
.
Le problème ne vient pas de la fonction 'transitoires'. Cela ressemble à un message d'erreur renvoyé par votre API tierce. Vous devrez probablement vérifier cela avant d'utiliser set_transient
. set_transient
insérera ce qui est donné et get_transient
récupérera tout ce qui se trouve dans la base de données. En d'autres termes, je suis à peu près sûr que le problème n'est pas ce que vous pensez.
$weather = get_transient($location);
if (false === $weather) {
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
$weather = curl_exec($ch);
curl_close($ch);
// now check $weather to see if you got a valid result
$check = json_decode($weather);
if (isset($check->data->error)) {
// there is a problem; do not insert; try something else
} else {
set_transient($location, $weather, 60*60*6);
}
}
Je devine certaines des données de votre API météo. Vous devrez peut-être modifier cela pour obtenir les résultats souhaités.
Remarque: votre API renvoie JSON. Votre exemple décode à:
stdClass::__set_state(array(
'data' =>
stdClass::__set_state(array(
'error' =>
array (
0 =>
stdClass::__set_state(array(
'msg' => 'Unable to find any matching weather location to the query submitted!',
)),
),
)),
))