我想更快地向 WordPress API 发出请求。我的 API 在插件中实现(使用 register_rest_route 注册我的路线)。然而,由于这是一个插件,所有东西都被它加载了(子主题和主题)并且基本上对这个 API 的查询需要半秒钟,因为加载了所有这些无用的部分。
WordPress API 不能以其他方式使用吗?由于大多数使用 WP-API 的插件不需要加载任何其他插件,更不用说主题了……我不明白他们怎么会错过。
有没有办法做到这一点?
我想更快地向 WordPress API 发出请求。我的 API 在插件中实现(使用 register_rest_route 注册我的路线)。然而,由于这是一个插件,所有东西都被它加载了(子主题和主题)并且基本上对这个 API 的查询需要半秒钟,因为加载了所有这些无用的部分。
WordPress API 不能以其他方式使用吗?由于大多数使用 WP-API 的插件不需要加载任何其他插件,更不用说主题了……我不明白他们怎么会错过。
有没有办法做到这一点?
对的,这是可能的。在我的一个插件中,我需要最小的 WordPress 核心(没有插件和主题的数据库),这就是我所做的:
<?php
define('SHORTINIT', true); // load minimal WordPress
require_once PATH_TO_WORDPRESS . '/wp-load.php'; // WordPress loader
// use $wpdb here, no plugins or themes were loaded
我编造的PATH_TO_WORDPRESS
常数;你只需要指出正确的路径。例如,在插件中,它可能看起来像:
require_once dirname(__FILE__) . '/../../../wp-load.php'; // backwards 'plugin-dir/plugins/wp-content'
设置SHORTINIT
为true
确实对性能有所帮助。
禁用后,WP_DEBUG
引导 WordPress 所需的时间如下:
如果这适用于您自己的需要性能的站点,您可以通过启用 OpCache(例如,最近版本中的 APC 或 PHP OpCache)来增加这一点。
SHORTINIT
但我相信上面定义和要求的 2 行代码wp-load.php
就是你要找的。
澄清一下,这个文件是插件的一部分,但它是独立于 WordPress 本身调用的(通过 Ajax 和直接调用)。它永远不会被插件或 WP 本身的任何其他部分包含或使用。
编辑: 由于 OP 实际上与 WP-API 相关,而不是一般的 WordPress,我添加它是为了解决实际问题。我会留下原来的答案内容,以防它可以帮助别人。
我用 WP API 做了进一步的测试,就像@David 在他的回答中说的那样,问题可能是别的。
除了其余的 api 之外,我还加载了 12 个插件,一些相当“大”的插件,我的本地安装安装了大约 25 个主题(当然一个是活动的)。我编辑了 WordPress 的index.php
文件并用于microtime(true)
记录一切开始的时间,然后编辑了一个 REST 控制器来计算从开始到到达 API 端点所用的时间。
我系统上的结果始终在0.0462
-0.0513
秒左右(没有 PHP OpCache,也没有其他系统负载)。因此,似乎引导所有 WordPress 对性能几乎没有影响。
如果请求需要半秒钟,那么瓶颈就在其他地方,并且删除插件和主题的影响将很小。至少这是我发现的。
我认为您可能专注于错误的问题。
加载 php 文件并不像从您的数据库中读取那么慢,这可能是您的 500 毫秒加载时间。无论如何,您实际上应该考虑减少这种情况(缓存 wp-options 等),但我对您的 api 建议是使用 mu-plugin 缓存输出。使用 exit 我们可以从文件加载输出并立即提供。
我们的方法: 1.在wp-content文件夹中创建一个文件mu-plugins
夹(可能已经有)
创建一个名为api-cache.php
将此代码输入到您的文件中:
function get_api_cache(){
//dont run if we are calling to cache the file (see later in the code)
if( isset($_GET['cachecall']) && $_GET['cachecall'] === true)
return;
$url = "$_SERVER[REQUEST_URI]";
//do a little error checking
$uri= explode('/',$url);
//we have a array (1st key is blank)
if( $uri[1] !== 'wp-json' || $uri[2] !== 'wp' || $uri[3] !== 'v2'){
return;
}
//lock down the possible endpoints we dont want idiots playing with this...
$allowed_endpoints= array(
'posts'
);
$endpoint= array_pop($uri); // not sure if this is valid or not, is there more structure to some api calls?
if( !in_array( $endpoint, $allowed_endpoints) ){
return;
}
//ok reasonably confident its a api call...
$cache_folder= get_stylesheet_directory().'/api_cache/';
// prob best if not within php server but to get you going
if(! file_exists ( $cache_folder ) ){
mkdir($cache_folder); //warning 777!!
}
/*
* Need to choose a method of control for your cached json files
* you could clear out the folder on update post/ taxonomies etc
* or cron clear out hourly/weekly whatever freq you want
*/
if( file_exists($cache_folder.$endpoint.'.json') ){
$json= file_get_contents($cache_folder.$endpoint.'.json');
header('Content-Type: application/json');
echo $json;
exit;// we need nothing else from php exit
} else {
//make sure there will be no errors etc..
$ch = curl_init();
$url= "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]?cachecall=true";
$timeout= 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$json = curl_exec($ch);
curl_close($ch);
file_put_contents($cache_folder.$endpoint.'.json', $json);
}
}
get_api_cache();
现在您应该注意到第二次加载时加载时间的显着差异(这是第一次缓存输出)。
一些免责声明:
你应该试试 这个。它是一个插件,允许您为帖子类型、页面和其他情况启用/禁用某些插件。
对于主题部分,如果您编写了它,很容易在 function.php 中添加一些内容,以防止它在 API 请求的情况下附加任何挂钩或过滤器。
作为旁注,您不能直接查询 de DB 吗?
如果这对您有帮助,请原谅我糟糕的英语。
将插件文件夹放在根 wordpress 安装中。
/public_html/my-plugin/my-plugin.php
and include wordpress main file.
require dirname( dirname( __FILE__ ) ).'/wp-load.php';
或者在插件文件夹中直接访问
/public_html/wp-content/plugins/my-plugin/my-plugin.php
require_once dirname(__FILE__) . '/../../../wp-load.php';
在检查 wp-load.php 文件是否正确包含并工作之前。
wp-settings.php 文件加载整个核心、插件和主题文件。wordpress 是加载第一个 mu-plugins 文件 (wp-content/mu-plugins/) 并在操作后提供挂钩muplugins_loaded。触发此操作以退出加载的所有其他文件。您还可以在muplugins_loaded之前找到提供了哪个操作挂钩并停止其他文件和脚本执行。
如果在包含 wp-load.php 之前定义常量 SHORTINIT,则它包含一些提供数据库、插件或基本功能的文件。当我们想要更多的加载核心文件而不是只想加载插件和主题文件时,这种方式找到了解决方案。
// file my-plugin.php
//call before include file wp-load.php
global $wp_filter;
$wp_filter = array(
// pass wp hook where to want exit extra wp loaded
'muplugins_loaded' => array(
// prority
1 => array(
// callback function register
'wp_extra_loaded_exit' => array(
'function' => 'wp_extra_loaded_exit',
'accepted_args' => 1
)
)
)
);
function wp_extra_loaded_exit(){
exit;
}
require dirname( dirname( __FILE__ ) ).'/wp-load.php';
// plugin code here.
我们检查muplugins_loaded钩子是否提前定义了 wordpress,您还可以找到在muplugins_loaded之前定义的钩子,然后在加载更多 wordpress 文件后停止该点。-
当你想测试你的脚本打开文件 wp-settings.php 并找到字符串 muplugins_loaded 然后回显语句来检查。
echo "Wordpress loaded in this point before";
do_action( 'muplugins_loaded' );
echo "After this wordpress not loading"; // Output fail bcz we exit