GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Executar if com 2 funções ao mesmo tempo


#1

Boa tarde.

Tenho 2 funções que inserem dados em um bd ao mesmo tempo. Preciso fazer um “if” ondeele executa as duas funções e dá uma resposta caso as duas sejam executadas corretamente.

Mas caso uma delas não execute, a outra também não pode executar.

Tentei assim:

if((adicionaCategoria01($conecta01, $categoria)) && (adicionaCategoria02($conecta02, $categoria))){

#2

e assim?

if(adicionaCategoriaApp($conecta, $categoria) && adicionaCategoriaSite($conectaSite, $categoria)){

#3

Assim assim executou uma delas.

A intenção é não executar nenhuma se uma delas não executar.

E só executar as 2 se as 2 funcionarem corretamente.


#4

do jeito q eu fiz vai executar as duas pq o if espera uma “e” a outra pra ser satisfeito…

crie duas variaveis do tipo boolean e debuga pra vc ver é batata


#5

Eu testei aqui.

As duas funções inserem a mesma informação em bd diferentes.

Deixei uma das funções com erro, e a outra executou.

Será que o problema é a função em si?

   function adicionaCategoria01($conecta, Categoria $categoria){	  
	$sql  = 'INSERT INTO categoria (cat_nome) ';
	$sql .= 'VALUES (:nome)';
	  
	try{
	  $query = $conecta -> prepare($sql);  
	  $query -> bindValue(':nome', $categoria->getNome(), PDO::PARAM_STR);
	  $query -> execute();
			
	  return $query;
	}catch(PDOException $error){
	  return 0;
	}
  }

#6

haaaa intendi o q vc quer…

não ponha o try catch dentro da função lance ela e trate fora daí vc vai ter o resultado esperado


#7

Não se esqueça de usar transactions (commit e rollback) assim os dados no banco não serão gravados se algo der errado…


#8

isso ai…


#9

Desculpa, nessa caso não entendi o que devo fazer exatamente.

Teria como ajudar, mesmo se for indicando algo que eu possa estudar?


#10

pior q eu num sei php só te dei uma dica de lógica, sou programador java…mais tem bastante gente aki no guj q pode te ajudar


#11

Ok, muito obrigado pela ajuda.


#12
$conecta->beginTransaction();  

try{
    funcao1()...
    funcao2()...

    $conecta->commit(); // confirma a gravacao
} catch (PDOException $error){
    $conecta->rollback(); // volta tudo pq deu zica!!!...
}

E o try/catch em cada função você retira, deixa apenas os comandos de gravar e tal… só tem um problema… cada objeto PDO fica “amarrado” a um banco de dados por vez, você citou que cada função executa um insert em bancos diferentes né? Vai precisar fazer o commit/rollback para cada conexão pegou?


#13

Acho que entendi.

posso fazer assim:

if(adicionaCategoria($conecta, $categoria)){
  //deu certo
}else{
  //deu errado
}

e ai a funçao fazer isso que vc disse?

function adicionaCategoria($conecta, $categoria){
    $conecta01->beginTransaction();
    $conecta02->beginTransaction();  

try{
    // da o insert no bd 01
    // da o insert no bd 02

    $conecta01->commit();
    $conecta02->commit();

     return true;  
} catch (PDOException $error){
    $conecta01->rollback();
    $conecta02->rollback();

    return false;
}

#14

Não cara, faz uma coisa mais limpa…

function adicionaCategoria01($conecta, Categoria $categoria){	  
    $sql  = 'INSERT INTO categoria (cat_nome) ';
    $sql .= 'VALUES (:nome)';
  
    $query = $conecta->prepare($sql);  
    $query->bindValue(':nome', $categoria->getNome(), PDO::PARAM_STR);
    return $query->execute(); // isso ja retorna true ou false...
}

Faça algo parecido na outra função… depois de tudo…

$conecta->beginTransaction();  
$conecta2->beginTransaction();

try{
    adicionaCategoria($conecta, $categoria);
    funcao2($conecta2, ...);

    $conecta->commit();
    $conecta2->commit();
} catch (PDOException $error){
    $conecta->rollback();
    $conecta2->rollback();
}

A função apenas tenta executar os comandos, o tratamento deixa para “fora” dela, pegou?


#15

E apenas uma dica, quando você estiver afiado em PHP OOP, crie uma classe DAO e coloque suas funções lá dentro e peça uma conexão apenas uma única vez, por exemplo essa categoria ai…

class CategoriaDAO {
    private $conexao; //sera PDO

    public function __construct(PDO $pdo) {
        $this->conexao = $pdo;
    }

    public function lista() {...}
    public function busca($id) {...}
    public function adiciona(Categoria $categoria) {...}
    public function atualiza(Categoria $categoria) {...}
    public function remove(Categoria $categoria) {...}
}

Seu $conecta de dentro da função acabaria sendo o $this->conexao preenchido na construção do objeto (quando der um new)…

$dao = new CategoriaDAO($conecta);
$dao->adiciona($categoria);

Viu como fica “cheiroso” seu código, mais limpo e organizado…


#16

Acho que entendi. Vou tentar aqui e mais tarde aviso se deu certo.

Mas mesmo assim, muito obrigado pela ajuda.


#17

Bom dia amigo.

Eu segui a ajuda que deu e fiz, e funcionou!!! Agora, poderia me ajudar dizendo se estou usando as melhores praticas para a programação?

No final, ficou asssim:

Categoria_forms.php
Contém os formulários para adição, edição, exclusão, etc.

Categoria_funcoes.php
Trata os chamados dos forms, onde coloquei:

$dao  = new CategoriaDao();
$categoria -> setNome($_POST['nome']);

$conecta01 -> beginTransaction();  
$conecta02 -> beginTransaction();

try{
  $dao -> adiciona($categoria, 'tipo01', $conecta01);
  $dao -> adiciona($categoria, 'tipo02', $conecta02);

  $conecta01 -> commit();
  $conecta02 -> commit();
  $_SESSION['mensagem'] = 'Categoria adicionada com sucesso!';
  header("Location: Categoria_forms.php");
  
}catch (PDOException $error){
	
  $conecta01 -> rollback();
  $conecta02 -> rollback();
  $_SESSION['mensagem'] = 'Não foi possível adicionar a categoria.';
  header("Location: Categoria_forms.php");	
}

Depois:
CategoriaDao.php

  class CategoriaDao{
   function adiciona(Categoria $categoria, $tipo, $conexao){	  
	$sql  = 'INSERT INTO '.$tipo.'_categoria (cat_nome) ';
	$sql .= 'VALUES (:nomeCategoria)';
  
	$query = $conexao->prepare($sql);  
	$query->bindValue(':nomeCategoria', $categoria->getNome(), PDO::PARAM_STR);
	return $query->execute();
   }		
 }

No fim, funcionou exatamente como queria, executa as 2 instruções e caso uma delas dê problema, não executa nenhuma. Mas esta é a melhor forma de construir um código “cheiroso”??? rsrs


#18

Ta ficando “da hora”! :joy:

Agora fiquei na dúvida, o conecta01 e conecta02 apontam para bases de dados diferentes como você disse antes, ou apontam para a mesma base?

Pergunto porque você reutilizou o método adiciona mudando apenas o nome da tabela?

Se sim, é necessário criar duas conexões com o banco?


#19

Sim, apontam para bancos diferentes.

Mas para facilitar, eu coloquei as tabelas com nomes parecidos:

  banco01_categorias
  banco02_categorias

Assim consigo reutilizar o método com mais facilidade. Visto que um banco é uma cópia do outro. Ai é apenas passar o PDO de cada banco e sua respectiva tabela.

Será que estou no caminho certo?


#20

Em se tratando de cópia, o ideal seria a aplicação php guardar registros apenas em uma base, e no banco você deixar uma rotina (job, schedule, etc) que faça backup do banco de tempos em tempos, há configurações no banco que fazem replicação (raid) de um servidor para outro…

Isso deixa o php mais leve ainda, e sem responsabilidade demais (não sei se é seu caso), mas vale dar uma estudada a respeito…

Sempre tenha em mente que para o php (ou qualquer outro backend) um recurso externo (banco de dados, arquivos, web services, ftp, etc) são caros de se manter, quanto menos você precisar usá-los e mais rapidamente possível liberá-los (fechar conexões, etc) melhor…