Gerando dezenas para jogos em PHP

33 respostas
php
J

Galera, estou tentando criar um programinha em PHP que gere numeros para jogos de loteria como Mega Sena, Quina etc. Criei o seguinte código:

<?php
$Servidor = "localhost";
$Banco = "megasena";
$Usuario = "root";
$Senha = "";

if($_POST)
$Numjogos = $_POST["jogos"];
$Qtydezenas = $_POST["dezenas"];
$Valormin = $_POST["de"];
$Valormax = $_POST["ate"];
$tmp=[];
$arr = [];

//* for que gera combinações conforme escolhido no campo NumerodeJogos
  
                for($j=0; $j<$Numjogos;$j++){
                  
               echo "Combinação #" . ($j+1) . "{";
        
   //  for que gera os quantas dezenas conforme campo Quantidade //
     
                             for($k=0; $k<$Qtydezenas; $k++){
               
     //* o while se repete enquanto o numero gerado for repetido//
        
                             while(true){
            
            //gera numero aleatorio entre Valormin e Valormax digitados nos campos
         
                   $tmp = str_pad(rand($Valormin, $Valormax), 2, '0',STR_PAD_LEFT);
                         // verificar se a sequencia gerada ja existe no array $arr
                                   if (!array_search(($tmp), $arr)) { 
            	                       array_push($arr, ($tmp));
                         //sai do laço
                break;
            }
        }
        //exibe o numero gerado
      // echo " Dezena :" .is_array($tmp);
  
       var_dump($tmp);
            
    }
  
}    

try{

    $Conn = new PDO("mysql:host=$Servidor;dbname=$Banco", $Usuario, $Senha);
    $sql = "SELECT * FROM sorteio";
    $stmt = $Conn->query($sql);
    $resultado = $stmt->fetchAll();
   // echo "<pre>";
  //  print_r($resultado);

}catch(PDOException $erro){
    echo "Não foi possível conectar ao Banco de Dados: " . $erro->GetMessage();
}
?>

<html lang="en">
<head>
   <title>teste</title>
</head>
<body>

<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>

Bem, quando executo e dou um var_dump na variavel $tmp vejo que o programa gerou as cobinações certinho, conforme escolhido nos campos do formulário. Mas quando dou um eco na mesma variavel, o resultado não vem correto. Aparece sempre Dezena :string(2) repetido antes do que o var_dump ta imprimindo.
Eu que gostaria que cada combinação gerada fosse mostrada em uma linha abaixo da outra.
Outra coisa que eu gostaria de implementar é o seguinte: primeiro ordenar as dezenas geradas da menor para maior. Depois jogar no banco de dados que criei com os campos: Dez1, Dez2, Dez3, Dez4, Dez5 e Dez6, mas só poderia armazenar se a sequencia ainda nao existisse.
Alguem poderia me ajudar ??

33 Respostas

H

Depende, como vc guarda esses valores no banco? É um campo varchar contendo as dezenas, tipo 1,5,10,25,43,51? Ou tem uma coluna para cada dezena?

Enfim, vou assumir que é o primeiro caso, mas aí se não for, vc adapta.

Para gerar números aleatórios sem repetição, eu já respondi aqui. Não precisa fazer um loop e toda hora verificar se o número já existe. Basta criar um array contendo todos os números, embaralhá-lo e pegar os 6 primeiros.

Só precisa de um loop para ficar gerando um novo jogo até que ele não esteja no array de jogos. Ficaria assim:

$Numjogos = $_POST["jogos"];
$Qtydezenas = $_POST["dezenas"];
$Valormin = $_POST["de"];
$Valormax = $_POST["ate"];
$jogos = [];

// array contendo todos os números, formatados com o zero à esquerda
$numeros = array_map(function($n) { return sprintf("%02d", $n); }, range($Valormin, $Valormax));

for($i = 1; $i <= $Numjogos; $i++) {
    echo "Combinação #$i: ";
    while (true) {
        // embaralha
        shuffle($numeros);
        // pega os 6 primeiros e ordena
        $sorteio = array_slice($numeros, 0, $Qtydezenas);
        sort($sorteio);
        // se não é jogo repetido, adiciona
        if (! in_array($sorteio, $jogos)) {
            $jogos[] = $sorteio;
            echo implode(', ', $sorteio). "\n";
            break;
        }
    }
}

// para verificar no banco, converta cada jogo para o formato usado
// abaixo estou assumindo que os valores ficam em uma única string, separados por vírgula (ex: "02,08,12,45,47,55")
foreach ($jogos as $jogo) {
    $formato_para_salvar_no_banco = implode(',', $jogo);
    // verifica se já existe, salva no banco, etc
}
J

