Gerando dezenas para jogos em PHP

É no trecho $stmt->execute($jogo); - no caso, os valores do array $jogo são colocados no lugar dos ?, na ordem em que aparecem (o primeiro elemento vai no lugar do primeiro ?, e assim por diante).

No segundo código (o que usa mysqli), é no $stmt->bind_param('iiiiii', ...$jogo); - cada i indica que é um valor numérico, e ...$jogo diz para usar os valores do array (novamente, as substituições são feitas na ordem).

Cara, assim, dei uma estudada e fiz as alterações que achei necessárias, o programa tá funcionando até certo ponto. Está gerando as combinações conforme o que se coloca nos campos do formulário, mas o SELECT no BD parece estar dando algo de errado. Coloquei os bindParam para substituir os pontos de interrogação, preparei a query e executei, tudo conforme o manual, eu acho rsrsrs, mas ai, ta executando mas dando o seguinte erro:
Warning : PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\xampp\htdocs\Mega\sorteia2.php on line 5

Warning : PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\xampp\htdocs\Mega\sorteia2.php on line 5

Traduzindo: numero de parametros invalidos. Parametro nao definido na linha 5.

Vou colocar aqui o código completo, por favor da uma olhada e ve se compreende o que está errado

<?php
// verifica se o jogo já existe no banco
function ja_existe($jogo, $stmt) {
    $stmt->execute($jogo);
    return $stmt->fetchColumn() > 0;
}

$Servidor = "localhost";
$Banco = "megasena";
$Usuario = "root";
$Senha = "";

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $Numjogos = $_POST["jogos"];
    $Qtydezenas = $_POST["dezenas"];
    $Valormin = $_POST["de"];
    $Valormax = $_POST["ate"];
    $jogos = [];
    $numeros = array_map(function($n) { return sprintf("%02d", $n); }, range($Valormin, $Valormax));

    $Conn = new PDO("mysql:host=$Servidor;dbname=$Banco", $Usuario, $Senha);
    $stmt = $Conn->prepare('SELECT count(*) FROM sorteio WHERE Dez1= :d1 AND Dez2= :d2 AND Dez3= :d3 AND Dez4= :d4 AND Dez5= :d5 AND Dez6= :d6');
    $stmt->bindParam(":d1", $dez1);
    $stmt->bindParam(":d2", $dez2);
    $stmt->bindParam(":d3", $dez3);
    $stmt->bindParam(":d4", $dez4);
    $stmt->bindParam(":d5", $dez5);
    $stmt->bindParam(":d6", $dez6);
    $stmt->execute();
    
    $dezenas = $stmt->fetchAll();

    for ($i = 1; $i <= $Numjogos; $i++) {
        while (true) {
            shuffle($numeros);
            $sorteio = array_slice($numeros, 0, $Qtydezenas);
            sort($sorteio);
            // se não é jogo repetido, adiciona
            if (!ja_existe($sorteio, $stmt)) {
                $jogos[] = $sorteio;
                
                break;
            }else{
                echo "Esses jogos já existem: " .implode(', ', $jogo). "<br>\n";
            }
          
        }
    }
}

?>

<form method="POST"> 

Numero de Jogos: <input type="text" size="10" name="jogos"> <br>
 
Quantidade de Dezenas em cada jogo: <input type="text" size="10" name="dezenas"> <br>
 
Iniciando em: <input type="text" size="5" name="de"> indo até:<input type="text" size="5" name="ate"> <br><br><br>
<input type="submit" name="BTEnvia" value="Enviar">  <input type="reset" name="BTApaga" value="Apagar">
       
<?php

?>
    
</body>
</html>
<br><br><br><br>
<?php


foreach ($jogos as $jogo) {
    // aqui vc pode imprimir os jogos, inserir no banco, etc
    echo "Os Jogos são: " .implode(', ', $jogo). "<br>\n";
}


?>

Testa ai. Ta gerando tudo direitinho, só na hora de executar a função [ ja_existe($jogo, $stmt) ] que tá dando erro

