RogerTi 0 Denunciar post Postado Abril 23, 2017 Pessoal estou fazendo uma função aqui para um portal de noticias, ela consiste em mostrar algumas noticias, eu seleciono as noticias a partir da ultima data de forma decrescente porem eu chamo a função na primeira vez com limite 1, nas outras o limite é alterado, mas de forma que não exiba a ultima noticia novamente, até ai tudo bem, o problema é o seguinte eu preciso usar um operador logico que não é statico na função, ele muda de acordo com a chamada da função public function selecionar_noticias($tema, $operadorlogico,$ultimadata, $quantidade){ try{ $query = "SELECT * FROM noticia WHERE tema = :tema AND data_post ".$operadorlogico." :data ORDER BY data_post DESC LIMIT :quantidade"; $this->Selecionar = $this->Conn->prepare($query); $this->Selecionar->bindParam(':tema' , $tema , PDO::PARAM_STR); $this->Selecionar->bindParam(':data' , $ultimadata , PDO::PARAM_STR); $this->Selecionar->bindParam(':quantidade', $quantidade , PDO::PARAM_INT); $this->Selecionar->execute(); if($this->Selecionar->rowCount() > 0){ return $this->Selecionar->fetchAll(PDO::FETCH_ASSOC); } } catch (PDOException $ex) { } } porem se eu colocar ele assim $query = "SELECT * FROM noticia WHERE tema = :tema AND data_post :operador :data ORDER BY data_post DESC LIMIT :quantidade"; $this->Selecionar->bindParam(':operador' , $operadorlogico , PDO::PARAM_STR); não funciona, alguem sabe pq? Compartilhar este post Link para o post Compartilhar em outros sites
marsolim 110 Denunciar post Postado Abril 23, 2017 é porque o operador não é um nome de campo, ele tem que ser passando como ele realmente é. se tu butar os operadores numa select tu pode passar ele sem problema porque o usuário não pode inserir dado extra nele Compartilhar este post Link para o post Compartilhar em outros sites
RogerTi 0 Denunciar post Postado Abril 23, 2017 tipo, o grande medo ai é só SQLInjection, a função é chamada assim $noticias_curiosidades = $NoticiasPDO->selecionar_noticias('Curiosidade', '>', $ultimadata, 3); na própria pagina, então o usuário não insere dado algum, é apenas para separação de conteúdo em cada parte do site. Acha que tem algum problema em fazer da forma que funcionou? Compartilhar este post Link para o post Compartilhar em outros sites
marsolim 110 Denunciar post Postado Abril 23, 2017 bem tu pode ainda verificar se tem mais de um caractere sendo passado ou usar um preg_match pra validar de forma a passar só os caracteres validos para o caso tipo $operadorlogico = substr($_POST['operadorlogico'], 0, 1); se tiver mais coisa acrescentada nele só vai passar o primeiro caractere, também pode checar se tem mais de um caractere $operadorlogico = ((str_len($_POST['operadorlogico']) == 1) ? $_POST['operadorlogico'] : '>'); nesse caso se tiver só um caractere vai ser usado ele e se tiver mais de um fica apenas '>' Compartilhar este post Link para o post Compartilhar em outros sites
EdCesar 124 Denunciar post Postado Abril 23, 2017 Até o momento não tem, ou pelo menos desconheço, como tratar isso diretamente pelo PDO, segue uma sugestão: $validOperators = array('=', '>=', '>', '<=', '<'); if (!in_array($operator, $validOperators)) { throw new Exception('Invalid operator: ' . $operator . ')'; } $stmt = $conn->prepare("select * from table where :column $operator :value"); Compartilhar este post Link para o post Compartilhar em outros sites
RogerTi 0 Denunciar post Postado Abril 23, 2017 Ficou da seguinte forma public function selecionar_noticias($tema, $operadorlogico,$ultimadata, $quantidade){ try{ $validOperators = array('=', '>=', '>', '=<', '<'); if (!in_array($operadorlogico, $validOperators)) { throw new Exception('Operador invalido $operadorlogico ' . $operadorlogico); } $query = "SELECT * FROM noticia WHERE tema = :tema AND data_post $operadorlogico :data ORDER BY data_post DESC LIMIT :quantidade"; $this->Selecionar = $this->Conn->prepare($query); $this->Selecionar->bindParam(':tema' , $tema , PDO::PARAM_STR); $this->Selecionar->bindParam(':data' , $ultimadata , PDO::PARAM_STR); $this->Selecionar->bindParam(':quantidade', $quantidade , PDO::PARAM_INT); $this->Selecionar->execute(); if($this->Selecionar->rowCount() > 0){ return $this->Selecionar->fetchAll(PDO::FETCH_ASSOC); } } catch (PDOException $ex) { } } Em relação aos outros dados, eu preciso fazer uma verificação em seus valores? Digo que não existe o formulario para ser alterado os dados, essa função é função de carregamento de pagina, quando o cara entrar na index do site vai abrir cada sessão do site com varias noticias separadas por tema, preciso fazer uma verificação em cada variavel? Uma vez que tema é FK da tabela noticia, caso não tenha vai retornar 0 ou null. a função é chamada dessa forma na pagina $noticias_curiosidades = $NoticiasPDO->selecionar_noticias('Curiosidade', '>', $ultimadata, 3); if($noticias_curiosidades != FALSE){ foreach ($noticias_curiosidades as $x){ $not_titulo = $x['titulo']; $cur_banner = $x['banner']; $not_descricao = $x['descricao']; ?> Compartilhar este post Link para o post Compartilhar em outros sites
EdCesar 124 Denunciar post Postado Abril 23, 2017 Roger, não entendi muito bem essa ultima questão, vou tentar responder de forma genérica, do que acho que seja a questão. Precisamos sempre tratar dados que vem do usuário, e no caso de não poder tratar esse valor pelo PDO, por exemplo, com bindValue, em $sql = "... limit :limit"; Ai temos que validar com outras funções do PHP, como is_int() , FILTER_SANITIZE_NUMBER_INT ... Compartilhar este post Link para o post Compartilhar em outros sites
RogerTi 0 Denunciar post Postado Abril 23, 2017 Correto, estou falando que os dados ai eles são de carregamento do conteudo da pagina, exemplo, você entra agora no site da globo.com e já carrega as ultimas notícias, essa função é justamente para isso, quando a pessoa entrar no site carregar as ultimas notícias, então não tem contato com o usuário, contato por formulario que digo. Compartilhar este post Link para o post Compartilhar em outros sites
EdCesar 124 Denunciar post Postado Abril 23, 2017 Por exemplo: $this->Selecionar->bindParam(':tema', $tema, PDO::PARAM_STR); $this->Selecionar->bindParam(':data', $ultimadata, PDO::PARAM_STR); $this->Selecionar->bindParam(':quantidade', $quantidade, PDO::PARAM_INT); No caso de $tema, $ultimadata e $quantidade serem variaveis criadas por você mesmo, que não veem da pagina do usuario, você esta na duvida se precisa tratar elas? Se for isso, não precisa! Já vi gente defendendo que não custa nada, na verdade custa, custa muito pouco, mas custa. :) Compartilhar este post Link para o post Compartilhar em outros sites
RogerTi 0 Denunciar post Postado Abril 23, 2017 Sim, essa era a duvida, vlw ai! Compartilhar este post Link para o post Compartilhar em outros sites
EdCesar 124 Denunciar post Postado Abril 23, 2017 Talvez seja mais apropriado um tópico sobre, mas vou colocar os testes que fiz, e quem tiver interesse... Criando ambiente, no Mysql: create database Imasters; use Imasters; create table php_pdo ( id int auto_increment primary key, nome varchar(10), funcao varchar(10), objetivo varchar(25) ); Inserindo registro para teste (Não critiquem esse insert, não vem ao caso :) ) $db = new \PDO("mysql:host=localhost;dbname=Imasters", "root", ""); for($contador = 0; $contador < 15000; $contador++) { $db->exec("INSERT INTO php_pdo (nome,funcao,objetivo) VALUES ('PHP PDO','bindValue','teste de desempenho')"); } Primeiro teste, com execute e bindValue: $start = microtime(true); $sql = "select * from php_pdo where nome = :nome and funcao = :funcao"; $stmt = $db->prepare($sql); $stmt->bindValue(':nome', 'PHP PDO'); $stmt->bindValue(':funcao', 'bindValue'); $stmt->execute(); $result = $stmt->fetchall(\PDO::FETCH_ASSOC); $total = (microtime(true) - $start); echo $total; Amostra de sete resultados, com execute, com bindValue() 0.040969848632812 0.049991130828857 0.044628858566284 0.079172134399414 0.042876005172729 0.041944980621338 0.047070026397705Segundo teste, com execute e sem bindValue() $start = microtime(true); $sql = "select * from php_pdo where nome = 'PHP PDO' and funcao = 'bindValue'"; $stmt = $db->prepare($sql); $stmt->execute(); $result = $stmt->fetchall(\PDO::FETCH_ASSOC); $total = (microtime(true) - $start); echo $total; Amostra de sete resultados, com execute, sem bindValue: 0.023535013198853 0.031256914138794 0.044435024261475 0.042974948883057 0.037087202072144 0.052536964416504 0.030627012252808Terceiro teste, com query: $start = microtime(true); $sql = "select * from php_pdo where nome = 'PHP PDO' and funcao = 'bindValue'"; $resultado = $db->query($sql, PDO::FETCH_ASSOC)->fetchall(); $total = (microtime(true) - $start); echo $total; Amostra de sete resultados, com query: 0.031246900558472 0.027747869491577 0.026332855224609 0.02532696723938 0.027284145355225 0.02863597869873 0.023416996002197 Os teste foram executados em um ambiente isolado (vps na digitalocean) com as seguintes configurações: Memoria 1 GB 1 CPU, 30 GB SSD, PHP 7.1 Debian 8.7 x64 Mysql 5.5.54 Compartilhar este post Link para o post Compartilhar em outros sites
RogerTi 0 Denunciar post Postado Abril 23, 2017 Da forma que entendi o 3° teste foi o resultado mais rapido, porem ele não trata a variavel com statement? no caso, seria a melhor forma para variaveis que são criadas no ambiente, e não inseridas por algum usuário? Compartilhar este post Link para o post Compartilhar em outros sites
EdCesar 124 Denunciar post Postado Abril 24, 2017 Roger, se for considerar apenas essas amostras, seria isso mesmo. Mas esses simples testes estão longe de provar alguma coisa. Infelizmente, pelo menos nas minhas pesquisas, também não encontrei nada mais concreto sobre o assunto. Bom, mas fica aqui o espaço para quem possui um melhor conhecimento do assunto e quiser compartilhar. Compartilhar este post Link para o post Compartilhar em outros sites