Perdoe-me a ignorância mas ainda fiquei confuso.
Ponto 1 - Meu banco de dados tem a tabela sorteio que tem os seguintes campos:
Cod_jogo (corresponde ao numero de cada sorteio e é auto incremento), Dez_1, Dez_2, Dez_3, Dez_4, Dez_5 e Dez_6. Assim sendo eu gostaria de, após serem geradas as dezenas, embaralhadas e escolhidas as 6, que verificasse no Banco de dados se aquela sequencia em especifico ja existe. Se existisse, o sistema geraria e salvaria. Depois disso imprimiria todas as combinações geradas na tela.
Mas essa parte com banco eu realmente nao sei fazer. Nem mesmo em que parte do código encaixa-la.

H

As colunas Dez_1, Dez_2, Dez_3, Dez_4, Dez_5 e Dez_6 estão ordenadas? Por exemplo, se os números forem 10, 12, 23, 34, 40 e 56, é garantido que Dez_1=10, Dez_2=12, Dez_3=23, Dez_4=34, Dez_5=40 e Dez_6=56?

Se for, basta fazer queries no banco verificando se já existe, e só inserir um novo caso não exista. Não uso PDO com frequência, mas seria algo assim:

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

$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 = // criar conexão
$stmt = $Conn->prepare('select count(*) from NomeDaTabela where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?');
for ($i = 1; $i <= $Numjogos; $i++) {
    while (true) {
        // embaralha
        shuffle($numeros);
        // pega os 6 primeiros e ordena
        $sorteio = array_slice($numeros, 0, $Qtydezenas);
        sort($sorteio);
        // se não é jogo repetido, adiciona
        if (! ja_existe($sorteio, $Conn)) {
            $jogos[] = $sorteio;
            break;
        }
    }
}
J

Não. Nao estao ordenadas. Como existe o recurso de ordenar ainda enquanto array, sugerido por voce, pensei nao ser necessário

H

Aí complica, né. Eu sugiro que tente atualizar para deixá-las ordenadas, pois aí fica mais fácil verificar se um jogo já existe.

Claro que também dá para fazer um select que traz as colunas, aí vc coloca-as em um array e ordena, e depois compara com o que foi gerado, mas é mais trabalhoso (o ideal seria deixar ordenado no banco, pois aí dá pra fazer somente com count como eu fiz acima).

J

Vou tentar. Muito obrigado
obs: se não conseguir te falo
Valeu

J

Nessa função que voce criou voce declara dois parametros:

um deles é $jogo, correto ? Só não entendi bem o que jogo está recebendo e de onde, pois não o vi em outra parte do código.

H

Ops, o código deveria ser:

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

$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 = // criar conexão
$stmt = $Conn->prepare('select count(*) from NomeDaTabela where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?');
for ($i = 1; $i <= $Numjogos; $i++) {
    while (true) {
        // embaralha
        shuffle($numeros);
        // pega os 6 primeiros e ordena
        $sorteio = array_slice($numeros, 0, $Qtydezenas);
        sort($sorteio);
        // se não é jogo repetido, adiciona
        if (! ja_existe($sorteio, $Conn)) {
            $jogos[] = $sorteio;
            break;
        }
    }
}

Antes estava if (! ja_existe($jogo, $Conn)) {, corrigi para if (! ja_existe($sorteio, $Conn)) { - já corrigi acima também

J

Cara, vou precisar de sua ajuda. Poderia me passar um email ou whatsapp. Nem sei se isso é normal mas nao estou conseguindo

J

Coloquei o código completo e coloquei a parte da conexão que faltava. Quando atualizei a pagina recebi o seguinte erro:

Notice : Undefined index: jogos in C:\xampp\htdocs\Mega\sorteia.php on line 13

Notice : Undefined index: dezenas in C:\xampp\htdocs\Mega\sorteia.php on line 14

Notice : Undefined index: de in C:\xampp\htdocs\Mega\sorteia.php on line 15

Notice : Undefined index: ate in C:\xampp\htdocs\Mega\sorteia.php on line 16

Veja o meu código inteiro,

<?php

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

function ja_existe($jogo, $stmt) {
    $stmt->execute($jogo);
    return $stmt->fetchColumn() > 0;
}

$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));

try{

    $Conn = new PDO("mysql:host=$Servidor;dbname=$Banco", $Usuario, $Senha);
    $sql = "SELECT * FROM sorteio";
    $statmt = $Conn->query($sql);
    $resultado = $statmt->fetchAll();
   // echo "<pre>";
  //  print_r($resultado);


}catch(PDOException $erro){
    echo "Não foi possível conectar ao Banco de Dados: " . $erro->GetMessage();

}


$stmt = $Conn->prepare('select count(*) from sorteio where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?');
for ($i = 1; $i <= $Numjogos; $i++) {
    while (true) {
        // embaralha
        shuffle($numeros);
        // pega os 6 primeiros e ordena
        $sorteio = array_slice($numeros, 0, $Qtydezenas);
        sort($sorteio);
        // se não é jogo repetido, adiciona
        if (! ja_existe($sorteio, $Conn)) {
            $jogos[] = $sorteio;
            break;
        }
    }
}

   

    ?>

<html lang="en">
<head>
<title>Sorteia</title>
</head>
<body>

<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">

</body>
</html>
H

Na verdade acho que deveria ser if (! ja_existe($sorteio, $stmt)) - vc passa a prepared query, e não a conexão.

