web-dev-qa-db-fra.com

Quel est le plus performant: entity_metadata_wrapper ou field_get_items?

Pour obtenir des valeurs à partir d'entités, il existe deux manières:

  • Utilisez field_get_items Et obtenez la valeur d'un champ
  • Utilisez entity_metadata_wrapper Et obtenez la valeur d'un champ

Bien que entity_metadata_wrapper Résume les différences de langage, son API est parfois maladroite, en particulier lors de l'utilisation de PHP 5.3. Par exemple, obtenir la valeur d'un champ de texte long va généralement dans cette voie :

$field = $wrapper->field->value();
print $field['safe_value'];

Heureusement, PHP 5.4 prend en charge cette syntaxe: print $wrapper->field->value()['safe_value'];.

Mais ma question concerne davantage la performance. Comment fonctionnent-ils tous les deux? Interrogent-ils la base de données chaque fois qu'ils demandent une valeur? entity_metadata_wrapper Demande-t-il tout à la fois? (Rendre field_get_item Plus adapté aux récupérations à valeur unique.)

Je ne suis pas assez courageux pour plonger profondément dans la source Drupal.

10
Florian Margaine

La réponse courte: field_get_items () est plus performant que entity_metadata_wrapper ().

Consultez le code de ces fonctions:

Les deux nécessitent que vous transmettiez l'entité, qui a déjà été chargée depuis la base de données. Par exemple:

$node = node_load(123);
$items = field_get_items('node', $node, 'field_my_field_name');
print $items[0]['value'];

ou, comme vous l'avez déjà suggéré:

$wrapper = entity_metadata_wrapper('node', $node);
$field = $wrapper->field_my_field_name->value();
print $field['safe_value'];

Ces deux cas me dérangent un peu à cause de la logique stupide d'essayer d'obtenir une valeur qui est déjà à votre disposition, mais ils sont certainement utiles dans de nombreux cas.

Vous pourriez simplement faire print $node->field_my_field_name[LANGUAGE_NONE][0]['value']; Mais cela lancerait PHP remarquera des erreurs si le champ n'a pas de valeur, puisque vous essayez d'accéder à des tableaux qui n'existent peut-être pas (par exemple [LANGUAGE_NONE][0]['value']). Je me retrouve à le faire assez souvent ces derniers temps:

if ($field = field_get_items('node', $node, 'field_my_field_name')) {
  print $field[0]['value'];
}

ce qui est beaucoup plus propre que de le faire:

if (isset($node->field_my_field_name[LANGUAGE_NONE]) && isset($node->field_my_field_name[LANGUAGE_NONE][0])) {
  print $node->field_my_field_name[LANGUAGE_NONE][0]['value'];
}

Si vous regardez le code de field_get_items()), vous verrez qu'il ne fait rien de plus que de s'assurer que le tableau du champ contient des données dans le langage courant, puis les renvoie. Ainsi, les frais généraux liés à l'exécution d'une fonction aussi minuscule sont négligeables, mais si vous êtes vraiment préoccupé par les performances, vous pouvez simplement vérifier par vous-même si les données existent, puis les imprimer.

Edit: Puisque field_get_items() s'exécute field_language() il y aurait en fait une plus grande performance frapper que de simplement vérifier la langue, donc, si vous savez déjà que la langue $ entity-> existe, vous pouvez simplement écrire votre propre fonction super performante:

function my_super_performant_field_value_getter($entity, $field_name) {
  return isset($entity->{$field_name}[{$entity->language}]) ? $entity->{$field_name}[{$entity->language}] : FALSE;
}
12
Charlie Schliesser