私は私のWordpressでget_transient()
メソッドを使おうとしています、私はドキュメントを読みました、そして、私はドキュメントで説明されたことをやっているようです。
私は私のウェブサイトに天気を表示する必要があり、私は6時間ごとに更新されるサードパーティの天気APIを使用しています。
APIが有効期限後に呼び出されるように、天気のローカルキャッシュを作成しています。 (その他の理由:APIレート制限)
これは私のコードです:
$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);
}
天気予報を得るための場所(say delhi
)を送っていて、それがキャッシュにない場合は、それがfalse
を返す一方でそれが次の文字列を返すことを期待していました
'{ "data": { "error": [ {"msg": "Unable to find any matching weather location to the query submitted!" } ] }}'
私はvar_dump($weather);
を使用して$weather
の値をチェックしました
誰かが私が間違っているところを私に直すことができますか?
あなたがあなたの質問に示しているmsg
は、基本的に天気APIからの結果です。そして、それはあなたの場所のために利用可能なデータがないことを言います。
あなたが最初にしたいことは、 Codexと "WP HTTP API" に関する研究です。
WP HTTP APIについて学んだ後は、それを行うための一般的な方法が次のようになることがわかります(このように簡略化されています)。
$response = wp_remote_request( 'http://example.com?some=parameter', array(
'ssl_verify' => true
) );
例に示すようにエラーがある場合は、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()
);
それでは適切なデータを入手しましょう。リモート側のすべてがうまくいった場合、これは200
とOK
を示します。 重要:リモートデータは、おそらく内部データよりも標準に準拠しないでしょう。それでcanエラーがあるかもしれません、しかしあなたはまだそれらから正の200/OK
メッセージを受け取るでしょう。
$response_code = wp_remote_retrieve_response_code( $response );
$response_status = wp_remote_retrieve_response_message( $response );
最後に結果を検証します。まず、先頭/末尾の空白を取り除きます。次のサンプルでは、WP HTTP APIを使用してヘッダーを確認する方法を説明しています。 JSON
を捉えた場合はjson_decode()
を使い、XML
を受け取った場合はPHPネイティブのSimpleXML
クラスを使います。
// 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...
CSVファイルの場合は、カスタムソリューションを見つけるか、Web上でPHPクラスを検索する必要があります。しかし正直なところ:CSVを使用している場合は、他のサービスを検索する方が簡単です。
Transient API はこれを実行するための非常に素晴らしい方法を提供します。
// Set Transient
$transient = set_transient(
'Your cache key',
$content,
60*60*6
);
そうするとget_transient()
で一時的なものを捕らえることができるはずです。
よくあるエラーは、SSL検証が機能しないことです。喜んであなたは非常に簡単にそれをオン/オフにすることができます:
// ON:
add_filter( 'https_ssl_verify', '__return_true' );
// OFF:
add_filter( 'https_ssl_verify', '__return_false' );
適切なコアファイルを調べるとわかるように、かなり面白いことが1つあります。コアは、 local request用のフィルタも持っています。しかし、これにだまされてはいけません。このフィルタは、A)WPインストール内からリモートサービスを提供している場合、およびB)自分で使用している場合にのみ使用することを目的としています。私は知っている、これはあなたがあなたのローカルインストールとあなたの本番環境/サーバーの間で異なるSSL検証設定を使うためのスイッチではないというかなり#WTF?!
瞬間であるかもしれませんあなたは自分自身をI としてここで説明するWP G +コミュニティに説明しました 。
// Debug your own service without SSL verification.
add_filter( 'https_local_ssl_verify', '__return_false' );
Digginがないと、更新プロセスが深くなりすぎますが、WP HTTP APIはWP_HTTPクラスを使用します。デバッグフックという素晴らしいこともあります。
do_action( 'http_api_debug', $response, 'response', $class, $args, $url );
$response
はWP_Error
オブジェクトになることもできます。
注:簡単なテストでは、このフィルタは(何らかの理由で)実際にリクエストを行っている場所の近くに配置した場合にのみ機能するようです。そのため、以下のいずれかのフィルタでコールバック内から呼び出す必要があります。
簡単です。私が上に示した「WP HTTP API」のすべてのファンキーさは基本的に基本クラスとして機能する(そして異なるシナリオのために拡張される)WP_HTTP
クラス内部のための関数ベースのラッパーです。拡張するWP_HTTP_*
クラスはFsockopen
、Streams
、Curl
、Proxy
、Cookie
、Encoding
です。コールバックを'http_api_debug'
-アクションにフックすると、3番目の引数はどのクラスがあなたのリクエストに使われたかを教えてくれます。 直接クラスを呼び出す必要はありません。関数を使用するだけです。
ほとんどのリモート/ HTTP APIリクエストにとって、これは
WP_HTTP_curl
クラスです。これはPHPネイティブのcurl
ライブラリのラッパーです。
WP_HTTP_curl
クラスの中には、request()
メソッドがあります。このメソッドは、SSLの振る舞いを傍受するための2つのフィルタを提供します。1つはローカル要求'https_local_ssl_verify'
、もう1つはリモート要求'https_ssl_verify'
です。 WPはおそらくlocal
をlocalhost
として定義し、あなたがget_option( 'siteurl' );
からreturn
で得たものを定義するでしょう。
問題は「トランジェント」機能に関するものではありません。それはあなたのサードパーティのAPIから返されたエラーメッセージのように見えます。 set_transient
を使う前に、おそらくそれをチェックする必要があります。 set_transient
は与えられたものをすべて挿入し、get_transient
はDBにあるものをすべて検索します。 言い換えれば、私は問題があなたがそれがあると思う場所ではないことをかなり確信しています。
$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);
}
}
私はあなたの天気APIからの出力のいくつかについて推測しているので、あなたが望む結果を得るためにそれを微調整する必要があるかもしれません。
注:あなたのAPIはJSONを返しています。 あなたの例は以下のものをデコードします:
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!',
)),
),
)),
))