Ir ao conteúdo
  • Cadastre-se
Mineirovsky

Php não abre múltiplos statements

Posts recomendados

Estou programando uma interação um pouco complicada com banco de dados e preciso fazer várias declarações preparadas para ler e gravar.

<?php
$email = $_POST['email'];
$mysqli = new mysqli(...);
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->bind_result(...)
$stmt->close();
$sql = "UPDATE users...";
$stmt = $mysqli->prepare($sql);
[...]

Após algumas interações recebo o erro:

Fatal error: Call to a member function bind_param() on a non-object

O que pode estar causando esse problema? Como posso contorná-lo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Mineirovsky Olá,

seria interessante você por o código todo na íntegra. Desse jeito não tem como analisar o código!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, lá vai:

<?php
require_once('../../config/config.php');
if(isset($_POST['id_transacao'])) {
    // Variáveis de retorno

    // Obtenha seu TOKEN entrando no menu Ferramentas do Bcash
    $token = $bcash['token'];

    /* Montando as variáveis de retorno */

    $id_transacao = $_POST['id_transacao'];
    $data_transacao = $_POST['data_transacao'];
    $data_credito = $_POST['data_credito'];
    $valor_original = $_POST['valor_original'];
    $valor_loja = $_POST['valor_loja'];
    $valor_total = $_POST['valor_total'];
    $desconto = $_POST['desconto'];
    $acrescimo = $_POST['acrescimo'];
    $tipo_pagamento = $_POST['tipo_pagamento'];
    $parcelas = $_POST['parcelas'];
    $cliente_nome = $_POST['cliente_nome'];
    $cliente_email = $_POST['cliente_email'];
    $cliente_rg = $_POST['cliente_rg'];
    $cliente_data_emissao_rg = $_POST['cliente_data_emissao_rg'];
    $cliente_orgao_emissor_rg = $_POST['cliente_orgao_emissor_rg'];
    $cliente_estado_emissor_rg = $_POST['cliente_estado_emissor_rg'];
    $cliente_cpf = $_POST['cliente_cpf'];
    $cliente_sexo = $_POST['cliente_sexo'];
    $cliente_data_nascimento = $_POST['cliente_data_nascimento'];
    $cliente_endereco = $_POST['cliente_endereco'];
    $cliente_complemento = $_POST['cliente_complemento'];
    $status = $_POST['status'];
    $cod_status = $_POST['cod_status'];
    $cliente_bairro = $_POST['cliente_bairro'];
    $cliente_cidade = $_POST['cliente_cidade'];
    $cliente_estado = $_POST['cliente_estado'];
    $cliente_cep = $_POST['cliente_cep'];
    $frete = $_POST['frete'];
    $tipo_frete = $_POST['tipo_frete'];
    $informacoes_loja = $_POST['informacoes_loja'];
    $id_pedido = $_POST['id_pedido'];
    $free = $_POST['free'];/* Essa variável indica a quantidade de produtos retornados */
    $qtde_produtos = $_POST['qtde_produtos'];
    $produto_codigo = $_POST['produto_codigo_1'];
    $autorizar = false;

    /* Verificando ID da transação */
    /* Verificando status da transação */
    /* Verificando valor original */
    /* Verificando valor da loja */

    $post = "transacao=$id_transacao".
    "&status=$status".
    "&cod_status=$cod_status".
    "&valor_original=$valor_original".
    "&valor_loja=$valor_loja".
    "&token=$token";
    $enderecoPost = "https://www.bcash.com.br/checkout/verify/";
/*
    ob_start();
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, $enderecoPost);
    curl_setopt ($ch, CURLOPT_POST, 1);
    curl_setopt ($ch, CURLOPT_POSTFIELDS, $post);
    curl_exec ($ch);
    $resposta = ob_get_contents();
    ob_end_clean();
*/
    if(/*trim($resposta)=="VERIFICADO"*/true) {
        //1. Verificar se id_transacao já existe no banco de Dados
        $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
        $sql = "SELECT status
                  FROM bcash
                 WHERE id_transacao = ?";
        $stmt = $conn->prepare($sql);
        printf("Error: 1.prepare %s.\n", $stmt->error);
        $stmt->bind_param('i', $id_transacao);
        $stmt->execute();
        printf("Error: 1.execute %s.\n", $stmt->error);
        $stmt->store_result();
        $id_exist = $stmt->num_rows;
        $stmt->bind_result($status_anterior);
        $stmt->fetch();
        $stmt->close();
        $conn->close();
        //2. Adicionar ou atualizar dados no banco de dados
        if($id_exist) {
            //Atualizar
            $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
            $sql = "UPDATE bcash
                       SET pay_method = ?, status = ?
                     WHERE id_transacao = ?";
            $stmt = $conn->prepare($sql);
            printf("Error: 2. prepare_atualizar %s.\n", $stmt->error);
            $stmt->bind_param('ssi', $tipo_pagamento, $status, $id_transacao);
            $stmt->execute();
            printf("Error: 2.execute_atualizar %s.\n", $stmt->error);
            $stmt->close();
            $conn->close();
            printf("\$status_anterior = %s; \$status = %s; \n", $status_anterior, $status);
            if($status_anterior == "Transação em Andamento" && $status == "Transação Concluída") $autorizar = true;
        } else {
            //Adicionar
            $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
            $sql = "INSERT INTO bcash (id_transacao, user_email, plan_id, pay_method, status, `timestamp`)
                         VALUES (?, ?, ?, ?, ?, ?)";
            $stmt = $conn->prepare($sql);
            printf("Error: 2. prepare_adicionar %s.\n", $stmt->error);
            $time = time();
            $stmt->bind_param('isissi', $id_transacao, $cliente_email, $produto_codigo, $tipo_pagamento, $status, $time);
            $stmt->execute();
            printf("Error: 2. execute_adicionar %s.\n", $stmt->error);
            $stmt->close();
            $conn->close();
            if($cod_status == 1) $autorizar = true;
        }
        //3. Autorizar usuário se pagamento for aprovado
        if($autorizar) {
            //3.1 Armazenar tempo do plano assinado
            $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
            $sql = "SELECT duration
                      FROM planos
                     WHERE id = ?";
            $stmt = $conn->prepare($sql);
            printf("Error: 3.1.0 prepare %s.\n", $stmt->error);
            $stmt->bind_param('i', $produto_codigo);
            $stmt->execute();
            printf("Error: 3.1.0 execute %s.\n", $stmt->error);
            $stmt->bind_result($duration);
            $stmt->fetch();
            $stmt->close();
            //$conn->close();
            $duration = $duration * 3600 * 24; //converte de dias para segundos
            if(!$duration) { //Se duração = 0, i.e. plano vitalício
                $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
                $sql = "UPDATE users
                           SET expire_date = '-1'
                         WHERE email = ?";
                $stmt = $conn->prepare($sql);
                printf("Error: 3.1.1 prepare %s.\n", $stmt->error);
                $stmt->bind_param('s', $cliente_email);
                $stmt->execute();
                printf("Error: 3.1.1 execute %s.\n", $stmt->error);
                $stmt->close();
                $conn->close();
            } else {
                //3.2 Verificar se usuário já possui plano
                $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
                printf("Connect failed: %s\n", mysqli_connect_error());
                $sql = "SELECT expire_date
                          FROM user
                         WHERE email = ?";
                $stmt = $conn->prepare($sql);
                printf("Error: 3.2 prepare %s.\n", $stmt->errno);
                $stmt->bind_param('s', $cliente_email);
                $stmt->execute();
                printf("Error: 3.2 execute %s.\n", $stmt->error);
                $stmt->bind_result($expire_date);
                $stmt->fetch();
                $stmt->close();
                $conn->close();
                //3.3 Se plano ainda for válido (i.e. expire_date > time()), somar o tempo assinado
                if($expire_date != 0) {
                    if($expire_date == -1) {
                        //faz nada
                    } elseif($expire_date > time()) {
                        $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
                        $sql = "UPDATE users
                                   SET expire_date = '" . ($expire_date + $duration) ."'
                                 WHERE email = ?";
                        $stmt = $conn->prepare($sql);
                        printf("Error: 3.3.1 prepare %s.\n", $stmt->error);
                        $stmt->bind_param('s', $cliente_email);
                        $stmt->execute();
                        printf("Error: 3.3.1 execute %s.\n", $stmt->error);
                        $stmt->close();
                        $conn->close();
                    } else {
                        $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
                        $sql = "UPDATE users
                                   SET expire_date = '" . (time() + $duration) . "'
                                 WHERE email = ?";
                        $stmt = $conn->prepare($sql);
                        printf("Error: 3.3.2 prepare %s.\n", $stmt->error);
                        $stmt->bind_param('s', $cliente_email);
                        $stmt->execute();
                        printf("Error: 3.3.2 execute %s.\n", $stmt->error);
                        $stmt->close();
                        $conn->close();
                    }
                    //3.4 Senão, somar o tempo da assinatura à data atual
                } else {
                    $conn = new mysqli($database['sname'], $database['user'], $database['pass'], $database['name']);
                    $sql = "UPDATE users
                               SET expire_date = '" . (time() + $duration) . "'
                             WHERE email = ?";
                    $stmt = $conn->prepare($sql);
                    printf("Error: 3.4 prepare %s.\n", $stmt->error);
                    $stmt->bind_param('s', $cliente_email);
                    $stmt->execute();
                    printf("Error: 3.4 execute %s.\n", $stmt->error);
                    $stmt->close();
                    $conn->close();
                }
            }
        }
    }
} else {}
?>

