Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Nuno Levezinho

Optimização de Código PHP (Leilao)

Mensagens Recomendadas

Nuno Levezinho

Boas noites comunidade do P@P,

Tenho andado num projecto que consiste em criar um site de leilões do tipo BidRivals e o site já funciona totalmente com bastantes funcionalidades.

A parte mais chata, a meu ver do projecto já está concluida que é o hard codding agora vou passar à parte de optimização do código e vou precisamente começar no script de leilão em si mas para tal preciso de ideias.

O meu script do leilão funciona da seguinte maneira:

*São carregados os produtos (incluindo os dados do contador, etc) da base de dados para um form

*Se for premido o botão licitar serão debitados os créditos da conta do utilizador, caso não tenha créditos a licitação não tem efeito

*O contador adiciona recomeça sempre nos 20 segundos por cada licitação realizada com sucesso

*Por cada licitação realizada com sucesso, o preço do produto sobre 1Centimo

O meu senão é que eu tenho um refresh automático da div onde estão os produtos e penso que seja desnecessário fazer esse refresh automatico mesmo que nenhum produto tenha sido licitado.

Andei à procura de resolver esta situação de outra maneira, e falaram-me em xmlHttpRequest.

Já fui ao http://www.w3schools.com/xml/xml_http.asp e segui os tutoriais mas não cheguei a nenhuma conclusão.

Estarei a fazer "bem" em usar o xmlHttpRequest ou haverá outro método melhor?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Ainda não usei o xmlHttpRequest em parte nenhuma. Apenas estou a tentar saber qual a melhor maneira  de fazer com que a página apenas actualize se tiver havido uma licitação e não estar sempre a actualizar de 5 em 5 segundos quer tenha ou não havido licitações.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Pois eu sei, já fiz alguma pesquisa mas não encontro nehuma base (código) ou nada concreto em que possa ajudar a começar a trabalhar :s

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Mas não precisas de usar isso. Ajax serve perfeitamente por si só.

É vdd. Se se trata de 20s, basta enviar um pedido a cada 5 e tudo mantém-se bem.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Será que uma coisa deste genero é o que pretendo?

leilao.php

<?php
      //abre ligação
      $query = "SELECT leilao_bids_counter FROM leiloes WHERE  leilao_id_produto ='$id_prod'";
      $result = mysql_query($query);
    
     
      //se nao vieram resultados
      if(mysql_num_rows($result) == 0) 
            
      else{
            $resultadoArray = array();
            $row = mysql_fetch_array($result);
            $resultadoArray["leilao_id_produto"] = $row["leilao_id_produto"];
            $resultadoArray["leilao_bids_counter"] = $row["leilao_bids_counter"];
      
            echo "[" . json_encode($resultadoArray) . "]";
      }
?>

index.php

