12
votes

Approche de traduction PHP simple - votre opinion

Je fais un site Web PHP, sans utiliser de cadre. J'ai besoin que le site soit disponible en plusieurs langues et je lisais à ce sujet et cela semble être un peu déroutant. Il existe plusieurs solutions, mais tous semblent dépendre d'un cadre spécifique.

Ce que vous pensez d'utiliser une simple fonction de traduction comme celui indiqué ci-dessous?

Je veux dire, je voudrais savoir ce qui peut être un inconvénient d'utiliser ce code. Ici, c'est (ceci est juste un échantillon simple et incomplet): xxx


1 commentaires

Si vous pouvez utiliser gettext (que vous devriez), jetez un coup d'œil à php-i18n pour une classe d'introduction et d'assistance complète.


10 Réponses :


17
votes

Cela n'a pas l'air mauvais. J'ai vu cela utilisé plusieurs fois.

Je séparerai cependant les différentes chaînes d'un fichier par langue. Au moins, ou si les fichiers deviennent grands, un fichier par module par langue. P>

alors votre classe de traduction peut charger et mettre en cache les fichiers de langue (si vous ne comptez pas sur un autre système de mise en cache) à chaque fois Une nouvelle langue doit être utilisée. P>

Un petit exemple de ce que je veux dire p> xxx pré>

Ceci recherchera des fichiers .txt nommé après la langue ayant des entrées comme celui-ci p>

foo = foo
Bar = bar p> blockQuote>

retourne toujours à la chaîne d'origine au cas où il ne trouve aucune traduction. P>

C'est un exemple très simple. Mais il n'y a rien de mal à mon avis avec le faire par vous-même si vous n'avez pas besoin d'un cadre plus gros. P>

Pour l'utiliser de manière beaucoup plus simple, vous pouvez toujours le faire et créer un fichier appelé "EN_Example .txt ' p> xxx pré>

Parfois, vous souhaitez traduire des chaînes contenant des variables. Une telle approche est celle que je trouve assez simple à utiliser de temps en temps. P>

public function __() {
    if (func_num_args() < 1) {
        return false;
    }
    $args = func_get_args();
    $str = array_shift($args);
    if (count($args)) {
        return vsprintf(parent::__($str, $this->lang . '_' . $this->package),$args);
    }
    else {
        return parent::__($str, $this->lang . '_' . $this->package);
    }
}


0 commentaires

2
votes

C'est bien de ne pas utiliser un cadre. Le seul problème que je vois avec votre fonction est qu'il charge de nombreuses données dans la mémoire. Je recommanderais d'avoir des matrices pour chaque langue, de cette façon, vous n'auriez besoin que de charger la langue utilisée.


2 commentaires

Je suis désolé mon manque d'expérience, mais comment puis-je gérer différentes tableaux d'une classe? Merci


@Sandro, vous voudriez avoir un boîtier de commutation ou un bloc-même sur la langue qui exécuterait un inclure pour le fichier de langue pour une langue donnée. De cette façon, vous pouvez stocker des fichiers de langue séparément.



2
votes

L'avantage d'utiliser une classe ou des fonctions à cet égard est que vous pouvez modifier le stockage des langues car le projet augmente. Si vous n'avez que quelques cordes, il n'y a absolument aucun problème avec votre solution.

Si vous avez beaucoup de chaînes, cela pourrait prendre du temps, de la mémoire et des ressources harddrifiques pour charger les tableaux de langue sur toutes les charges de la page. Ensuite, vous voulez probablement diviser jusqu'à différents fichiers ou peut-être même utiliser un backend de base de données. Si vous utilisez la base de données I, envisagez d'utiliser la mise en cache (par exemple MEMCACHED ) afin que vous n'ayez pas besoin d'interroger la base de données des centaines de fois. avec chaque charge de page.

Vous pouvez également consulter GetText qui utilise des fichiers de langue précompilés qui sont vraiment rapides.


0 commentaires

4
votes

Il y a quelques éléments qu'il apparaît que vous n'avez pas pris en compte:

  • Vous traduisez simplement des mots simples? Qu'en est-il de la structure de phrase et de la syntaxe qui diffère entre les langues?
  • Que faites-vous quand un mot ou une phrase n'a pas encore été traduit dans une langue?
  • Vos traductions prennent-elles des variables? L'ordre des mots dans une phrase peut différer dans différentes langues et si vous avez une variable, elle ne sera généralement pas assez bonne pour diviser le mot autour de la phrase.

    Il y a deux solutions que j'ai utilisées et recommanderais pour PHP:


1 commentaires

Cela semble être moins de scénario de "traduction", et plus d'un scénario "alternatif de mise en œuvre de langues", à quel point il est tout simplement un tas de chaînes prédéterminées sur le backend. Les préoccupations de la syntaxe devraient alors être hors de propos.



2
votes

J'aurais pensé qu'il pourrait être plus facile d'utiliser simplement une inclure pour chaque langue, dont le contenu pourrait simplement être une liste de définition.

En faisant cela, vous éviteriez les frais généraux d'inclure toutes les données linguistiques et de la surcharge de l'appel de votre fonction 'Traduire' sur une base régulière.

là encore, cette approche limitera les choses en termes de flexibilité future. (Cela peut ne pas être un facteur cependant.)