Mas como eu já disse antes, isso só funcionaria se as dezenas estivessem ordenadas no banco. Se não estiverem, aí fica mais complicado: precisaria consultar todos os jogos, e para cada um criar um array com as dezenas, ordenar e comparar com o $sorteio criado.

J

É como se ele não tivesse reconhecendo os campos do formulario. Não entendi

H

Na primeira vez que carrega a página, não vai ter nada preenchido, então não vai ter os campos.

Deveria ter algo como:

if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
    // código que gera os jogos
}
J
Coloquei o IF para verificar se havia ou não algo nos campos.

IF($_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));

Depois tentei preenchendo os campos e pressionei enviar e recebi o seguinte erro:

Fatal error : Uncaught Error: Call to undefined method PDO::execute() in C:\xampp\htdocs\Mega\sorteia.php:17 Stack trace: #0 C:\xampp\htdocs\Mega\sorteia.php(48): ja_existe(Array, Object(PDO)) #1 {main} thrown in C:\xampp\htdocs\Mega\sorteia.php on line 17

J
16   function ja_existe($jogo, $stmt) {

17    $stmt->execute($jogo);    ------   >   Ta dando erro aqui

18    return $stmt->fetchColumn() > 0;

}
H

Fiz um teste rápido aqui e funcionou:

// verifica se o jogo já existe no banco
function ja_existe($jogo, $stmt) {
    $stmt->execute($jogo);
    return $stmt->fetchColumn() > 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(*) from sorteio where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?');
    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;
            }
        }
    }

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

Mas como eu já disse, só vai funcionar se as colunas Dez_1, Dez_2, etc estiverem ordenadas. Porque eu comparo o primeiro elemento do array $sorteio com a coluna Dez_1, o segundo elemento com Dez_2 e assim por diante (por isso que eu ordeno o array).

Mas se as colunas não estiverem ordenadas no banco, aí tem que mudar a estratégia: precisaria fazer um SELECT de todos os jogos, e para cada um, jogar as colunas em um array, ordená-lo e comparar com $sorteio. Bem mais demorado e trabalhoso.


Agora, mudando de assunto, se vc está usando MySQL, pra que usar PDO?

Existe esse “mito da troca do banco de dados” (que é uma das justificativas mais comuns para escolherem PDO), mas na prática isso é algo que acontece tão pouco que acaba caindo no princípio YAGNI.

Outra desvantagem é que o PDO só simula prepared statements, que é algo que eu uso no código acima. A ideia é não recriar a query a cada iteração do for, por isso eu a preparo antes, fazendo com que ela seja reaproveitada a cada execução. Nativamente isso é feito do lado do servidor do banco, mas o PDO elimina este ganho por apenas simular a preparação.

Enfim, por que não usar as funções do MySQL diretamente? Vc elimina o overhead do PDO (já que a suposta “vantagem” de mudar de banco no futuro é algo que ocorre menos do que as pessoas pensam) e ainda ganha a vantagem do prepared statement (que é reaproveitar o trabalho do query planner em operações repetitivas).

// verifica se o jogo já existe no banco
function ja_existe($jogo, $stmt) {
    $stmt->bind_param('iiiiii', ...$jogo);
    $stmt->execute();
    $stmt->bind_result($count);
    $stmt->fetch();
    return $count > 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 mysqli('host', 'usuario', 'senha', 'nome do banco');
    $stmt = $Conn->prepare('select count(*) from sorteio where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?');
    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;
            }
        }
    }

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

Lembrando que usei as funções mysqli (com esse “i” no final). Também existem as funções mysql (sem o “i”), que estão obsoletas, então atenção aí :slight_smile:

Mais sobre PDO vs MySQLi em:

J

Amigo, deu certo aqui. Vou dar uma estudada no código e tentar compreender algumas coisas que ainda não conhecia. Muito obrigado.
Estou batendo cabeça para fazer o INSERT aqui. Vai da certo

J

Me explica uma coisa,
$stmt = $Conn->prepare(‘select count(*) from sorteio where Dez_1=? AND Dez_2=? AND Dez_3=? AND Dez_4=? AND Dez_5=? AND Dez_6=?’);

Aqui percebi que a clausula WHERE recebe um parametro representado por uma interrogação. Estava lendo que geralmente essa exclamação será substituida em outro ponto do código pela variavel que sera procurada no banco. Nesse codigo aqui nao vi.
Voce pode me explicar ?

J

Outra coisa que estou tentando entender é que testei a conexão, mudando o nome do BD ou da tabela e o sistema deu erro de conexão, porem, a tabela tem os campos dez1, dez2 etc, e nao Dez_1, Dez_2 e por em diante. Porque nao dá erro ?

H

É 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).

J

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

J
<?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";
}


?>
J

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

J
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 ?

H

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.

J

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

J

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

J

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:

J

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

H

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";
    }
}
J

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.

H

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.

J

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

Criado 26 de julho de 2023
Ultima resposta 3 de ago. de 2023
Respostas 33
Participantes 2