//Jquery
var checkTable = setInterval(function(){
      $.post('leilao.php', function(resultData){
            //se houver dados
             if(resultData){
            var resultObject = eval(resultData)[0];        
                  alert('Houve uma alteração no produto com id: ' + resultObject.leilao_id_produto + ' no contador: ' + resultObject.leilao_bids_counter);
            }
      }, 1000);

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yoda

resultData é a variável que é definida como portadora do resultado do request depois do mesmo ser feito. Eu costumo dar-lhe o nome de response, porque é o que ela contém, a resposta do servidor ao pedido. Podes dar-lhe o nome que quiseres, afinal, está a declarar uma função na hora, a ser chamada como callback.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Por alguma razão não estou a conseguir entrar no ciclo if do js.

if(resultData)

Será que não consigo obter nada do $.post ?

EDIT: Consegui resolver um dos problemas.

O resultData já imprime e é algo deste género: {"leilao_id":"1","leilao_bid_counter":"5"}

Mas acho que não é bem o que eu pretendo porque o que eu quero é verificar se houve alguma alteração nos registos das tabelas e isso implicaria retirar os pelos menos 2 campos de todos os registos e estar sempre a compara-los a cada 1-2 segundos certo?

Em termos práticos, como o faço?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
morsa

Isso é um objecto JSON  - Javascript Object Notation - http://en.wikipedia.org/wiki/JSON

No teu resultData recebes um objecto Javascript que vem do PHP logo, terás as propriedades disponíveis do lado do Javascript. Logo, se fizeres:

alert(resultData.leilao_id); 

deve aparecer uma mensagem com o id do leilão. O que deves fazer agora, é substituir os valores que recebes do servidor no local correcto.

      if(resultData){
                //var resultObject = eval(resultData)[0]; // <- eu nunca usei isto portanto vou fazer como sei 
                // actualiza o html no local correcto
                $("#licitacoes_" + resultData.leilao_id_produto).html(resultData.leilao_bids_counter);
            }

Em que o teu html seria algo do género

<div id="leilao">
   <div class="leilao-item">
      <div class="leilao-descricao-objecto"> Porta Chaves </div>
      <div class="leilao-licitacoes"><span id="licitacoes_1"> 0</span> licitações  </div>
   </div>
</div>

Após o teu intervalo (1segundo) devem aparecer os dados. Digo eu, cus nervos :)

Quanto às comparações, o que sugiro é que registes, na Base de Dados, a última data em que o leilão sofreu uma alteração, i.e, eu licitei um produto agora, actualizo um campo com a data e hora da ultima licitação para agora. Quando obtiver novos dados, devo obter apenas aqueles que se modificaram desde a última vez que fiz um pedido de dados - utilizas esse campo de dataUltimaLicitacao como base de comparação. Do lado do cliente, deves guardar a data e a hora numa variável em Javascript com a data do último pedido enviá-la quando fazes o pedido AJAX.

Qualquer coisa deste género:

// last update é a variável que guarda a última vez que foste ao servidor buscar dados
$.post('leilao.php?lastUpdate=' + lastUpdate, function(resultData){

   // depois de actualizares tudo deves actualizar a data
   // nota - vais ter problemas porque a data do javascript é diferente do MySQL, por exemplo~
   // vais ter que resolver isso 
   lastUpdate = new Date();

}

Espero ter ajudado. Boa sorte!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Muito Obrigado pela resposta e pela ajuda, acho que é mesmo isto que eu preciso.

Vou tentar adaptar para o meu código e depois digo qualquer coisa :)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nuno Levezinho

Estou com um problema, é que na minha parte HTML é tudo escrito dinamicamente numa tabela desenhada por mim e não tenho nada desses divs. Apenas tenho uma div que é a do conteudo da página que é onde estão apresentados os produtos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
morsa

Usas <table> invés de <div> ? Podes colocar aí o código?

Suponho que seja algo do género:

<table>
    <tr>
        <td> Porta Chaves </td><td> 2 licitações</td>
        <td> Relógio de Parede </td><td> 5 licitações</td>
        <td> Torradeira a Cores </td><td> 9 licitações</td>
   </tr>
</table>

Então basta colocares algo deste género:

<table>
    <tr>
        <td> Porta Chaves </td><td><span id="licitacoes_1">2</span> licitações</td>
        <td> Relógio de Parede </td><td><span id="licitacoes_2">5</span> licitações</td>
        <td> Torradeira a Cores </td><td><span id="licitacoes_3">9</span> licitações</td>
   </tr>
</table>

onde o valor do "X" em <span id="licitacoes_X"> é a chave (ID) do leilão na base de dados;

Será isto?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

@morsa Acho q a tua ideia é má. Devia-se de usar o ID do "parent" que é o <table> e seguir no DOM para encontrar os span correspondentes.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
morsa

@brunoais Embora perceba o que queres dizer e já tenha lido demasiadas coisas contraditórias acerca disso, gostava que explanasses isso. Do que percebi a tua ideia passava por colocar o id na table:

<table id="leilao">
    <tr>
        <td> Porta Chaves </td><td><span>2</span> licitações</td>
        <td> Relógio de Parede </td><td><span>5</span> licitações</td>
        <td> Torradeira a Cores </td><td><span>9</span> licitações</td>
   </tr>
</table>

E obtinhas os spans como? Penso que tens que identificá-los na mesma, não? Eu sei que é muito mais eficaz fazer $("#leilao #licitacao_1").html("qq coisa"); do que somente utilizar o id da licitação.  Se tens outra abordagem partilha-a. Gostava de saber...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

@brunoais Embora perceba o que queres dizer e já tenha lido demasiadas coisas contraditórias acerca disso, gostava que explanasses isso. Do que percebi a tua ideia passava por colocar o id na table:

...

E obtinhas os spans como? Penso que tens que identificá-los na mesma, não? Eu sei que é muito mais eficaz fazer $("#leilao #licitacao_1").html("qq coisa"); do que somente utilizar o id da licitação.  Se tens outra abordagem partilha-a. Gostava de saber...

Simples. O jQuery usa seletores CSS, por isso, encontrar os span é facílimo.

var valores = [2,3,8];
$("#leilao span").each(function (index, element){
 // o que quiseres fazer, por exemplo:
element.firstChild.text = valores[index];
}


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
morsa

Isso, partindo do pressuposto que uma vez carregada a página, a ordem não muda.

Como sabes que a chave do primeiro elemento do span é a 1 e não 5? Imagina que o utilizador reordenou a forma de apresentação e não foi com "javascript". Continua a funcionar? E se um leilão deixou de "existir" e tiveres que adicionar um "novo"?

Não sei, não me parece que funcione... Mas posso testar... daqui a uns anos! LOL (Sem tempo...)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Quando alterares a ordem n há problema.

Quando retirares 1 n há problema

Quando adicionares >0 elementos tens que os adicionar e depois recalcular. Podes meter quilo dentro de uma função que recebe o array com a ordem atual e mandas re-executar quando são adicionadas novas linhas.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
brunoais

Usa divs e o respectivo atributo xhtml data-nome.

É para assumir que isto é html5?


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.