Intereting Posts
WP_posts (Not meta) добавление специального столбца поля и изменение его в настраиваемом типе сообщения get_posts в раскрывающемся списке мета-ящик, не показывающий последние сообщения Как не отображать экземпляр виджета динамически? Пользовательская загрузка Добавляет файл Ghost Отображать поле автора только на определенных должностях категории? Получить название категории за пределами цикла в category.php Отображать дочерние сообщения из определенной категории Как перенести из localHost жить, но использовать уже существующую базу данных на сервере? PHP-Почему моя контактная форма продолжает показывать, что она недействительна? Данные формы не сохраняются в базе данных WordPress Как настроить плагин Easy Appointment? Разрешить паукам сканировать мой сайт (выбираемый параметр в wp) WP Simple Fields – одно повторяемое поле внутри группы повторяемых полей Тестирование для короткого кода с использованием функции. Ошибка 404 страницы Сделайте массив, в котором перечислены пользовательские таксономии

Запрос удаленного кэша (HTTP) с API Transients

Я пытаюсь использовать get_transient() в своем WordPress, я прочитал документ и, похоже, делаю то, что описано в документах.

Мне нужно показать погоду на моем сайте, и я использую сторонний API погоды, который обновляется каждые 6 часов.

Мы создаем локальный кеш погоды, чтобы 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

Может ли кто-нибудь исправить меня, где я делаю неправильно?

Улавливание удаленных данных API погоды

msg , вы показываете в своем вопросе, в основном результат API погоды. И он говорит, что нет данных для вашего местоположения.

Первое, что вы хотите сделать, это некоторые исследования в Codex и «WP HTTP API» .

Правильный / WP способ захвата удаленных данных

После того, как вы узнали о WP HTTP API, вы увидите, что общий способ сделать это (упрощенно подобным образом):

 $response = wp_remote_request( 'http://example.com?some=parameter', array( 'ssl_verify' => true ) ); 

Если есть ошибка (как показано в вашем примере), вы сможете ее поймать с WP_Error класса 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 , если все на удаленной стороне будет работать. ВАЖНО: удаленные данные, скорее всего, не будут соответствовать стандартным, чем их внутренний. Таким образом, могут быть ошибки, но вы все равно получите положительное сообщение 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 , то перейдем к собственному классу SimpleXML 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-файла вам нужно найти собственное решение или выполнить поиск класса PHP на межсетевых экранах. Но честно: если они используют CSV, проще искать другую услугу.

Кэш данных с переходным процессом

API Transient предлагает довольно хороший способ сделать это:

 // 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' ); 

Есть одна довольно забавная вещь, как вы узнаете при проверке соответствующего файла ядра: Core также получил фильтр для локальных запросов. Но не обманывайтесь этим. Этот фильтр предназначен только для использования в случае, если вы A) предоставляете удаленный сервис из вашей установки WP и B) также потребляете его самостоятельно! Я знаю, это может быть довольно #WTF?! что это не является переключателем для использования разных настроек проверки SSL между вашей локальной установкой и рабочей средой / сервером, но у нее также есть идея: проверить службы, которые вы предоставляете сами, так как я также объяснил 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 который, возможно, говорит вам больше.

Примечание. Из краткого теста этот фильтр кажется только (по какой-то причине) работать, если вы разместите его как можно ближе к тому месту, где вы действительно выполняете запрос. Поэтому, возможно, вам нужно вызвать его из обратного вызова на один из нижеперечисленных фильтров.

Y NO CURL?

Легко. Вся функциональность «WP HTTP API», которую я показал выше, в основном представляет собой основанный на функциях оболочку для внутренних WP_HTTP класса WP_HTTP , который действует как базовый класс (и будет расширен для разных сценариев). WP_HTTP_* классами WP_HTTP_* являются Fsockopen , Streams , Curl , Proxy , Cookie , Encoding . Если вы подключите обратный вызов к 'http_api_debug' -action, то третий аргумент скажет вам, какой класс использовался для вашего запроса. Вам не нужно напрямую вызывать классы. Просто используйте функции.

Для большинства запросов удаленного / HTTP API это класс WP_HTTP_curl , который является оболочкой для собственной библиотеки curl для PHP.

Внутри класса WP_HTTP_curl вы найдете метод request() . Этот метод предлагает два фильтра для перехвата поведения SSL: один для локальных запросов 'https_local_ssl_verify' и один для удаленных запросов 'https_ssl_verify' . WP, скорее всего, определит local как localhost и что вы получите return от get_option( 'siteurl' ); ,

Проблема заключается не в функции «переходных процессов». Это похоже на сообщение об ошибке, полученное от вашего стороннего API. Вероятно, вам нужно проверить это, прежде чем использовать set_transient . set_transient будет вставлять все, что ему дано, и get_transient будет извлекать все, что находится в БД. Другими словами, я уверен, что проблема не в том, где вы думаете.

 $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 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!', )), ), )), ))