No caso aqui abri e fechei várias vezes a conexão, porque foi a forma que consegui contornar esse problema antes, mas nessa página especificamente há muito mais interações que nas outras que fiz. Só abrir e fechar os $stmt, ao invés de fechar os $conn também, não fez absolutamente nenhuma diferença.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como ninguém contribuiu e tenho prazo a ser cumprido, adaptei todo o código para PDO e resolvi o problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Este tópico está parado há muito tempo. Certifique-se que a sua mensagem tem a ver com o tema sendo discutido. Obrigado.

Junte-se à conversa

Você pode postar agora e cadastrar-se depois. Se você tem uma conta, faça o login para postar.

Visitante
Responder

×   Você colou conteúdo com formatação.   Restore formatting

  Só é possível ter até 75 emoticons.

×   O link foi automaticamente convertido para mostrar o conteúdo.   Clique aqui para mostrá-lo como link comum

×   Seu texto anterior foi restaurado.   Limpar o editor

×   You cannot paste images directly. Upload or insert images from URL.






Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: minicurso “Como ganhar dinheiro montando computadores”

Gabriel TorresGabriel Torres, fundador e editor executivo do Clube do Hardware, acaba de lançar um minicurso totalmente gratuito: "Como ganhar dinheiro montando computadores".

Você aprenderá sobre o quanto pode ganhar, como cobrar, como lidar com a concorrência, como se tornar um profissional altamente qualificado e muito mais!

Inscreva-se agora!