作者都是各自领域经过审查的专家,并撰写他们有经验的主题. All of our content is peer reviewed and validated by Toptal experts in the same field.
Scott Fennell
Verified Expert in Engineering
15 Years of Experience

Scott写过数百个WordPress主题和插件. He specializes in third-party API integration and he’s an active tech writer.

Share

提升你的地位的最好方法之一 WordPress developer, 至少在你的客户眼中是这样, is to become skilled at consuming APIs. 这里有一个实现WordPress API的常见场景:你的客户要求你向他们的站点添加一个小部件, for example, an email subscription widget. You grab some code from their third-party email service—perhaps it’s a script tag or an iframe-将其粘贴到页面中,然后回复客户:“明白了!”

Unfortunately, 如果你面对的是一个要求更高的客户,他们会注意到你的以下缺点:

  • Although the widget, like the rest of the site, features a sans-serif font, it’s not quite the right one. 这个小部件使用的是Helvetica字体,而不是您安装的自定义字体.
  • 小部件的订阅表单触发一个新的页面加载, 如果放在文章的中间,哪一个会造成破坏.
  • The widget seems to take an extra moment to load after the rest of the page, which feels jarring and cheap.
  • 客户端希望订阅者使用基于他们订阅的帖子的元数据进行标记, and the widget does not offer anything remotely resembling this functionality.
  • 客户端发现他们现在必须管理两个仪表板(wp-admin和电子邮件服务的管理区域)很烦人。.

在这一点上,两件事之一可能会合理地发生. You could declare these items “nice-to-haves” and reassure your client about the merits of an 80/20 solution,或者你可以满足这些要求. In my personal experience, 我发现满足这样的要求——就是说, 展示对第三方服务的精通——是让客户相信你是一个WordPress向导的可靠方法. Plus, it’s often fun to do.

Over the past decade, I’ve used WordPress as a platform for API consumption against probably 50 different APIs. 一些最常见的api是MailChimp, Google Analytics, Google Maps, CloudFlare, and Bitbucket. 但如果你需要做更多,如果你需要一个定制的解决方案?

如何开发WordPress API客户端

In this article, 我将针对通用的“电子邮件服务”API进行开发, 我尽我所能让事情变得尽可能的不可知论. However, I do feel it’s reasonable to assume that we’re dealing with a JSON REST API. Here are some background topics which might help you enjoy the technical points in this article:

If you find yourself marginally familiar with these topics and are interested in digging deeper, 现在暂停并下载优秀的 Postman application. 它允许您在不编写代码的情况下与api通信.

邮差仪表盘的截图

Postman. 也许是我最喜欢的开发工具?

但是,如果你对这些不熟悉,请继续阅读. 具有一定程度WordPress经验的技术观众将从本文中获益最多, 但我会尽力解释的 value 以一种不那么专业的方式来介绍每种技术. 非技术读者离开本文时,将能够在赞助本文之前评估每个点的ROI,并在交付后判断实现的质量.

Note: 如果您需要快速复习课程,您可以查看我们的 WordPress REST API guide.

With no further preamble, 请允许我与您分享一些不同的技术,我发现自己对大多数API都很欣赏, project, and team with which I work.

瞬态:什么时候握住它们,什么时候折叠它们

In my opening paragraph, 我注意到,客户发现跨越两个管理区域很烦人:wp-admin和他们的电子邮件服务的仪表板. A good way to resolve that would be to provide them with a dashboard widget in wp-admin, 显示他们最近的订阅者活动摘要.

wp-admin仪表板小部件的屏幕截图

An example of the type of dashboard UI that we might provide within WordPress, 为我们的客户省去了找第三方电子邮件服务提供商的麻烦.

But then again, 这可能需要向远程API(由电子邮件服务提供的API)发出多个HTTP请求。, resulting in long page loads. The solution to this performance problem is to store API calls as transients. This Codex article provides a great explanation that you should definitely read, but I’ll summarize it thusly:

  1. Get the data from the remote API.
  2. Store it using set_transient() with an expiration time of your choosing based on your own judgement about performance, rate limits, and the margin for error in displaying outdated data in this particular application.
  3. Proceed in your business logic—processing the data, returning a value, whatever the case may be.
  4. When you need the data again, such as on the next page load, 在暂态缓存中检查它 get_transient() 然后得出结论,您需要从API获取它.

我认为这是一个有益的和可行的基础, but you can take it a step further if you think for a moment about REST verbs. 在五个最常见的方法中(GET, POST, PATCH, PUT, DELETE), 其中只有一个属于你的临时缓存. Can you guess which one? It’s GET. In my plugins, I almost always have a PHP class dedicated to abstracting calls to the remote API in question, 实例化该类时的参数是HTTP方法. If it’s not a GET call, then I’m not going to invoke any caching layer at all.

