web-dev-qa-db-fra.com

Différence entre drupal_static et \ Drupal :: state?

Imaginez que j'ai une valeur difficile à calculer.

$my_heavy_value = compute_heavy_value();

Quelle est la différence, au niveau des performances, entre le stockage de la valeur calculée à l'aide de drupal_static() et à l'aide de \Drupal::state()?

Lequel est stocké dans la base de données? Y en a-t-il un qui est stocké en mémoire?

4
leandro713

Ils effectuent différentes tâches.

drupal_static() stocke uniquement les données pour le chargement de la page en cours (ou le chargement ajax). Par exemple, si vous chargez quelque chose à partir d'une table de base de données plusieurs fois sur un seul chargement de page (c'est-à-dire - un compte d'utilisateur), la première fois qu'il est chargé, il est enregistré en mémoire et la prochaine fois qu'il est nécessaire, il est extrait de la mémoire, plutôt que de le recharger à partir de la base de données, ce qui enregistre cette deuxième requête de base de données.

Drupal::state() enregistre les données dans la base de données, où elles peuvent être récupérées lors de futures requêtes. C'est une sorte de cache.

Vous pouvez réellement les utiliser en conjonction les uns avec les autres comme suit:

function get_some_value()
{
  // Instatiate the static
  $value = &drupal_static(__FUNCTION__);
  // Check if the value has already been set in this page load
  if(is_null($value))
  {
    // The value has not yet been set for this page load,
    // so retrieve it from the state if it exists, and if it
    // does, then save that to the static
    $value = \Drupal::state()->get('my_value');
    // Check if the value was retrieved from the state
    if(!$value)
    {
      // The value was not retrieved from the state, so
      // it needs to be generated. Below is an example
      // fetching it from the database
      $value = db_query('SELECT some_value FROM {some_table} WHERE some_column = :some_value', [':some_value' => 'some value'])->fetchField();

      // Save it to the state for future page loads
      \Drupal::state->set('my_value', $value);
    }
  }

  // Return the value
  return $value;
}

Avec le code ci-dessus, la première fois que cette fonction est exécutée, elle vérifiera d'abord si la valeur existe dans le cache statique (ce chargement de page), et quand ce n'est pas le cas, elle essaie de la récupérer dans le cache d'état, et quand il ne le génère finalement pas avec une requête de base de données, l'enregistrant à la fois dans le cache statique, ainsi que dans l'état.

S'il frappe à nouveau cette fonction au même chargement de page, la valeur sera dans le cache statique, donc aucun du code interne n'est nécessaire, et la valeur est renvoyée par le cache statique.

Lors d'un chargement de page futur, la première fois que cette fonction est lancée, rien n'est récupéré du cache statique, donc il le tirera du cache d'état. Si la fonction est à nouveau frappée lors de ce chargement de page, la valeur sera dans le cache statique et sera renvoyée à partir de cela.

10
Jaypan

drupal_static() est utilisé pour mettre en cache les données dans une seule demande de page. il stocke les données dans une variable statique.
La classe renvoyée par \Drupal::state() gère les valeurs qui doivent être conservées entre les requêtes. En tant que tel, il est probable qu'il stocke ses valeurs dans une table de base de données. (Cela dépend de l'implémentation exacte effectuée à partir de cette classe.)

drupal_static() est plus rapide car il enregistre ses valeurs dans la mémoire, mais l'utilisation des états ne fait pas beaucoup de différence.

Quant à recommander un, les deux sont recommandés. À vous de choisir celui qui correspond à vos besoins. Avez-vous besoin d'une valeur de demande croisée ou d'une valeur que vous utilisez uniquement dans une demande?

Si vous cherchez à remplacer drupal_static() par OOP code, Drupal 8.6 a introduit le MemoryCache classe, qui stocke les éléments du cache en mémoire à l'aide d'un tableau PHP. Il a été ajouté pour autoriser les classes qui maintiendraient précédemment l'état d'une propriété protégée (en tant que cache statique pour éviter le cache persistant ou recherche de base de données) pour injecter un service pour conserver cet état à la place. (Voir Cache mémoire ajouté .)
Notez que la classe n'est pas utilisée directement. Le module qui en a besoin doit définir un nouveau service, de la même manière que ce que fait Drupal core avec le entity.memory_cache service.

entity.memory_cache:
  class: Drupal\Core\Cache\MemoryCache\MemoryCache
5
kiamlaluno

Lorsque vous souhaitez stocker des données difficiles à calculer en mémoire, vous utilisez une variable statique. Mais pour stocker ces données dans la base de données, State API n'est pas le bon endroit, malgré le nom similaire:

L'API d'état permet aux développeurs de stocker des informations sur l'état du système.

Un état système est par exemple la dernière exécution de cron. L'API d'état \Drupal::state N'a donc rien à voir avec la mise en cache.

Utilisez plutôt l'API de cache Drupal::cache().

Exemple de stockage des données dans le cache:

\Drupal::cache('data')->set($cid, $data, Cache::PERMANENT, ['heavy:' . $heavy_id]);

$cid Est une clé de cache unique, qui est utilisée pour récupérer les données du cache:

$data = \Drupal::cache('data')->get($cid);

Vous pouvez utiliser la balise de cache que vous avez définie ci-dessus comme quatrième paramètre pour invalider l'entrée de cache si elle devient obsolète:

\Drupal\Core\Cache\Cache::invalidateTags(['heavy:1']);
5
4k4