Bonjour à tous,

Voilà j'ai créé un système d'option pour mon site et j'aimerais créer une fonction qui générerait les déclinaisons automatiquement.
Un petit exemple pour mieux comprendre :
Option Taille : XL, XXL
Option Couleur : Noir, Blanc
Option Composition : Coton
Et je voudrais faire les déclinaisons suivantes :
XL - Noir - Coton
XL - Blanc - Coton
XXL - Noir - Coton
XXL - Blanc - Coton
et ainsi de suite en fonction des options sélectionnées
Mes options sont stockées dans une base de données et je les récupère via un tableau bien entendu.
Ce que j'aimerais savoir c'est si dans php il y a une fonction qui me permette d'associé directement les valeurs que je récupère de mon tableau.

Merci à vous et très bonne fin d'année

21 réponses


Salut,

Sans un peu de code ni la structure de ton tableau de résultats, on va avoir du mal à t'aider :/
Tu veux générer, avec ton tableau, toutes les combinaisons possible c'est ça ?

Bonjour betaWeb,
Oui en fait c'est tout à fait sa.

Cf première partie de ma réponse.

En fait le but c'est de pouvoir mettre une quantité et une référence sur chaque déclinaison, pour l'instant je fais cette manipulation manuellement via des menus déroulants pour chaque déclinaison.
Je me suis donc dit qu'il serais plus simple de générer ces déclinaisons automatiquement, mais pour l'instant je ne vois pas pour ou commencer, j'ai regarder array_merge et array_combine mais ca donne rien.

EDIT : je vais refaire mon bout de code sa sera plus simple ;)

Salut,
Sans voir ton code c'est effectivement compliqué de t'aiguiller, mais il te suffit d'encapsuler le parcours de chaque option dans le parcours d'un autre afin de générer chaque possibilité.

Oui, un parcours récursif de ton tableau me paraît être la meilleure des solutions. Bon courage.

Merci pour votre aide, je suis en train de regarder les fonctions recursive de php. Je reviens vers vous quand mon code sera un peu plus avancé.

Ca marche, n'hésite pas à poster un peu de ton code pour que l'on puisse d'aider ;)

Bonjour,
je suppose que tu récupères les options séparément depuis la bd
tu te retrouves avec N tableaux d'options que tu dois combiner.
tu voudrais une fonction à laquelle on passe les N tableaux (N pouvant varier tant qu'à faire)
tu pourrais utiliser les varargs comme ceci (operateur ...)

function decline ( ...$options) {
    $result = array();
    foreach($options[0] as $option0) {
        if (isset($options[1])) {
            foreach($options[1] as $option1) {
                if (isset($options[2])) {
                    foreach($options[2] as $option2) {
                        if (isset($options[3])) {
                            foreach($options[3] as $option3) {
                                if (isset($options[4])) {
                                    foreach($options[4] as $option4) {
                                        $result[] = $option0 . ' - ' . $option1 . ' - ' . $option2 . ' - ' . $option3 . ' - ' . $option4;
                                    }
                                } else {
                                    $result[] = $option0 . ' - ' . $option1 . ' - ' . $option2 . ' - ' . $option3;
                                }
                            }
                        } else {
                            $result[] = $option0 . ' - ' . $option1 . ' - ' . $option2;
                        }                               
                    }
                } else {
                    $result[] = $option0 . ' - ' . $option1 ;
                }                               
            }               
        } else {
            $result[] = $option0 ;
        }                               
    }
    return $result;
}   

 }

 // appel de la fonction avec 3 tableaux d'options
$couleurs = ['rouge','vert','orange','fushia'];
$tailles = ['S', 'M', 'L', 'XL', 'XXL'];
$matieres = ['coton','lycra','laine','polyamide','tergal'];

 $declinaisons = decline( $tailles, $couleurs, $matieres);  // renvoie un tableau

J'ai limité le nombre d'options à 5 dans la fonction, ce qui devrait suffire

Suis-je sur la bonne piste ?

Bon j'ai réussi à faire ma fonction.
Bonjour, Huggy, alors oui c'est la bonne piste, mais au lieu de limiter les options ou enchaîner les foreach j'ai utilisé la récursion. Mais un grand merci pour le temps que tu m'as accordé. Je laisse la fonction ça pourra peut-être aider ou si certain vois quelque chose de plus propre ou plus optimisé je suis preneur.

    $option[0][1] = 'XL';
    $option[0][2] = 'XXL';
    $option[1][1] = 'Blanc';
    $option[1][2] = 'Noir';
    $option[2][1] = 'Coton';

    function generateDeclination($option, $i, $string = false) {
        foreach ($option[$i] as $value) :
            if (isset($option[$i+1])) {
                generateDeclination($option, $i + 1, $string . ' ' . $value);
            } else {
                echo $string . ' ' . $value . '<br />';
            }
        endforeach;
    }

    generateDeclination($option, 0);

