Add the apcu caching ability for performance (#7276)

* add the apcu caching ability for performance
When the PHP extension APCu is loaded, the settings class and the auto_loader will cache their results across requests in RAM. For more information about the APCu extension visit the PHP page: https://www.php.net/apcu

* use global instead of default terminology
This commit is contained in:
frytimo
2025-02-25 20:21:41 -04:00
committed by GitHub
parent 305f585b17
commit d919a3cc1b
7 changed files with 171 additions and 37 deletions

View File

@@ -53,6 +53,12 @@ class settings {
*/
private $database;
/**
* Tracks if the APCu extension is loaded for database queries
* @var bool
*/
private $apcu_enabled;
/**
* Create a settings object using key/value pairs in the $setting_array.
*
@@ -63,6 +69,16 @@ class settings {
*/
public function __construct($setting_array = []) {
//try to use RAM cache by default
if (!isset($setting_array['allow_caching'])) {
$setting_array['allow_caching'] = true;
}
//track ram caching
if ($setting_array['allow_caching']) {
$this->apcu_enabled = function_exists('apcu_enabled') && apcu_enabled();
}
//open a database connection
if (empty($setting_array['database'])) {
$this->database = database::new();
@@ -155,7 +171,7 @@ class settings {
* @param bool $enabled (optional) True or False. Default is True.
* @param string $description (optional) Description. Default is empty string.
*/
public function set(string $table_prefix, string $uuid, string $category, string $subcategory, string $type = 'text', string $value = "", bool $enabled = true, string $description = "") {
public function set(string $table_prefix, string $uuid, string $category, string $subcategory, string $value = "", string $type = 'text', bool $enabled = true, string $description = "") {
//set the table name
$table_name = $table_prefix.'_settings';
@@ -207,6 +223,15 @@ class settings {
*/
private function default_settings() {
//set the key for global defaults
$key = 'settings_global_' . $this->category;
//if the apcu extension is loaded get the already parsed array
if ($this->apcu_enabled && apcu_exists($key)) {
$this->settings = apcu_fetch($key);
return;
}
//get the default settings
$sql = "select * from v_default_settings ";
$sql .= "where default_setting_enabled = 'true' ";
@@ -247,7 +272,11 @@ class settings {
}
}
}
unset($sql, $result, $row);
//if the apcu extension is loaded store the result
if ($this->apcu_enabled) {
apcu_store($key, $this->settings);
}
}
/**
@@ -255,13 +284,22 @@ class settings {
* @access private
*/
private function domain_settings() {
$sql = "select * from v_domain_settings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and domain_setting_enabled = 'true' ";
$parameters['domain_uuid'] = $this->domain_uuid;
$result = $this->database->select($sql, $parameters, 'all');
unset($sql, $parameters);
$key = 'settings_domain_'.$this->domain_uuid;
$result = '';
//if the apcu extension is loaded get the cached database result
if ($this->apcu_enabled && apcu_exists($key)) {
$result = apcu_fetch($key);
} else {
$sql = "select * from v_domain_settings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and domain_setting_enabled = 'true' ";
$parameters['domain_uuid'] = $this->domain_uuid;
$result = $this->database->select($sql, $parameters, 'all');
//if the apcu extension is loaded store the result
if ($this->apcu_enabled) {
apcu_store($key, $result);
}
}
if (!empty($result)) {
//domain setting array types override the default settings set as type array
foreach ($result as $row) {
@@ -305,7 +343,6 @@ class settings {
}
}
unset($result, $row);
}
/**
@@ -314,15 +351,25 @@ class settings {
* @depends $this->domain_uuid
*/
private function user_settings() {
$sql = "select * from v_user_settings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and user_uuid = :user_uuid ";
$sql .= " order by user_setting_order asc ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['user_uuid'] = $this->user_uuid;
$result = $this->database->select($sql, $parameters, 'all');
if (is_array($result)) {
$key = 'settings_user_'.$this->user_uuid;
$result = '';
//if the apcu extension is loaded get the cached database result
if ($this->apcu_enabled && apcu_exists($key)) {
$result = apcu_fetch($key);
} else {
$sql = "select * from v_user_settings ";
$sql .= "where domain_uuid = :domain_uuid ";
$sql .= "and user_uuid = :user_uuid ";
$sql .= " order by user_setting_order asc ";
$parameters['domain_uuid'] = $this->domain_uuid;
$parameters['user_uuid'] = $this->user_uuid;
$result = $this->database->select($sql, $parameters, 'all');
//if the apcu extension is loaded store the result
if ($this->apcu_enabled) {
apcu_store($key, $result);
}
}
if (!empty($result)) {
foreach ($result as $row) {
if ($row['user_setting_enabled'] == 'true') {
$name = $row['user_setting_name'];
@@ -406,4 +453,34 @@ class settings {
}
}
}
/**
* Clears the settings cache
* @param string $type Empty clears all settings. Values can be global, domain, or user.
*/
public static function clear_cache(string $type = '') {
if (function_exists('apcu_enabled') && apcu_enabled()) {
switch ($type) {
case 'all':
case '':
default:
$type = "";
break;
case 'global':
case 'domain':
case 'user':
$type .= "_";
break;
}
$cache = apcu_cache_info(false);
if (!empty($cache['cache_list'])) {
foreach ($cache['cache_list'] as $entry) {
$key = $entry['info'];
if (str_starts_with($key, 'settings_' . $type)) {
apcu_delete($key);
}
}
}
}
}
}