J'ai une fonction qui génère une clé de 4 caractères qui doit être unique pour chaque fois. Pour ce faire, la fonction génère d'abord une clé, puis vérifie une table de base de données pour voir si elle est utilisée par quelqu'un d'autre.
Si ce n'est pas utilisé, il retourne la clé, sinon, elle s'appelle à nouveau, Mais cela provoque la fonction de faire une boucle infinie, ce qui est un non-non. Voici toute la fonction: p> Quel est le moyen correct d'appeler la fonction à nouveau? P> Au fait, j'utilise le codeigniter, donc < code> $ CU code>. p> p>
7 Réponses :
Vous pouvez mettre votre code dans une boucle et déterminer la clé La boucle elle-même n'empêche pas une boucle infinte, mais contrairement à une fonction Appelez, cela ne mange pas d'espace de pile, de sorte que vous ne risquez pas de débordement d'une pile. P> aussi il simplifie un peu les choses. Selon le type de clé, vous pouvez également adapter la méthode de la génération de clé, par exemple avec des touches numérotées, vous pouvez augmenter de manière exponentielle avec chaque itération. P> Remarques: strong> Si c'est possible, Utilisez la fonction d'incrémentation automatique d'une base de données au lieu de rouler votre propre fonctionnalité de génération de clé. p> Assurez-vous également de protéger votre code contre un accès simultané. Et si deux instances de cette fonction tentent de générer une clé et qu'ils déterminent tous les deux la même chose? Utilisez des sections ou des transactions critiques pour vous assurer que rien de mal ne se produit. P> p>
Mais cela provoque la fonction de faire une boucle infinie, p>
Si vous voulez absolument garder votre stratégie récursive, vous devez définir une affaire de fin. Par exemple, vous pouvez définir un compteur, comme celui-ci: p>
xxx pré> Il est toutefois aussi possible de faire votre code itérus ... p> blockquote>
Je n'utiliserais pas de fonctions récursives pour les scénarios de réessayage (puisque vous ne réutilisez pas le résultat de la fonction, il est inutile d'utiliser la récursion) ... Il ajoute beaucoup de frais généraux inutiles. Faites quelque chose comme ceci: Si vous êtes proche du nombre maximum de clés, cela entraînera une longue période de boucle, de sorte que vous souhaiterez peut-être mettre une sorte de limite maximale. P> OH, et si cela se produit sur plusieurs threads simultanément et que vous vérifiez une base de données, vous devez implémenter le verrouillage d'écriture de table afin que la même clé ne puisse pas être insérée deux fois. De préférence, la fonction qui vérifie si une clé est disponible si une clé est
Tu as raison. Cela semble être la meilleure solution (et la plus simple). Merci!
Solution idéale Dans de nombreux cas, veillez à mettre un mécanisme en place pour éviter une boucle excessivement longue.
Vous devez renvoyer le résultat de l'auto-appel, sinon la clé valide ne sera pas retournée une fois qu'elle est recuches.
Bon point =) Je ne le recommanderais pas à utiliser la récursion dans ce cas cependant.
Si vous incluez assez unicité em> dans votre routine de génération de clé, vous pourrez peut-être éviter cette situation en premier lieu. Par exemple. Demandez à la routine de prendre en compte l'horodatage actuel et le nom d'hôte local et / ou PID. La boucle de manière aussi non déterministe est généralement la preuve d'une certaine partie étant trop naïve. Ce n'est pas bon. : -) p> Quoi qu'il en soit, il serait au moins une bonne pratique de l'attraper et de loger une sorte d'erreur par opposition à la suspension de la demande et de chronométrer finalement: P>
function key_generator($length = 4)
{
/* The $attempts_left clearly depends on how much trust
you give your key generation code combined with the key space size. */
$attempts_left = pow(16, $length) * 2;
/* ... just guessing, in case your key base is 16, i.e. [0-9a-z] for example */
do {
// ... key generation goes here ...
$key = 'xxxx';
} while ( $this->user_model->valid_key($key) == false && $attempts_left-- > 0 );
if( $attempts_left < 1 )
return false;
else
return $key;
}
Pourquoi ne pas simplement numériser l'espace de la valeur clé pour la première clé inutilisée? Besoin de la clé pour remplir des contraintes supplémentaires au-dessus d'être de quatre caractères longs et uniques? P>
Vous pouvez vous souvenir de la dernière clé retournée pour reprendre la numérisation à partir de là sur des appels ultérieurs. P>
Si vous voulez des appels ultérieurs pour ne pas renvoyer des clés similaires, vous pouvez d'abord mélanger votre base de données de clé. Cela signifierait que vous devez contenir un ensemble d'éléments 456976, 1679616, 7311616 ou 14776336 quelque part (selon que l'alphabet utilisé soit des caractères à double enveloppe, avec ou sans chiffres). P>
Utiliser une fonction à l'intérieur de lui-même
En outre, $ Celui-ci n'est pas exclusif au codédiciteur.
Je pense qu'il vient d'expliquer là où cela venait dedans et pourquoi il n'est pas défini dans l'extrait de code.
$ Celui-ci est utilisé pour la portée de l'objet / de la classe. Tant que votre fonction est au sein d'une classe et c'est là que vous l'appelez, vous devez utiliser $ ceci-> MODENAME () ..) Nom de fonctionnement () s'il s'agit d'une fonction statique. etc