le résultat
XL Blanc Coton
XL Noir Coton
XXL Blanc Coton
XXL Noir Coton

Voilà il me reste plus qu'a faire ma requête pour remplacer les $option[0][1] = 'XL'.......
Un grand merci à vous tous pour vos conseils qui mon permis de débloquer mes neurones, car avant d'arriver sur le forum j'étais dans le brouillard total et pour une fonction pas si compliqué en fait.

Petite question hors sujet, comment fait-on pour mettre le sujet sur résolu.

Tu ne devrais pas faire d'echo dans ta fonction, il faut séparer la présentation des données
essaye de retourner un tableau

function decline_recurs($options, $i, $string): array {
    $result = array();

    if (isset($options[$i])) {
        foreach($options[$i] as $option) {
            if ($string == '') {
                $chaine =  $option;
            } else {
                $chaine = $string . ' - ' . $option;
            }
            $result = array_merge($result, decline_recurs( $options, $i+1,  $chaine ));

        }
        return $result;
    } else {
        return array($string);
    }   
}

$couleurs = ['rouge','vert','orange','fushia'];
$tailles = ['S', 'M', 'L', 'XL', 'XXL'];
$matieres = ['coton','lycra','laine','polyamide','tegal'];

$options[0] = $tailles;
$options[1] = $couleurs;
$options[2] = $matieres;

$declinaisons = decline_recurs($options, 0, "");

foreach ($declinaisons as $declinaison) {
    echo $declinaison . '<br />';
}

Merci Huggy, pourrais-je abuser un peu et te demander de m’expliquer à quoi sert le array situé au début de la fonction ( function decline_recurs($options, $i, $string): array { )

Ce n'est ni plus ni moins que ta fonction generateDeclinaison qui a réécrite.

Oui sa j'ai bien compris :-) mais il y a un array ajouter au début
function decline_recurs($options, $i, $string): array {
et je ne sais pas à quoi sa sert donc je voudrais savoir si cela indique que la function est un tableau ou autre peut-être

le : array c'est du php7, ça indique que la fonction retourne un array
bien sûr on peut le supprimer en php5

Ok, je savais pas que l'on pouvait indiquer le type de retour ou d'argument de la fonction.
Une fois encore merci

Il y a plus simple.

function decline(array $options = [])
{
    return array_map(function ($item) use ($options) {
        $temp = $item;

        $temp .= ', ';
        $temp .= implode(' ', array_map('ucfirst', $options['matieres']));

        $temp .= ', ';
        $temp .= implode(' ', array_map('ucfirst', $options['couleurs']));

        return $temp;
    }, $options['tailles']);
}

$postOptions = [ // exemples de $_POST['...']
        'tailles' => ['S', 'M', 'L', 'XL', 'XXL'],
        'matieres' => ['coton', 'lycra', 'laine', 'polyamide', 'tegal'],
        'couleurs' => ['rouge', 'vert', 'orange', 'fushia'],
];
print_r(decline($postOptions));

Qui donne un résultat comme suit:

Array
(
    [0] => S, Coton Lycra Laine Polyamide Tegal, Rouge Vert Orange Fushia
    [1] => M, Coton Lycra Laine Polyamide Tegal, Rouge Vert Orange Fushia
    [2] => L, Coton Lycra Laine Polyamide Tegal, Rouge Vert Orange Fushia
    [3] => XL, Coton Lycra Laine Polyamide Tegal, Rouge Vert Orange Fushia
    [4] => XXL, Coton Lycra Laine Polyamide Tegal, Rouge Vert Orange Fushia
)

Bonjour PhiSyX
En effet sa donne bien ce résultat, mais ce n'est pas ce qu'il me faut, moi je veux par exemple pour S
[0] => S, Coton , Rouge
[1] => S, Coton, Vert
[2] => S, Coton, Orange
[3] => S, Lycra, Rouge
[4] => S, Lycra, Vert
[5] => S, Lycra, Orange
.......

Bon maintenant que tout fonctionne bien, je complique un peu les choses.
Pour insérer mes déclinaisons dans ma base de données je fais appel à une requête ajax qui me lance la fonction d'insertion, jusque-là tout va bien. Mais si je rajoute une nouvelle couleur par exemple, je voudrais qu'il insère seulement les nouvelles combinaisons, car pour l'instant il me réinsère toute la liste. J'ai essayé avec is_array mais ça ne fonctionne pas ou peut-être array_diff.
Je laisse mon code qui permet d'insérer

EDIT : j'edit le message car j'y suis arrivé avec un array_diff

Ha oui d'accord, effectivement ça change tout. :-)