Amigo, eu acho que nós temos um problema de lógica neste código, digo porque,
conforme está o código o programa está: 1 - gerando os numeros aleatorios (entre o minimo e maximo indicados);
2 - criando a conexão com o banco e fazendo o SELECT através de parametros (? com MySqli ou :dez1 com PDO) e (bind_Param com MySqli ou bindParam com PDO);
3 - executa o For que faz o seguinte:
1 - embaralha com o shuffle
2 - escolhe a quantidade de dezenas indicada com o array_slice
3 - e então ordena.
4- Aqui ele faz um IF para verificar se os numeros ordenados existem ou nao no resultado do SELECT que foi feito.
e por ultimo se nao existir, joga na array $jogos.
5 - $jogos[] = $sorteio;

Pois bem, quando o sistema faz if (!ja_existe($sorteio, $stmt)), ele verifica se os 6 numeros retirados do montande que foi gerado, embaralhado e ordenado, existem na variavel $stmt, que deveria receber o resultado do SELECT, que por sua vez precisa desses mesmos numeros para ser realizada. {os parametros indicados atraves do binParam (dez1, dez2, dez3 etc) ainda nem existem, portanto a variavel $stmt vai estar sempre vazia pois o SELECT vai sempre retornar 0.

Concorda ???

Entao, acho que é essa questao que tem que ser resolvida. Os numeros devem ser gerados, embaralhados, escolhidos os 6 e ordenados, só depois deve ser feito SELECT, pois ai a variavel $stmt já teria um resultado valido para ser comparado quando a função ja_existe($jogo, $stmt) fosse executada,
concorda ?

Por que vc executa o select aqui? De onde vieram essas variáveis $dez1, $dez2, etc? Elas não foram criadas em nenhum lugar, isso aqui não vai funcionar. E nem faz sentido executar a query neste ponto.

Esses são os parametros da busca. Lembra que perguntei sobre os pontos de interrogação que tem na clausula WHERE ? Pois é, eles são substituidos pelos valores desses parametros (dez1, dez2 etc.)
Mas veja bem, no código a função function ja_existe($jogo, $stmt) { está sendo executada após o select e precisa do resultado da query para comparar, e a query por sua vez não vai encontrar os valores porque pra isso depende dos numeros aleatorios que ainda nem foram gerados. Conclusão, o problema agora é esse, o SELECT para trazer os resultados corretos precisa dos 6 numeros gerados e a função precisa do resultado do $stmt.
Pergunto: essa query poderia (ou deveria ) ser executada dentro de um desses laços ? Sera se deveria ser após o sort($sorteio) ?
Só sei que para quem ta começando tá dificil viu

Dá uma olhada nesse teste que eu fiz :point_down: :point_down: :point_down:

<?php
// verifica se o jogo já existe no banco
function ja_existe($jogo, $stmt) {
    $stmt->execute($jogo);
    return $stmt->fetchColumn() > 0;
}

$Servidor = "localhost";
$Banco = "megasena";
$Usuario = "root";
$Senha = "";

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $Numjogos = $_POST["jogos"];
    $Qtydezenas = $_POST["dezenas"];
    $Valormin = $_POST["de"];
    $Valormax = $_POST["ate"];
    $jogos = [];
    $numeros = array_map(function($n) { return sprintf("%02d", $n); }, range($Valormin, $Valormax));
}

   // $dez1 = 9;
  //  $dez2 = 37;
  //  $dez3 = 39;
   /// $dez4 = 41;
  //  $dez5 = 43;
  //  $dez6 = 48;

    $Conn = new PDO("mysql:host=$Servidor;dbname=$Banco", $Usuario, $Senha);
   // $stmt = $Conn->prepare('SELECT * FROM sorteio WHERE Dez1= :d1 AND Dez2= :d2 AND Dez3= :d3 AND Dez4= :d4 AND Dez5= :d5 AND Dez6= :d6');
  //  $stmt->bindParam(":d1", $dez1);
  //  $stmt->bindParam(":d2", $dez2);
  //  $stmt->bindParam(":d3", $dez3);
  //  $stmt->bindParam(":d4", $dez4);
  //  $stmt->bindParam(":d5", $dez5);
  //  $stmt->bindParam(":d6", $dez6);
  //  $stmt->execute();
    
  //  $dezenas = $stmt->fetch();

  //  print_r($dezenas);

    for ($i = 1; $i <= $Numjogos; $i++) {
        while (true) {
            shuffle($numeros);
            $sorteio = array_slice($numeros, 0, $Qtydezenas);
            sort($sorteio);
            $stmt = $Conn->prepare('SELECT * FROM sorteio WHERE Dez1= :d1 AND Dez2= :d2 AND Dez3= :d3 AND Dez4= :d4 AND Dez5= :d5 AND Dez6= :d6');
            $stmt->bindParam(":d1", $dez1);
            $stmt->bindParam(":d2", $dez2);
            $stmt->bindParam(":d3", $dez3);
            $stmt->bindParam(":d4", $dez4);
            $stmt->bindParam(":d5", $dez5);
            $stmt->bindParam(":d6", $dez6);
            $stmt->execute();
            $dezenas = $stmt->fetch();
            
            ?>
            <br> <br>
            <?php 
            var_dump($dezenas);
            ?>
        <br> <br>
            <?php
           //  print_r($dezenas);
            // se não é jogo repetido, adiciona
           // if //(!ja_existe($sorteio, $stmt))// {
                $jogos[] = $sorteio;
                
                break;
          //  }//else{
              //  echo "Esses jogos já existem: " .implode(', ', $jogo). "<br>\n";
          //  }
          
        }
    
        var_dump($jogos);

        ?>

        <br> <br>
        <br> <br>

        <?php

foreach ($jogos as $jogo) {
    // aqui vc pode imprimir os jogos, inserir no banco, etc
    "<br>\n" ;"<br>\n";
    echo "Os Jogos são: " .implode(', ', $jogo). "<br>\n";
}

}
?>
  
<form method="POST"> 

Numero de Jogos: <input type="text" size="10" name="jogos"> <br>
 
Quantidade de Dezenas em cada jogo: <input type="text" size="10" name="dezenas"> <br>
 
Iniciando em: <input type="text" size="5" name="de"> indo até:<input type="text" size="5" name="ate"> <br><br><br>
<input type="submit" name="BTEnvia" value="Enviar">  <input type="reset" name="BTApaga" value="Apagar">
       
<?php

?>
    
</body>
</html>
<br><br><br><br>

Eu acho que O SELECT está funcionando direitinho agora. Mas a função não

Bem… testei o código como voce me enviou e nao funcionou de jeito nenhum. Sempre dá erro na execução da função, exatamente porque quando voce coloca na query WHERE dez1= ?, esse parametro precisa ser preenchido com um valor, correto ? Ocorre que o vai ser adicionado atraves do bindParam. E nao está sendo. Então a função compara os valores armazenados com a array $sorteio com o $tmt vazio. E ele está vazio exatamente porque os valores não foram repassados ainda.
Eu peguei o código exatamente como voce me enviou e não funcionou. Ele gera as dezenas, fato, mas não está fazendo a comparação com o que há no banco. Por isso acredito que deve ser por isso.
Eu fiz uns testes e modifiquei a ordem, coloquei o SELECT dentro do FOR logo depois que os numeros são gerados e ordenados, tirei o IF e dei um va var_dump na variavel que recebe os valores do $stmt e tambem na array $jogos. Está fazendo tudo direito, porem, quando deixo no IF a instrução que executa a função ja_existe(), dá erro na linha 5 ($stmt->execute($jogo):wink:

Pra mim que sou iniciante tá complicado de resolver…confesso

Uma última tentativa (pois não dá pra adivinhar o problema, já que vc só diz que não funcionou, mas não diz exatamente qual foi o erro, etc).

Bom, vc pode tentar fazer o bind um por um, mas use os loops a seu favor:

function ja_existe($jogo, $stmt) {
    // faz o bind dos parâmetros um a um
    // poderia usar count($jogo), mas como eu sei que sempre serão 6, deixei assim mesmo
    for ($i = 0; $i < 6; $i++) {
        $stmt->bindParam(":d". ($i + 1), $jogo[$i]);
    }
    $stmt->execute();
    $dezenas = $stmt->fetch(PDO::FETCH_ASSOC);
    return $dezenas['quantidade'] > 0;
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $Numjogos = $_POST["jogos"];
    $Qtydezenas = $_POST["dezenas"];
    $Valormin = $_POST["de"];
    $Valormax = $_POST["ate"];
    $jogos = [];
    $numeros = array_map(function($n) { return sprintf("%02d", $n); }, range($Valormin, $Valormax));

    $Conn = new PDO("mysql:host=etc");
    $stmt = $Conn->prepare('select count(*) as quantidade from sorteio where Dez_1=:d1 AND Dez_2=:d2 AND Dez_3=:d3 AND Dez_4=:d4 AND Dez_5=:d5 AND Dez_6=:d6');
    for ($i = 1; $i <= $Numjogos; $i++) {
        while (true) {
            shuffle($numeros);
            $sorteio = array_slice($numeros, $j++, $Qtydezenas);
            sort($sorteio);
            // se não é jogo repetido, adiciona
            if (! ja_existe($sorteio, $stmt)) {
                $jogos[] = $sorteio;
                break;
            }
        }
    }

    foreach ($jogos as $jogo) {
        // insere o jogo
        $insert = $Conn->prepare('insert into sorteio(dez_1, dez_2, dez_3, dez_4, dez_5, dez_6) values (:d1, :d2, :d3, :d4, :d5, :d6)');
        for ($i = 0; $i < 6; $i++) { 
            $insert->bindParam(":d". ($i + 1), $jogo[$i]);
        }
        $insert->execute();
        echo "inserido no banco: ". implode(', ', $jogo). "<br>\n";
    }
}

Não amigo, voce nao entendeu. Como expliquei, o programa está funcionando até aqui:

for ($i = 1; $i <= $Numjogos; $i++) {
        while (true) {
            // embaralho os numeros gerados
            shuffle($numeros);
         
            // retiro a quantidade de dezenas indicada no campo numero de jogos
           $sorteio = array_slice($numeros, 0, $Qtydezenas);
          //$sorteio = [10, 11, 29, 30, 36, 47];
 // aqui eu ordeno as dezenas escolhidas
           // sort($sorteio);
            // e então faço a busca no BD
            $stmt = $Conn->prepare('SELECT * FROM sorteio WHERE Dez1 = :d1 AND Dez2= :d2 AND Dez3= :d3 AND Dez4= :d4 AND Dez5= :d5 AND Dez6= :d6');
            $stmt->bindValue(":d1", $sorteio[0]);
            $stmt->bindValue(":d2", $sorteio[1]);
            $stmt->bindValue(":d3", $sorteio[2]);
            $stmt->bindValue(":d4", $sorteio[3]);
            $stmt->bindValue(":d5", $sorteio[4]);
            $stmt->bindValue(":d6", $sorteio[5]);
            $stmt->execute();
            $dezenas = $stmt->fetch();
 //  exit;
           
            ?> <br> <br>
            <?php

           

Toda essa parte está funcionando, ele gera as combinações, o Select no banco está sendo feito, o problema ocorre aaqui:

 

            if (!ja_existe($jogos, $stmt)) {
                $jogos[] = $sorteio;
                echo "<pre>";
                print_r($jogos);
               // exit;
   // echo "Esse jogo nao existe: " .implode(', ', $sorteio). "<br>\n";
   break;
            }else{
                echo "Esse jogo já existe: " .implode(', ', $sorteio). "<br>\n";
      
            }
          
        }

A função que voce criou é que está dando erro. Eu falei isso la em cima. Até coloquei a mensagem.

Vc testou com o código que coloquei acima? Porque não estão iguais.

Repare na diferença: o meu faz os binds e execute dentro da função, o seu faz fora (antes do if (! ja_existe). Se vc já faz o execute antes, não tem porque chamar a função pra fazer tudo de novo.

Ou faz um, ou outro. Se vai fazer tudo fora da função, não precisa mais dela. Bastaria trocar o if para verificar se $dezenas retornou alguma coisa.

Está funcionando perfeitamente agora. Muito obrigado mesmo. Na verdade, muita coizinha que carece do maximo de atenção. Desculpa o stress. Seu código está perfeito
Abraço