6 commentaires

ne pensais pas à ça! Cela semble encore plus simple! Et cela semble résoudre les problèmes mentionnés avant ... merci


Ce n'est en aucun cas une solution parfaite, mais c'est probablement aussi simple que possible. Rappelez-vous juste - UTF8 est votre ami. :-)


Et définir votre ennemi est votre ennemi ... :-)


J'ai travaillé avec la traduction effectuée avec définition avant, jetez un coup d'œil à OsCommerce ou à tout dérivé de celui-ci. Ce système tombe assez rapide.


@Pter Lindqvist. Ugh - Vous avez dit le mot "O". (Je frémise à la mémoire passée.) Comme je l'ai dit, ce n'est pas une solution parfaite. C'est cependant simple et peut suffire à un petit projet.


@middaparka ouais, tu as raison. Mais je refuserais simplement en fonction de l'expérience antérieure. Parfois, les méthodes simples sont les meilleures, mais parfois elles ne suffisent pas assez.



1
votes

Quand j'ai eu un problème comme celui-ci (mais pour un très petit site, quelques pages) il y a longtemps, j'ai créé un fichier nommé langpack.php code> et toute chaîne de texte sur mon le site devait être couru à travers cela. Maintenant, j'utiliserais une approche similaire, mais scinder plusieurs fichiers.

Exemple d'approche OOP H2>

LANGPACK.PHP H3>
$langpack = new $_SESSION['language'];
echo $langpack::get('inbox');


5 commentaires

__get est un tueur de performance !! J'avais l'habitude de faire quelque chose comme ça pour ma classe de configuration, mais j'ai trouvé que c'était beaucoup plus rapide de passer à travers le tableau $ de données et de rendre toutes les variables publiques


Également! Dans la note manuelle: les propriétés ne peuvent pas être déclarées finales, seules des classes et des méthodes peuvent être déclarées en finale.


Hah, j'ai fait deux erreurs dans la version originale; Corrigez les deux et supprimé la fonction magique. En outre, le tueur de performance est un peu surestimé, sauf si vous courez sur une boîte qui mesure des performances dans une MHz individuelle.


C'est en effet un tueur de performance. J'ai profilé du site Web que j'ai fait et j'ai remarqué que l'heure d'accès, en utilisant la méthode __get, était très très élevée par rapport à l'accès normal


C'est une histoire ancienne, vraie, mais: "donnant accès aux variables des membres directement en les déclarant que le public est autorisé mais découragé en faveur des méthodes d'accesseur (set & get)." de Framework.zend.com/Manual/fr/coding-standard .coding-style.ht ml - juste dire '



1
votes

utilise des constantes (définies) une mauvaise pratique?

C'est comme ça que j'ai la configuration. Il suffisait d'avoir un support multi-langua.

J'ai un fichier portugais et un fichier anglais rempli de: xxx

peut-être que ceci est un peu une mémoire porc, mais je peux accéder à tous les endroits où je veux :)

Je peux passer à une approche d'OOP, mais pour l'instant, j'ai ceci.


1 commentaires

Oui, c'est une mauvaise approche. Essayez de définir une traduction pour le mot true ou grouper. Ceux-ci existent déjà. Vous voulez empêcher les affrontements de nom. Un choix serait de préfixer toutes les constantes, mais vous ne pouvez jamais être sûr d'une tierce partie liber la même constante. En règle générale: placez le moins possible dans la portée mondiale. Capsule ce qui appartient ensemble. Voir php.net/manual/fr/userlandnaming.php .



0
votes

Je pense que ça va si vous n'utilisez aucun cadre pour d'autres raisons. Nous avons été dans le même scénario que le vôtre, lorsque vous ne pouvez pas / ne veut pas utiliser un cadre de traduction plus structuré:

Nous travaillions dans un petit projet PHP et que vous recherchez un mécanisme de traduction simple. Nous avons utilisé une approche de tableau semblable à la vôtre, mais avec des fichiers séparés pour chaque textes de langue. Nous avons mis en place un petit composant pour que Thins soit aussi propre que possible.

Si vous voulez donner un look, nous avons partagé que sur https://github.com/ BrainCrummbz / Simple-PHP-Traduire . N'hésitez pas à l'améliorer!


0 commentaires

1
votes

On pourrait également utiliser le Composant de traduction Symfony , aucun cadre est requis et Compositeur aide à faire face aux dépendances:

compositeur installer --Prefer-dist "symfony / traduction": "@ stable"


0 commentaires

0
votes

J'utiliserais simplement une fonction avec des entrées de contrôleur et de langue, par exemple: xxx

Vous devez simplement placer vos chaînes formatées JSON dans lang / index / en.json si le contrôleur est index et la langue est en. Vous pouvez ajouter une fonction pour les dépendances (par exemple, vous souhaitez charger des valeurs de contrôleur d'index sur l'accès à un autre contrôleur) tout ce que vous avez à faire est de fusionner les résultats. Vous pouvez simplement inclure des fichiers PHP avec des tableaux ASWELL et simplement renvoyer le tableau, mais je vous suggère de scinder ces traductions dans des projets plus importants. Si votre projet n'est pas si gros, votre fonction est absolument correcte.


0 commentaires