Mysql moving average query
O PHP oferece três API diferentes para se conectar ao MySQL. Estes são o mysql (removido a partir do PHP 7), mysqli. E extensões de PDO. As funções mysql costumavam ser muito populares, mas seu uso não é mais encorajado. A equipe de documentação está discutindo a situação de segurança do banco de dados, e educar os usuários para se afastarem da extensão usada extmysql é parte disso (verifique php. internals: deprecating extmysql). E a equipe de desenvolvedores do PHP posterior tomou a decisão de gerar erros EDEPRECADOS quando os usuários se conectam ao MySQL, seja através do mysqlconnect (). Mysqlpconnect () ou a funcionalidade de conexão implícita incorporada em extmysql. O extmysql foi oficialmente reprovado a partir do PHP 5.5 e foi removido a partir do PHP 7. Quando você vai em qualquer página do manual da função mysql, você vê uma caixa vermelha, explicando que não deveria mais ser usado. Mover-se de extmysql não é apenas sobre segurança, mas também sobre ter acesso a todos os recursos do banco de dados MySQL. O extmysql foi construído para o MySQL 3.23 e só obteve muito poucas adições desde então, enquanto mantendo a compatibilidade com esta versão antiga, o que torna o código um pouco mais difícil de manter. Os recursos que faltam que não são suportados pelo extmysql incluem: (a partir do manual do PHP). Razão para não usar a função mysql: Não em desenvolvimento ativo Removido a partir do PHP 7 Falta uma interface OO Não suporta consultas não assíncronas não bloqueadoras Não suporta instruções preparadas ou consultas parametrizadas Não suporta procedimentos armazenados Não suporta várias declarações Não suporta transações Não suporta todos A funcionalidade no MySQL 5.1 A falta de suporte para declarações preparadas é particularmente importante, pois eles fornecem um método mais claro e menos propenso a erros para escapar e citar dados externos do que escapá-lo manualmente com uma chamada de função separada. Supressão de avisos de desaprovação Enquanto o código está sendo convertido no MySQLi DOP. Os erros de EDEPRECATED podem ser suprimidos definindo o relatório de erro no php. ini para excluir EDEPRECATED: Observe que isso também esconderá outros avisos de desaprovação. Que, no entanto, pode ser para outras coisas que o MySQL. (A partir do manual PHP) E uma maneira melhor é PDO. E agora estou escrevendo um simples tutorial PDO. Um tutorial PDO simples e curto Q. Primeira pergunta em minha mente foi: o que é PDO A. PDO O PHP Data Objects é uma camada de acesso ao banco de dados que fornece um método uniforme de acesso a vários bancos de dados. Conectando-se ao MySQL Com a função mysql ou podemos dizer o caminho antigo (obsoleto no PHP 5.5 e acima) Com o PDO. Tudo o que você precisa fazer é criar um novo objeto PDO. O construtor aceita parâmetros para especificar a fonte de banco de dados. O PDO s construtor leva principalmente quatro parâmetros que são DSN (nome da fonte de dados) e opcionalmente nome de usuário. senha . Aqui, acho que você está familiarizado com todos, exceto o DSN, este é novo na DOP. Um DSN é basicamente uma série de opções que contam à DOP que driver usar e detalhes de conexão. Para mais referência, cheque PDO MySQL DSN. Nota: você também pode usar charsetUTF-8. Mas às vezes causa um erro, então é melhor usar utf8. Se houver algum erro de conexão, ele lançará um objeto PDOException que pode ser armazenado em cache para lidar com a Exceção ainda mais. Você também pode passar várias opções de driver como uma matriz para o quarto parâmetro. Eu recomendo passar o parâmetro que coloca o PDO no modo exceção. Como alguns drivers PDO não suportam declarações preparadas nativas, então o PDO executa a emulação da preparação. Ele também permite ativar manualmente esta emulação. Para usar as instruções preparadas nativas do lado do servidor, você deve explicitamente configurá-lo como falso. O outro é desligar preparar a emulação habilitada no driver MySQL por padrão, mas preparar a emulação deve ser desligada para usar o PDO com segurança. Depois, explicaremos por que a emulação deve ser desativada. Para encontrar razões, verifique esta postagem. É apenas utilizável se você estiver usando uma versão antiga do MySQL que eu não recomendava. Abaixo está um exemplo de como você pode fazê-lo: podemos definir atributos após a construção do PDO, sim. Também podemos definir alguns atributos após a construção do PDO com o método setAttribute: Manipulação de erros O tratamento de erros é muito mais fácil em DOP do que no mysql. Uma prática comum ao usar o mysql é: OR die () não é uma boa maneira de lidar com o erro, uma vez que não podemos lidar com a coisa em dado. Ele acabará por terminar o roteiro abruptamente e depois repetirá o erro na tela que você normalmente NÃO quer mostrar aos seus usuários finais, e deixa os hackers sangrentos descobrirem seu esquema. Alternativamente, os valores de retorno das funções mysql podem ser usados com o mysqlerror () para lidar com erros. O PDO oferece uma solução melhor: exceções. Tudo o que fazemos com a DOP deve ser envolvido em um bloco try-catch. Podemos forçar o DOP a um dos três modos de erro configurando o atributo do modo de erro. Três modos de tratamento de erros estão abaixo. PDO :: ERRMODESILENT. É apenas definir códigos de erro e age praticamente o mesmo que o mysql, onde você deve verificar cada resultado e, em seguida, ver db-gterrorInfo () para obter os detalhes do erro. PDO :: ERRMODEWARNING Raise EWARNING. (Avisos em tempo de execução (erros não fatais). A execução do script não é interrompida.) PDO :: ERRMODEEXCEPTION. Throw exceções. Representa um erro gerado pela DOP. Você não deve lançar uma PDOException do seu próprio código. Veja Exceções para obter mais informações sobre exceções em PHP. Isso funciona muito ou morre (mysqlerror ()). Quando não é pego. Mas ao contrário ou morre (). A PDOException pode ser capturada e tratada graciosamente se você optar por fazê-lo. E você pode envolvê-lo na tentativa de captura. Como abaixo: você não precisa lidar com tentar - pegar agora. Você pode pegá-lo a qualquer momento, mas eu recomendo que você use tentativas. Também pode fazer mais sentido para atraí-lo para fora da função que chama o material PDO: Além disso, você pode manipular ou morrer () ou podemos dizer como mysql. Mas será muito variado. Você pode esconder as mensagens de erro perigosas na produção, desligando as opções e simplesmente lendo seu registro de erros. Agora, depois de ler todas as coisas acima, você provavelmente está pensando: o que diabos é aquele quando eu só quero começar a se inclinar SELECT simples. INSERIR. ATUALIZAR. Ou DELETE não se preocupe, aqui vamos: Selecionando dados Então, o que você está fazendo no mysql é: agora em DOP. Você pode fazer isso como: Nota. Se você estiver usando o método como abaixo (consulta ()), esse método retorna um objeto PDOStatement. Então, se você deseja obter o resultado, use-o como acima. Nos dados PDO, ele é obtido através do - gtfetch (). Um método do identificador de declaração. Antes de chamar a busca, a melhor abordagem seria informar a DOP como você gostaria que os dados fossem obtidos. Na seção abaixo, estou explicando isso. Modos de busca Observe o uso de PDO :: FETCHASSOC no código fetch () e fetchAll () acima. Isso diz a DOP para retornar as linhas como uma matriz associativa com os nomes dos campos como chaves. Há muitos outros modos de busca também, que vou explicar uma a uma. Antes de tudo, explico como selecionar o modo de busca: no acima, usei fetch (). Você também pode usar: PDOStatement :: fetchAll () - Retorna uma matriz contendo todas as linhas de set de resultados PDOStatement :: fetchColumn () - Retorna uma única coluna da próxima linha de um conjunto de resultados PDOStatement :: fetchObject () - Obtém o Próxima linha e retorna como um objeto. PDOStatement :: setFetchMode () - Defina o modo de busca padrão para esta declaração Agora venho para o modo de busca: PDO :: FETCHASSOC. Retorna uma matriz indexada pelo nome da coluna como retornado no seu conjunto de resultados PDO :: FETCHBOTH (padrão): retorna uma matriz indexada pelo nome da coluna e pelo número da coluna indexado de 0 como retornado no seu conjunto de resultados. Há ainda mais opções Leia sobre todos eles Na documentação de recolha de PDOS. . Obtendo a contagem de linhas: Em vez de usar mysqlnumrows para obter o número de linhas retornadas, você pode obter um PDOStatement e fazer rowCount (). Como: Obter as últimas inserções de Inserção de Inserção e Atualizar ou Excluir declarações O que estamos fazendo na função mysql é: E no pdo, o mesmo pode ser feito por: Na consulta acima, o PDO :: exec executa uma instrução SQL e retorna o número Das fileiras afetadas. Inserir e excluir será abordado mais tarde. O método acima é útil somente quando você não está usando a variável na consulta. Mas quando você precisa usar uma variável em uma consulta, nunca tente como o acima e lá para declaração preparada ou declaração parametrizada é. Declarações preparadas P. O que é uma declaração preparada e por que eu preciso deles. Uma declaração preparada é uma instrução SQL pré-compilada que pode ser executada várias vezes enviando apenas os dados para o servidor. O fluxo de trabalho típico do uso de uma declaração preparada é o seguinte (citada a partir de Wikipedia 3 pontos 3): Prepare. O modelo de declaração é criado pelo aplicativo e enviado ao sistema de gerenciamento de banco de dados (SGBD). Alguns valores são deixados não especificados, chamados parâmetros, espaços reservados ou variáveis de ligação (rotulados abaixo): INSERT INTO PRODUCT (nome, preço) VALUES (.) O SGBD analisa, compila e executa a otimização de consulta no modelo de declaração e armazena o resultado Sem executá-lo. Execute. Mais tarde, o aplicativo fornece (ou liga) valores para os parâmetros, e o SGBD executa a declaração (possivelmente retornando um resultado). O aplicativo pode executar a declaração quantas vezes quiser com valores diferentes. Neste exemplo, ele pode fornecer Bread para o primeiro parâmetro e 1.00 para o segundo parâmetro. Você pode usar uma declaração preparada incluindo espaços reservados no seu SQL. Existem basicamente três sem espaços reservados (não tente isso com variável acima), um com marcadores de lugar sem nome e um com marcadores de lugar com nome. P. Então, agora, quais são os marcadores de posição e como os uso A. Marcadores de lugar nomeados. Use nomes descritivos precedidos por dois pontos, em vez de pontos de interrogação. Não nos importamos com a posição de valor no titular do nome: também pode vincular usando uma matriz de execução: Outro recurso agradável para os amigos do OOP é que os espaços reservados nomeados têm a capacidade de inserir objetos diretamente no seu banco de dados, assumindo que as propriedades correspondem ao nomeado Campos. Por exemplo: Q. Então, agora, quais são espaços reservados sem nome e como os uso A. Vamos ter um exemplo: no acima, você pode ver esses. Em vez de um nome como em um titular de lugar de nome. Agora, no primeiro exemplo, atribuímos variáveis aos vários espaços reservados (stmt-gtbindValue (1, name, PDO :: PARAMSTR)). Em seguida, atribuímos valores aos espaços reservados e executamos a declaração. No segundo exemplo, o primeiro elemento de matriz vai para o primeiro. E o segundo para o segundo. NOTA . Em espaços reservados sem nome, devemos cuidar da ordem correta dos elementos na matriz que estamos passando para o método PDOStatement :: execute (). SELECIONE. INSERIR. ATUALIZAR. DELETE perguntas preparadas Amine, não, não é. Enquanto NullPoite realmente fez um ótimo trabalho ao escrever, isso certamente não é uma boa leitura, porque é muito longo. Tenho certeza de que 8 de 10 visitantes simplesmente ignorá-lo. E você também tem explicação, por que esta resposta não é votada pela maior parte. Uma parte do tldr no começo seria uma boa ideia, penso. Ndash trejder Jul 4 14 às 11:00 Primeiro, vamos começar com o comentário padrão que damos a todos: Por favor, não use funções mysql em um novo código. Eles não são mais mantidos e estão oficialmente obsoletos. Veja a caixa vermelha. Saiba mais sobre declarações preparadas e use DOP ou MySQLi - este artigo irá ajudá-lo a decidir qual. Se você escolher PDO, aqui está um bom tutorial. Vamos passar por isso, frase por frase, e explicar: eles não são mais mantidos, e estão oficialmente obsoletos Isso significa que a comunidade PHP está gradualmente a deixar o suporte para essas funções muito antigas. É provável que não existam em uma versão futura (recente) do PHP. O uso continuado dessas funções pode quebrar o seu código no futuro distante (e não). O extmysql mais recente foi removido no PHP 7 Em vez disso, você deve aprender instruções preparadas - a extensão mysql não suporta declarações preparadas. Que é (entre outras coisas) uma contramedida muito eficaz contra a Injeção de SQL. Ele corrigiu uma vulnerabilidade muito séria em aplicativos dependentes do MySQL, o que permite que os invasores obtenham acesso ao seu script e executem qualquer consulta possível em seu banco de dados. Quando você vai em qualquer página do manual da função mysql, você vê uma caixa vermelha, explicando que não deveria mais ser usado. Use PDO ou MySQLi Existem alternativas melhores, mais robustas e bem construídas, PDO - Objeto de Banco de Dados PHP. Que oferece uma abordagem OOP completa para interação de banco de dados e MySQLi. Que é uma melhoria específica do MySQL. Facilidade de uso As razões analíticas e sintéticas já foram mencionadas. Para os recém-chegados, há um incentivo mais significativo para parar de usar as funções mysql datadas. As APIs de banco de dados contemporâneas são apenas mais fáceis de usar. É principalmente os parâmetros vinculados que podem simplificar o código. E com excelentes tutoriais (como visto acima) a transição para PDO não é excessivamente árdua. Reescrever uma base de código maior ao mesmo tempo, contudo leva tempo. Raison dtre para esta alternativa intermediária: funções pdo equivalentes no lugar de mysql Usando lt pdomysql. php gt, você pode alternar das antigas funções mysql com um esforço mínimo. Ele adiciona wrappers de função pdo que substituem suas equivalências mysql. Basta incluir uma (pdomysql. php) em cada script de invocação que tenha que interagir com o banco de dados. Remova o prefixo da função mysql em todos os lugares e substitua-o por pdo. Mysql connect () torna-se pdo connect () mysql query () torna-se pdo query () mysql numrows () torna-se pdo desrows () mysql insertid () torna-se pdo insertid () mysql fetcharray () torna-se pdo fetcharray () mysql fetchassoc () torna-se Pdo fetchassoc () mysql realescapestring () torna-se pdo realescapestring () e assim por diante. Seu código funcionará de forma semelhante e ainda mais parece o mesmo: Et voil. Seu código está usando DOP. Agora é hora de realmente utilizá-lo. Os parâmetros vinculados podem ser fáceis de usar. Você só precisa de uma API menos difícil. Pdoquery () adiciona suporte muito fácil para parâmetros vinculados. Converter código antigo é direto: mova suas variáveis para fora da seqüência SQL. Adicione-os como parâmetros de função delimitados por vírgulas para pdoquery (). Coloque pontos de interrogação. Como espaços reservados onde as variáveis eram anteriores. Livrar-se de aspas simples que anteriormente incluíram variáveis de valores de string. A vantagem torna-se mais óbvia para um código mais longo. Muitas vezes, as variáveis de string não são interpoladas para o SQL, mas concatenadas com chamadas de escape entre elas. Com. Os marcadores de posição aplicados não precisam se preocupar com isso: lembre-se de que o pdo ainda permite ou. Basta não escapar de uma variável e ligá-la na mesma consulta. A característica de espaço reservado é fornecida pelo DOP real por trás disso. Assim, também permitido: listas de espaço reservado nomeadas mais tarde. Mais importante ainda, você pode passar as variáveis REQUEST com segurança de qualquer consulta. Quando os campos ltformgt submetidos coincidem com a estrutura do banco de dados exatamente é ainda mais curto: tanta simplicidade. Mas vamos voltar a mais reescrever conselhos e razões técnicas sobre por que você pode querer se livrar do mysql e fugir. Corrija ou remova qualquer função oldschool sanitize () Depois de ter convertido todas as chamadas mysql para pdoquery com params vinculados, remova todas as chamadas redundantes pdorealescapestring. Em particular, você deve corrigir qualquer desinfetante ou limpar ou filtrar as funções deste ou cleandata conforme anunciado por tutoriais datados de uma forma ou outra: o bug mais flagrante aqui é a falta de documentação. Mais significativamente, a ordem de filtragem estava exatamente na ordem errada. A ordem correta teria sido: depreciado stripslashes como a chamada mais interna, e depois aparar. Depois striptags. Htmlentities para o contexto de saída, e apenas por último o escapestring como sua aplicação deve preceder diretamente o SQL intersparsing. Mas, como primeiro passo, simplesmente se livrar da chamada realcapestring. Você pode ter que manter o resto da sua função de higienização () por enquanto, se o banco de dados e o fluxo de aplicativos esperam cadeias seguras em contexto HTML. Adicione um comentário que aplica apenas HTML escapando doravante. O gerenciamento de Stringvalue é delegado em DOP e suas instruções parametrizadas. Se houvesse alguma menção de stripslashes () na sua função de sanitização, isso pode indicar uma supervisão de nível superior. Isso era comum para desvendar o dano (escape duplo) das magicasquinas depreciadas. O que, no entanto, é melhor corrigido centralmente. Não string por string. Use uma das abordagens de reversão do usuário. Em seguida, remova as barras de tira () na função de higienização. Nota histórica sobre magicquotes. Esse recurso está corretamente depreciado. É, contudo, retratado incorretamente como característica de segurança com falha no entanto. Mas magicquotes são tanto um recurso de segurança falhado quanto as bolas de tênis falharam como fonte de nutrição. Isso simplesmente não era seu propósito. A implementação original no PHP2FI introduziu explicitamente com apenas as cotações será escapada automaticamente tornando mais fácil a transmissão de dados de formulário diretamente para consultas msql. Notavelmente, foi acidentalmente seguro usar com mSQL. Como somente ASCII suportado. Em seguida, PHP3Zend reintroduziu magicquotes para MySQL e maldito. Mas, originalmente, era apenas uma característica de conveniência. Não pretende segurança. Como as declarações preparadas diferem Quando você codifica as variáveis de string nas consultas SQL, ele simplesmente não é mais intrincado para você seguir. É também esforço estranho para o MySQL segregar código e dados novamente. As injeções de SQL são simplesmente quando os dados sangram no contexto do código. Um servidor de banco de dados não pode mais tarde detectar onde o PHP originalmente colou variáveis entre as cláusulas de consulta. Com parâmetros vinculados, você separa o código SQL e os valores do contexto SQL em seu código PHP. Mas não é arrastado novamente atrás dos bastidores (exceto com PDO :: EMULATEPREPARES). Seu banco de dados recebe os comandos SQL não variáveis e valores variáveis 1: 1. Enquanto esta resposta enfatiza que você deve se preocupar com as vantagens de legibilidade de deixar o mysql. Há ocasionalmente também uma vantagem de desempenho (INSERTs repetidos com apenas valores diferentes) devido a esta separação de dados e dados visíveis. Cuidado com o fato de que o parâmetro de ligação ainda não é uma solução mágica de uma única parada contra todas as injeções de SQL. Ele lida com o uso mais comum para datavalues. Mas não consiga os identificadores da tabela de nomes da coluna da lista branca, ajude a construção da cláusula dinâmica ou apenas listas de valores de matriz simples. Uso de PDO híbrido Estas funções de wrapper de pdo tornam uma API de lacunas de redução de codificação. (É praticamente o que MYSQLI poderia ter sido se não fosse para a mudança de assinatura da função idiossincrática). Eles também expõem o DOP real na maioria das vezes. Reescrever não precisa parar de usar os novos nomes das funções pdo. Você poderia uma por uma transição cada pdoquery () em uma simples chamada pdo-prepare () - execute (). É melhor começar a simplificar novamente no entanto. Por exemplo, a obtenção de resultados comuns: pode ser substituída por apenas uma iteração foreach: Ou melhor ainda, uma recuperação de matriz direta e completa: você obterá avisos mais úteis na maioria dos casos do que o PDO ou o mysql geralmente fornecem após consultas falhadas. Outras opções Então, espero que tenha visualizado algumas razões práticas e um caminho digno para soltar mysql. Basta mudar para pdo não cortá-lo. Pdoquery () também é apenas um frontend para ele. A menos que você também apresente vinculação de parâmetros ou possa utilizar algo mais da API mais agradável, é um interruptor inútil. Espero que seja retratado simples o suficiente para não diminuir o desânimo para os recém-chegados. (A educação costuma funcionar melhor do que a proibição.) Embora seja qualificado para a categoria mais simples - que-possivelmente-trabalho, também é um código muito experimental. Acabei de escrever isso durante o fim de semana. Há, no entanto, uma infinidade de alternativas. Apenas google para abstração de banco de dados PHP e navegue um pouco. Sempre houve e haverá muitas bibliotecas excelentes para tais tarefas. Se você quiser simplificar a interação do banco de dados, os mapeadores como ParisIdiorm merecem uma tentativa. Assim como ninguém usa o DOM bland em JavaScript, você não precisa babysitar uma interface de banco de dados em bruto hoje em dia. Respondido 24 de dezembro às 23:30 Falando por razões técnicas, há apenas alguns, extremamente específicos e raramente usados. Provavelmente você nunca vai usá-los em sua vida. Talvez eu seja muito ignorante, mas nunca tive a oportunidade de usá-los, como procedimentos não bloqueados, consultas assíncronas, procedimentos armazenados que retornam múltiplos conjuntos de resultados. Criptografia (SSL) Compressão Se você precisar deles - não há dúvida de razões técnicas para se afastar do mysql Extensão para algo mais elegante e de aparência moderna. No entanto, existem também alguns problemas não-técnicos, que podem tornar a sua experiência um pouco mais difícil o uso dessas funções com versões modernas do PHP, levando avisos de nível obsoleto. Eles simplesmente podem ser desligados. Em um futuro distante, eles podem ser possivelmente removidos da compilação PHP padrão. Ainda não é um grande negócio, já que o mydsql ext será transferido para o PECL e todos os hospedeiros ficarão felizes em complacer o PHP com ele, pois não querem perder clientes cujos sites estavam funcionando há décadas. Forte resistência da comunidade Stackoverflow. Muito tempo você menciona essas funções honestas, você está sendo informado de que eles estão sob um tabu estrito. Sendo um usuário médio de php, provavelmente sua idéia de usar essas funções é propensa a erros e errada. Apenas por causa de todos esses inúmeros tutoriais e manuais que lhe ensinam o caminho errado. Não as próprias funções - eu tenho que enfatizar - mas a maneira como elas são usadas. Esta última questão é um problema. Mas, na minha opinião, a solução proposta também não é melhor. Parece-me idealista um sonho de que todos esses usuários do PHP aprenderão a lidar com consultas SQL de uma só vez. Provavelmente eles simplesmente mudariam mysql para mysqli mecanicamente, deixando o mesmo caminho. Especialmente porque o mysqli faz declarações preparadas, o uso incrível e doloroso. Para não mencionar que as declarações nativas preparadas não são suficientes para proteger das injeções SQL, e nem o mysqli nem a DOP oferecem uma solução. Então, em vez de combater essa extensão honesta, eu prefiro lutar contra práticas erradas e educar as pessoas da maneira certa. Além disso, existem alguns motivos falsos ou não significativos, como não suporta procedimentos armazenados (estávamos usando mysqlquery (CALL myproc) por idades) Não suporta transações (o mesmo que acima) Não suporta várias declarações (quem precisa delas) Não está em desenvolvimento ativo (Então, o que isso afeta de maneira prática). Falta uma interface OO (para criar uma é uma questão de várias horas). Não é compatível. Declarações preparadas ou consultas parametrizadas. Um último é um ponto interessante. Embora o mysql ext não ofereça instruções nativas preparadas, elas não são necessárias para a segurança. Podemos facilmente falsas declarações preparadas usando marcadores de posição manipulados manualmente (assim como o PDO faz): voila. Tudo é parametrizado e seguro. Mas ok, se você não gosta da caixa vermelha no manual, surge um problema de escolha: mysqli ou PDO Bem, a resposta seria a seguinte: se você entender a necessidade de usar uma camada de abstração de banco de dados. E procurando uma API para criar uma, o mysqli é uma escolha muito boa, pois, de fato, suporta muitos recursos específicos do mysql. Se, como a maior parte dos funcionários do PHP, você está usando chamadas de API em bruto no código do aplicativo (o que é essencialmente uma prática errada) - A DOP é a única escolha. Como esta extensão pretende não ser apenas API, mas sim um semi-DAL, ainda incompleto, mas oferece muitas características importantes, com duas delas faz com que a DOP se distingue criticamente do mysqli: ao contrário do mysqli, o DOP pode vincular os espaços reservados por valor. O que torna viáveis consultas dinâmicas possíveis sem várias telas de código bastante desarrumado. Ao contrário do mysqli, o PDO sempre pode retornar o resultado da consulta em uma matriz simples e simples, enquanto o mysqli pode fazê-lo somente em instalações mysqlnd. Então, se você é um usuário médio de PHP e quer economizar uma tonelada de dores de cabeça ao usar declarações preparadas nativas, o PDO - novamente - é a única escolha. No entanto, a DOP também não é uma bala de prata e tem dificuldades. Então, eu escrevi soluções para todas as armadilhas comuns e casos complexos no wiki tag PDO No entanto, todos falando de extensões sempre faltam os dois fatos importantes sobre Mysqli e DOP: Declaração preparada não é uma bala de prata. Existem identificadores dinâmicos que não podem ser vinculados usando instruções preparadas. Existem consultas dinâmicas com números desconhecidos de parâmetros que tornam a construção de consultas uma tarefa difícil. Nem as funções mysqli nem PDO devem aparecer no código do aplicativo. Deve haver uma camada de abstração entre eles e o código da aplicação, que fará todo o trabalho sujo de ligação, looping, manipulação de erros, etc. dentro, tornando o código do aplicativo DRY e limpo. Especialmente para casos complexos, como construção de consultas dinâmicas. Então, simplesmente mudar para PDO ou mysqli não é suficiente. É preciso usar um ORM ou um construtor de consulta, ou qualquer outra classe de abstração de banco de dados, em vez de chamar funções de API em bruto em seu código. E ao contrário - se você tiver uma camada de abstração entre o seu código de aplicação e a API do mysql - na verdade, não importa qual motor é usado. Você pode usar o mysql ext até ficar desaprovado e, em seguida, reescrever facilmente sua classe de abstração para outro mecanismo, tendo todo o código do aplicativo intacto. Aqui estão alguns exemplos baseados em minha classe safemysql para mostrar como essa classe de abstração deveria ser: Compare esta única linha com a quantidade de código que você precisará com a DOP. Em seguida, compare com a quantidade louca de código que você precisará com declarações preparadas Mysqli. Observe que o gerenciamento de erros, o perfil, o registro de consultas já foram criados e em execução. Compare-o com as inserções usuais da PDO, quando cada nome de campo é repetido seis a dez vezes - em todos estes numerosos marcadores de posição nomeados, ligações e definições de consulta. Você dificilmente pode encontrar um exemplo para a DOP para lidar com esse caso prático. E será muito falso e provavelmente inseguro. Então, mais uma vez - não é apenas o driver bruto deve ser sua preocupação, mas a classe de abstração, útil não só para exemplos bobos do manual de iniciantes, mas para resolver qualquer problema da vida real. Como não está em desenvolvimento ativo apenas para o inventado 390.0139 Se você construir algo com esta função de reposição, atualize sua versão do mysql em um ano e acabe com um sistema que não funcione, eu tenho certeza de que há uma grande quantidade de Pessoas de repente nesse 390.0139. Eu disse que depreciado e não em desenvolvimento ativo está intimamente relacionado. Você pode dizer que não há uma razão digna para isso, mas o fato é que, quando oferecido uma escolha entre as opções, nenhum desenvolvimento ativo é quase tão ruim quanto depreciado. Diga ndash Nanne 1 de fevereiro às 10:21 ShaquinTrifonoff: com certeza, Ele não usa declarações preparadas. Mas tampouco a DOP. Que a maioria das pessoas recomenda sobre o MySQLi. Então eu não tenho certeza de que tenha um impacto significativo aqui. O código acima (com um pouco mais de análise) é o que o DOP faz quando você prepara uma declaração por padrão. Ndash ircmaxell 4 de fevereiro às 12:44 Esta resposta está escrita para mostrar o quão trivial é ignorar o código de validação de usuário PHP mal escrito, como (e usando o quê) esses ataques funcionam e como substituir as antigas funções MySQL por um seguro Declaração preparada - e, basicamente, por que os usuários do StackOverflow (provavelmente com muitos rep) estão latindo em novos usuários fazendo perguntas para melhorar seu código. Primeiro, sinta-se livre para criar este banco de dados mysql de teste (eu chamei de preparação de minas): Com isso feito, podemos mudar para o nosso código PHP. Vamos assumir que o seguinte script é o processo de verificação de um administrador em um site (simplificado, mas funciona se você copiar e usá-lo para testes): parece bastante legítimo à primeira vista. O usuário tem que inserir um login e uma senha, bem Brilliant, não digite o seguinte: A saída é a seguinte: Super Working como esperado, agora vamos tentar o nome de usuário e a senha reais: Amazing Hi-fives em toda parte, o código corretamente verificado Um administrador. É perfeito. Bem, na verdade. Digamos que o usuário é uma pessoa pequena inteligente. Digamos que a pessoa é eu. Digite o seguinte: E a saída é: Parabéns, você acabou de me permitir entrar na seção somente de meus administradores protegidos, entrando um nome de usuário falso e uma senha falsa. Sério, se você não acredita em mim, crie o banco de dados com o código que eu forneci e execute este código PHP - que de relance REALMENTE parece verificar o nome de usuário e a senha bastante bem. Então, em resposta, é por isso que você está sendo grato. Então, vamos dar uma olhada no que deu errado e por que acabei de entrar na sua caverna super-admin-only-bat-cave. Adotei e assumi que você não fosse cuidadoso com suas entradas e simplesmente as passasse diretamente para o banco de dados. Eu construí a entrada de uma maneira que MUDARIA a consulta que você estava realmente executando. Então, o que deveria ser, e o que acabou sendo Essa é a consulta, mas quando substituímos as variáveis pelas entradas reais que usamos, obtemos o seguinte: Veja como construí minha senha para que ela primeiro Feche a citação única em torno da senha e, em seguida, introduza uma comparação completamente nova. Em seguida, apenas por segurança, adicionei outra seqüência de caracteres para que a citação única fiquem fechadas como esperado no código que originalmente possuímos. No entanto, isso não é sobre pessoas gritando com você agora, trata-se de mostrar-lhe como tornar seu código mais seguro. Ok, então, o que deu errado e como podemos corrigi-lo. Este é um ataque de injeção SQL clássico. Um dos mais simples para esse assunto. Na escala de vetores de ataque, esta é uma criança que ataca um tanque - e ganha. Então, como protegemos sua seção de administração sagrada e tornamo-la agradável e segura. A primeira coisa a fazer será parar de usar essas funções mysql realmente antigas e obsoletas. Eu sei, você seguiu um tutorial que você encontrou on-line e funciona, mas é antigo, está desatualizado e, no espaço de alguns minutos, acabei de ultrapassar sem gastar muito. Agora, você tem as melhores opções de usar mysqli ou DOP. Eu sou pessoalmente um grande fã de DOP, então vou usar DOP no restante desta resposta. Há prós e contras, mas pessoalmente acho que os profissionais superam em muito os contras. É portátil em vários mecanismos de banco de dados - se você está usando o MySQL ou Oracle ou apenas algo sangrento - apenas mudando a seqüência de conexão, possui todos os recursos sofisticados que queremos usar e é bom e limpo. Eu gosto de limpa. Agora, dê uma olhada nesse código novamente, desta vez escrito usando um objeto PDO: as principais diferenças são que não há mais funções mysql. Tudo está feito através de um objeto PDO, em segundo lugar, ele está usando uma declaração preparada. Agora, qual é uma declaração prepred que você pergunta. É uma maneira de dizer ao banco de dados antes de executar uma consulta, qual a consulta que é que vamos executar. Nesse caso, informamos o banco de dados: oi, vou executar uma declaração de seleção que deseja id, userid e passar dos usuários da tabela onde o userid é uma variável e a passagem também é uma variável .. Então, na instrução execute , Passamos o banco de dados uma matriz com todas as variáveis que agora espera. Os resultados são fantásticos. Vamos tentar essas combinações de nome de usuário e senha de antes: o usuário não foi verificado. Impressionante. Oh, eu fiquei um pouco excitada, funcionou: o cheque passou. We have a verified admin Now, lets try the data that a clever chap would enter to try to get past our little verification system: This time, we get the following: This is why you are being yelled at when posting questions - its because people can see that your code can be bypassed wihout even trying. Please, do use this question and answer to improve your code, to make it more secure and to use functions that are current. Lastly, this isnt to say that this is PERFECT code. There are many more things that you could do to improve it, use hashed passwords for example, ensure that when you store sensetive information in the database, you dont store it in plain text, have multiple levels of verification - but really, if you just change your old injection prone code to this, you will be WELL along the way to writing good code - and the fact that you have gotten this far and are still reading gives me a sense of hope that you will not only implement this type of code when writing your websites and applications, but that you might go out and research those other things I just mentioned - and more. Write the best code you can, not the most basic code that barely functions. answered Sep 18 13 at 12:28 Because (amongst other reasons) its much harder to ensure the input data is sanitized. If you use parametrized queries, as one does with PDO or mysqli you can entirely avoid the risk. As an example, some-one could use enhzflep) drop table users as a user name. The old functions will allow executing of multiple statements per query, so something like that nasty bugger can delete a whole table. If one were to use PDO of mysqli, the user-name would end-up being enhzflep) drop table users The old functions will allow executing of multiple statements per query - no, they won39t. That kind of injection is not possible with extmysql - the only way this kind of injection is possible with PHP and MySQL is when using MySQLi and the mysqlimultiquery() function. The kind injection that is possible with extmysql and unescaped strings is things like 39 OR 39139 391 to extract data from the database that was not meant to be accessible. In certain situations it is possible to inject sub queries, however it is still not possible to modify the database in this way. ndash DaveRandom Dec 30 12 at 20:58 The MySQL extension is the oldest of the three and was the original way that developers used to communicate with MySQL. This extension is now being deprecated in favor of the other two alternatives because of improvements made in newer releases of both PHP and MySQL. MySQLi is the improved extension for working with MySQL databases. It takes advantage of features that are available in newer versions of the MySQL server, exposes both a function-oriented and an object-oriented interface to the developer and a does few other nifty things. PDO offers an API that consolidates most of the functionality that was previously spread across the major database access extensions, i. e. MySQL, PostgreSQL, SQLite, MSSQL, etc. The interface exposes high-level objects for the programmer to work with database connections, queries and result sets, and low-level drivers perform communication and resource handling with the database server. A lot of discussion and work is going into PDO and its considered the appropriate method of working with databases in modern, professional code. answered Sep 2 15 at 7:20 I find the above answers really lengthy, so to summarize: The mysqli extension has a number of benefits, the key enhancements over the mysql extension being: Object-oriented interface Support for Prepared Statements Support for Multiple Statements Support for Transactions Enhanced debugging capabilities Embedded server support As explained in the above answeres, the alternatives of mysql are mysqli and pdo. API supports server-side Prepared Statements. Supported by MYSQLi and PDO API supports client-side Prepared Statements. Supported only by PDO API supports Stored Procedures. Both MySQLi and PDO API supports Multiple Statements and all MySQL 4.1 functionality - Supported by MySQLi and mostly also by PDO Both MySQLi and PDO where introduced in PHP5.0, whereas MySQL was introduced prior to PHP3.0. A point to note is MySQL is included in PHP5.x though deprecated in later versions. Delete Query error: quotCould not delete from specified tablesquot I am attempting to archive and delete records from a timelog table using selected start Startdate and end date EndDate paramaters which are fields contained in a separate StartEndDate table. Criei uma consulta de arquivamento e uma consulta de exclusão. A consulta de arquivo funciona bem, mas quando eu executo a consulta de exclusão, recebo uma mensagem: quotCode não excluir das tabelas especificadas. O código do arquivo e deletar vba é o seguinte: Dados do arquivo stDocName quotArchivehoursquot DoCmd. OpenQuery stDocName, acNormal, acEdit O SQL é o seguinte : INSERT INTO ArchvedTimeLog SELECT tblTimeLog. FROM tblTimeLog, StartEndDates WHERE ((((tblTimeLog. LogDate) gtStartEndDates. StartDate e (tblTimeLog. LogDate) ltStartEndDates. EndDate)) A ação do arquivo funciona bem. Purge Active File stDocName quotDeleteArchivedHoursquot DoCmd. OpenQuery stDocName, acNormal, acEdit DELETE DISTINCTROW tblTimeLog., TblTimeLog. LogDate FROM tblTimeLog, StartEndDates WHERE (((tblTimeLog. LogDate) gtStartDate e (tblTimeLog. LogDate) ltEndDate)) A tabela VIEW desta consulta parece perfeito. No entanto, após a execução, recebo a mensagem: quot Não poderia excluir das tabelas especificadas. Qualquer ajuda seria muito apreciada. MBA Re: Delete Query error: quotCode não ser excluído das tabelas especificadas DISTINCTROW é usado para suprimir duplicatas. Se você precisar usar isso, sua consulta claramente não oferece uma chave candidata adequada. Deletes become problematic once joins get involved. Costumo fazer esse tipo de exclusão em duas etapas. Atualize um dos campos com um valor fora do escopo, em seguida, exclua com base nesse sinalizador. Muitas vezes, fazemos perguntas sobre problemas com o arquivamento de novos desenvolvedores que pensam ter uma grande mesa quando chegar a algumas dezenas de milhares de registros. Quando uma tabela passa por um milhão de registros, está começando a ficar substancial. Moreover the dangerous process of moving records to another table is often under estimated and they assume the copy worked and nonchalently progress to the delete. Na maioria dos casos, um simples quotdeletedquot flag aplicado aos registros é uma opção mais simples e segura. With an index on the deleted field the performance is very similar. BTW A exibição de folha de dados de qualquer consulta é um SELECT, portanto, não funciona necessariamente como uma consulta de ação. Originally Posted by Galaxiom DISTINCTROW is used to supress duplicates. Se você precisar usar isso, sua consulta claramente não oferece uma chave candidata adequada. Deletes become problematic once joins get involved. Costumo fazer esse tipo de exclusão em duas etapas. Atualize um dos campos com um valor fora do escopo, em seguida, exclua com base nesse sinalizador. Muitas vezes, fazemos perguntas sobre problemas com o arquivamento de novos desenvolvedores que pensam ter uma grande mesa quando chegar a algumas dezenas de milhares de registros. Quando uma tabela passa por um milhão de registros, está começando a ficar substancial. Moreover the dangerous process of moving records to another table is often under estimated and they assume the copy worked and nonchalently progress to the delete. Na maioria dos casos, um simples quotdeletedquot flag aplicado aos registros é uma opção mais simples e segura. With an index on the deleted field the performance is very similar. BTW A exibição de folha de dados de qualquer consulta é um SELECT, portanto, não funciona necessariamente como uma consulta de ação. Muito obrigado por resolver um grande problema para mim. Não estou arquivando, mas tentando eliminar alguns registros indesejados em um conjunto de dados, e sua técnica de dois passos funcionou perfeitamente
Comments
Post a Comment