Pour obtenir des valeurs à partir d'entités, il existe deux façons:
- Utilisez
field_get_items
et obtenez la valeur d'un champ - Utilisez
entity_metadata_wrapper
et obtenez la valeur d'un champ
Bien qu'il entity_metadata_wrapper
résume les différences de langage, son API est parfois maladroite, surtout lors de l'utilisation de PHP 5.3. Par exemple, obtenir la valeur d'un long champ de texte suit généralement 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 plus les performances. Comment fonctionnent-ils tous les deux? Interrogent-ils la base de données chaque fois qu'ils demandent une valeur? Est-ce que entity_metadata_wrapper
demande tout à la fois? (Rendre field_get_item
plus adapté aux extractions à valeur unique.)
Je ne suis pas assez courageux pour plonger profondément dans la source Drupal.
la source
field_view_field()
sert au rendu d'un champ. La fonction pour obtenir la valeur d'un champ est field_get_items () .field_get_items()
n'encourt aucun frais généraux de base de données, donc je pense que c'est un cas assez ouvert et fermé :)field_get_items()
surcharge de la base de données soit nulle? Il doit obtenir ses données quelque part, non?entity_metadata_wrapper
fonctionne, en termes de performances.field_get_items()
donc le surcoût a déjà été encouru ... c'est un peu une route étranglée en D7 pour être honnêteRéponses:
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 à partir de la base de données . Par exemple:
ou, comme vous l'avez déjà suggéré:
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 pouvez le faire,
print $node->field_my_field_name[LANGUAGE_NONE][0]['value'];
mais cela générerait des erreurs de notification PHP si le champ n'a pas de valeur, car vous essayez d'accéder à des tableaux qui n'existent peut-être pas (par exemple[LANGUAGE_NONE][0]['value']
). Je me retrouve à faire cela assez souvent ces derniers temps:ce qui est beaucoup plus propre que de le faire:
Si vous regardez le code,
field_get_items())
vous verrez qu'il ne fait rien de plus que de vous assurer que le tableau du champ contient des données dans le langage courant, puis de les renvoyer. 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: Étant donné que les
field_get_items()
exécutions,field_language()
il y aurait en fait un impact sur les performances plus important que la simple vérification de la langue, donc, si vous savez déjà que le langage $ entity-> existe, vous pouvez simplement écrire votre propre fonction super performante:la source
$node = node_load(123);
dans 1 script et que vous le faites à nouveau ailleurs, vous n'encourez pas la surcharge de performances d'une charge et d'une génération d'objet complètes - Drupal affecte simplement à cette variable une copie de l'entité existante. Si vous souhaitez charger une nouvelle copie, vous devez passer$reset = TRUE
à la fonction de chargement d'entité. Voir aussi mes modifications concernant un getter super performant.if (isset($node->field_my_field_name[LANGUAGE_NONE]) && isset($node->field_my_field_name[LANGUAGE_NONE][0])) {
n'est pas nécessaire,isset($node->field_my_field_name[LANGUAGE_NONE][0]
suffit.isset($node->field_my_field_name[LANGUAGE_NONE])
, car la langue ne sera pas définie sur un champ vide? Je pense que c'est le delta /[0]
qui est redondant.