Я хотел бы сделать запросы к WordPress API намного быстрее. Мой API реализован в плагине (с помощью register_rest_route для регистрации моих маршрутов). Однако, поскольку это плагин, все загружается с ним (дочерняя тема и тема), и в основном запрос к этому API занимает половину секунды из-за загрузки всех этих бесполезных частей.
Разве WordPress API не может использоваться по-другому? Поскольку для большинства плагинов, использующих WP-API, не нужны никакие другие плагины для загрузки, тем более тема … Я не понимаю, как они могли это пропустить.
Есть какой-либо способ сделать это?
Да, это возможно. В одном из моих плагинов, где мне нужно минимальное ядро WordPress (DB без плагинов и тем), вот что я делаю:
<?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 в последних версиях).
Но я считаю, что 2 строки кода выше определяют SHORTINIT
и требуют, чтобы wp-load.php
– это то, что вы ищете.
Чтобы уточнить, этот файл является частью плагина, но он вызывается независимо от самого WordPress (через Ajax и напрямую). Он никогда не включается и не используется другими компонентами плагина или самого WP.
EDIT: Поскольку OP фактически связан с WP-API, а не с WordPress вообще, я добавляю это для решения актуального вопроса. Я оставлю исходный контент ответа, если он может помочь кому-то другому.
Я продолжал тестирование с помощью WP API и, как сказал @David в своем ответе, проблема, вероятно, что-то еще.
Я загрузил 12 плагинов в дополнение к остальным api, некоторые довольно «большие» плагины, а моя локальная установка содержит около 25 тем (один, конечно, конечно). Я отредактировал файл index.php
WordPress и использовал microtime(true)
для записи, когда все началось, а затем отредактировал один из контроллеров REST, чтобы рассчитать, сколько времени потребовалось от начала до получения конечной точки API.
Результат в моей системе постоянно составляет 0.0462
– 0.0513
секунд (без PHP OpCache и никакой другой загрузки системы). Таким образом, при загрузке WordPress мало влияет на производительность.
Если запросы занимают полсекунды, узкое место находится в другом месте, и вырезание плагинов и тем будет иметь минимальный эффект. По крайней мере, это то, что я нашел.
Я думаю, вы можете сосредоточиться на неправильном вопросе.
Загрузка php-файлов не так медленна, как чтение из вашего db, и это, вероятно, будет ваше время загрузки 500 мс. Вы должны на самом деле смотреть на снижение этого (параметры кэша wp и т. Д.), Но то, что я предлагаю вам по отношению к api, заключается в кэшировании вывода с использованием mu-plugin. Используя exit, мы можем загружать выходные данные из файла и обслуживать его мгновенно.
Наш метод: 1. Создайте папку с именем mu-plugins
в папке wp-content (возможно, она уже существует)
создайте файл 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();
Теперь вы должны заметить существенную разницу в времени загрузки на втором загрузке (это первый раз, когда он кэширует выход).
Несколько отказов:
Вы должны попробовать это . Это плагин, который позволяет включать / отключать определенные плагины для пост-типов, страниц и других обстоятельств.
Для части темы, если вы ее написали, было бы легко добавить что-то в функцию.php, чтобы предотвратить присоединение каких-либо крючков или фильтров в случае запроса API.
Как пропустить, вы не могли бы напрямую запросить 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 /) и предоставляет после действия hook muplugins_loaded . Запустите это действие, чтобы выгрузить все остальные загруженные файлы. Вы также можете найти, какой action hook предоставляет до muplugins_loaded и останавливать другие файлы и выполнение скриптов.
если определить константу SHORTINIT до включения wp-load.php, она включает в себя некоторые файлы, обеспечивающие DB, плагин или базовые функции. Когда мы хотим больше загружать файлы ядра, а не просто загружать плагины и файлы тем, то нашли решение.
// 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 hook определяет wordpress раньше, вы также можете определить, какой крючок определяется перед muplugins_loaded, а затем остановить эту точку после загрузки большего количества файлов WordPress. –
Если вы хотите протестировать свой скрипт, откройте файл wp-settings.php и найдите строку muplugins_loaded, затем выполните проверку echo.
echo "Wordpress loaded in this point before"; do_action( 'muplugins_loaded' ); echo "After this wordpress not loading"; // Output fail bcz we exit