Furthermore, if it’s not a GET call, then it stands to reason that I am taking some action to alter the remote data in some way, perhaps by adding, editing, or removing an email subscriber. This might be a good time to invalidate the existing cache for that resource, via delete_transient().

回到我们的WordPress邮件订阅API的例子, 以下是它在实践中的工作方式:

  • A dashboard widget for showing recent subscribers is going to call the API endpoint for /subscribers via a GET request. 因为它是一个GET请求,所以它被存储在我的临时缓存中.
  • A sidebar widget for subscribing to the email list is going to call the API endpoint for /subscribers via a POST request. Because it’s a POST request, 它不仅会避开我的暂存缓存, 这会促使我删除临时缓存的相关部分, 以便仪表板小部件反映这个新的订阅者.
  • When naming transients, I often organize them by literally naming them after the remote API URL that I am calling. 这是识别要删除的正确暂态的方便方法. 如果它是一个接受参数的端点, I’ll concatenate those into a string and add them to the transient name as well.

作为客户或其他技术含量较低的利益相关者, 在应用程序从远程服务提取数据的任何时候,都应该专门请求临时缓存——或者至少讨论一下. 你应该熟悉优秀的人 Query Monitor 插件来查看瞬态是如何工作的. It will give you an interface for browsing what data is being stashed as a transient, how frequently, and for how long.

有时候瞬变还不够好

一些高级WordPress托管服务实际上不允许你在生产环境中使用瞬态. They have code running, 也许以MU插件或其他脚本的形式, that will intercept your attempt to use the transients API and store that information via the object cache instead. WP-Engine,在其最常见的配置中,是这方面的一个主要例子.

标题中描述的phpMyAdmin视图的截图

An alarming sight in the phpMyAdmin UI: A production site completely devoid of transients? 这可能意味着对象缓存正在工作.

如果您只是存储和检索数据, you actually don’t have to care about this and may never even notice it’s happening. The entire family of *_transient() 函数将为您提供相同的最终结果, 只是过滤使用对象缓存而不是临时缓存. Where you might run into problems, though, is when attempting to delete transients. Here’s why.

如果您的API集成足够复杂,需要自己的设置页面, 您可能希望包含一个UI,以允许管理用户执行以下操作 清除插件的整个临时缓存. 此按钮最常见的用途是当客户端直接更改远程服务上的一些数据时, 并且想要使我们存储在WordPress中的缓存失效. This button might also come in handy if the client changes account credentials, API keys, 或者只是作为调试的“出厂重置”按钮.

Screenshot of option buttons

An example of a UI for allowing the client to empty the local cache for their API data.

即使您足够聪明,可以为所有的瞬态键命名空间,这样您就有希望识别它们中的每一个 delete_transient(),最好的情况可能仍然涉及原始SQL,这是我在WordPress中总是尽量避免的:

 get_transient_prefix() );
  $options = $wpdb -> options;
  $t = esc_sql("_transient_timeout_$prefix%");
  $sql = $wpdb -> prepare (
    "
      SELECT option_name
      FROM $options
      WHERE option_name LIKE '%s'
    ",
    $t
  );
  $transients = $wpdb -> get_col( $sql );
  // For each transient...
  Foreach ($transient作为$transient) {
    //去掉WordPress前缀,以便到达临时键.
    $key = str_replace('_transient_timeout_', ', $transient ');
    // Now that we have the key, use WordPress core to the delete the transient.
    delete_transient( $key );
  }
  
}
?>

Not convenient, not efficient. 相反,这种情况需要对象缓存 because object caching gives us a convenient way to group cached values together. This way, 当您需要清空与插件相关的所有缓存值时, it’s a simple one-liner call to wp_cache_delete( $key, $group ).

我可以这样总结: 如果还不擅长管理数据的缓存,就不可能成为使用api的专家.

As a client, 需要注意的关键是在登台环境和生产环境之间异常的缓存行为. In other words, 尽管在暂存阶段测试新一批工作始终是一种很好的做法, caching is something that must also be tested in production with equal care.

远程API可以帮助告知你的PHP类层次结构

在为我的插件布置各种PHP类时, I often find it helpful to mimic the way the API endpoints are defined—for example, 以下端点似乎有什么共同之处?

They all return collections, 我指的是GET请求的结果, 返回0到多的结果,其中每个结果都是数组的一个成员. That might sound fairly obvious, but I find it to be a helpful prompt for the following class structure in my PHP code:

  • class.collection.php, an abstract class
  • class.subscribers.php extends the abstract class, Collection.
  • class.lists.php extends the abstract class, Collection.
  • class.campaigns.php extends the abstract class, Collection.

抽象类将把查询参数数组作为它的唯一参数:分页之类的东西, sort column, sort order, and search filters. 它将具有用于调用远程API等常见任务的方法, handling errors, 并可能将结果转化为HTML

输入您的电子邮件,即表示您同意我们的 privacy policy.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

Join the Toptal® community.