-
Total de itens
1865 -
Registro em
-
Última visita
-
Dias vencidos
32
Tudo que Matheus Tavares postou
-
Kkkk imagina :P É um incremento. Cada vez que rodamos essa linha, a variável vai aumentar seu valor em 1. Veja no manual: https://www.php.net/manual/pt_BR/language.operators.increment.php Há uma sutil diferença entre ++$var (pré-incremento) e $var++ (pós-incremento). <?php $i = 1; echo ++$i + 10;// Resultado: 12 echo "\n"; echo $i;// 2 echo "\n\n"; $i = 1; echo $i++ + 10;// Resultado: 11 echo "\n"; echo $i;// 2 No pré-incremento, primeiro faz-se a soma, depois as demais operações. No pós-incremento, primeiro as operações são executadas, depois disso a soma. Quando utilizei apenas: ++$cotacoes_utilizadas; Ele apenas somou 1. Não há outras operações, não faria nenhuma diferença utilizar o pós-incremento: $cotacoes_utilizadas++; Que ainda seria o mesmo que: $cotacoes_utilizadas += 1; Ou ainda: $cotacoes_utilizadas = $cotacoes_utilizadas + 1; Tudo a mesma coisa :)
-
Oi @biakelly, ainda não estou 100%, mas estou melhorando bem rápido. Então, a minha resposta anterior estava se referindo apenas à união de strings com arrays baseado na sua tentativa, mas você disse algo que me chamou atenção: Talvez essa (a técnica que estava discutindo) não seja a forma correta de fazer o que você precisa. Você precisa ver bem a documentação do Telegram e alguns exemplos sobre esse recurso. Veja: https://stackoverflow.com/questions/45894518/how-to-create-inline-buttons-in-php-bot-telegram https://stackoverflow.com/questions/60529715/telegram-inline-keyboards-php https://stackoverflow.com/questions/41709382/telegram-bot-inline-keyboard-not-displaying-php https://github.com/php-telegram-bot/inline-keyboard-pagination Observe que nesses exemplos eles usam um padrão diferente do que mencionei, além de utilizarem json_encode e não urlencode. Talvez esse tutorial possa lhe ajudar nesse sentido: https://luizmarcus.com/php/utilizando-inline-keyboard-em-um-bot-para-o-telegram/
-
[RESOLVIDO] Formatar número inteiro para decimal para inserir no BD
Matheus Tavares respondeu ao tópico de manolegal em PHP
Olá amigo, tudo bem? Seu primeiro número está, vamos supor, em centavos e você quer armazenar em reais. O number_format não vai mudar a unidade, ele vai apenas formatar a string do número para exibir com outra notação. Você precisa, então, dividir esse número por 100. Exemplo: $numero = 2961966;// centavos $numero /= 100; echo $numero;// 29619.66 (reais)- 2 respostas
-
- decimal
- postgresql
-
(e mais 1 )
Tags:
-
Olá @biakelly, você está quase lá... 1 - Precisa retirar as vírgulas, os pontos representam os decimais e precisam estar na conta. Portanto: // Primeiro retiramos a vírgula com o str_replace. // O (float) força o tipo de variável a ser um float, ou seja, número com decimais. // Se price fosse originalmente '424,123.123', isso significa que era uma string // com vírgulas representando os milhares. $price = (float)str_replace( ',', '', $price);// Agora passaria a ser 424123.123 Você faz o mesmo com a outra variável, multiplica uma pela outra e aplica o number_format. Não precisa da divisão por 10000000000... O único problema é que como são números muito grandes, talvez você precise de uma biblioteca para lidar com a precisão dessa matemática, como fiz naquele exemplo da soma da API, para você, sabe? Nesse caso a matemática seria algo assim: <?php $precototal = '0.002822102460892938'; $totalemitido = '10,454,760.506412'; $precototal = str_replace( ',', '', $precototal ); $totalemitido = str_replace( ',', '', $totalemitido ); echo $precototal . "\n"; echo $totalemitido . "\n"; echo bcmul( $precototal, $totalemitido, 10 ); Resultado: 0.002822102460892938 10454760.506412 29504.4053531916 E agora vem o number_format para colocar esse produto no padrão brasileiro, ou outro desejado, mas o resultado do cálculo é essa terceira linha.
-
Olá @biakelly. Você poderia fazer algo assim: $cotacao = 0; $cotacoes_utilizadas = 0; if ( $dolar_google ) { ++$cotacoes_utilizadas; $cotacao += $dolar_google; } if ( $dolar_uol ) { ++$cotacoes_utilizadas; $cotacao += $dolar_uol; } $cotacao /= $cotacoes_utilizadas;// (divisão da soma das cotações pela qtd. utilizada). Ex: 10/2 ou 5/1 Você também pode utilizar cron jobs e armazenar a cotação em cache, sempre mantendo-a a mais correta possível sem precisar fazer essa requisições em cada consulta.
-
Olá @Marcos Vinícius. Que bom que você já resolveu, mas respondendo sua questão original: Você poderia ter, dentro do while, feito a soma da variável, assim: $soma = 0; while($dados = mysqli_fetch_array($resultado)){ $valor = $dados["valor"]; $soma += $valor;// se $valor for a variável que você gostaria de obter o somatório $dias = $dados["dias"]; $perc = $valor/$dias; $arr=array("$perc"); } echo $soma; O array_sum, dentro do seu contexto, faria um segundo loop, que seria muito mais lento. Além disso ele soma apenas os valores dentro de um array, como nesse exemplo: $array = [ 10, 20, 30, 40, 50 ]; echo array_sum( $array );// 150 Mas não era seu caso, pois seu array era mais complexo. Ao menos que você fizesse o seguinte (isso iria adicionar ainda mais loops, ou seja, não é muito recomendadável, mas seria uma opção fácil): <?php $array = [ [ 'id' => 1, 'valor' => 10, 'nome' => 'foo' ], [ 'id' => 2, 'valor' => 20, 'nome' => 'bar' ], [ 'id' => 3, 'valor' => 30, 'nome' => 'baz' ], ]; $valores = array_column( $array, 'valor' ); /** * $valores agora possui: * Array * ( * [0] => 10 * [1] => 20 * [2] => 30 * ) */ echo array_sum( $valores );// 60
-
Olá @biakelly, tudo bem? Estava um pouco indisposto nos últimos dias e não pude dar atenção à sua dúvida antes, mas vamos lá: Pelo que entendi as linhas estão invertidas, certo? $keyboard vem antes do if, mas na hora de colar você trocou a ordem, é isso? Pois do contrário não faria muito sentido. Assumindo que keyboard venha antes, e portanto é um array, quando você joga ele no file_get_contents você está unindo uma string com um array, o que não pode ser feito. String é apenas texto, array é um conjunto de dados de diferentes tipos. <?php $keyboard = ['inline_keyboard' => [[ ['Alunos', 'url' => 'https://www.link.com/admin/alunos/'], ['notas', 'url' => 'https://www.link.com/admin/notas/'] ]]]; echo "Concatenação de string com array: {$keyboard}"; O exemplo acima retorna isso: Concatenação de string com array: Array (e uma mensagem de erro, pois essa concatenação está incorreta, mas o PHP se forçou a tentar executá-la mesmo assim). Você precisa portanto formatar esse array para uma string. Mas antes vamos fazer uns pequenos ajustes na construção do array em si: $keyboard = ['inline_keyboard' => [[// aqui está criando 2 arrays. Apenas 1 seria suficiente ['Alunos', 'url' => 'https://www.link.com/admin/alunos/'], ['notas', 'url' => 'https://www.link.com/admin/notas/'] ]]]; //Portanto: $keyboard = ['inline_keyboard' => [ ['Alunos', 'url' => 'https://www.link.com/admin/alunos/'], ['notas', 'url' => 'https://www.link.com/admin/notas/'] ]]; // Também poderíamos adicionar uma chave para 'alunos' e 'notas', assim como as URLs: $keyboard = ['inline_keyboard' => [ [ 'name' => 'Alunos', 'url' => 'https://www.link.com/admin/alunos/'], [ 'name' => 'notas', 'url' => 'https://www.link.com/admin/notas/'] ]];// agora sim O próximo passo seria formatar a string. Isso poderia ser feito com um foreach por exemplo. Veja: $string = ''; foreach ( $keyboard[ 'inline_keyboard' ] as $values ) { $name = $values[ 'name' ]; $url = $values[ 'url' ]; $string .= "{$name}: {$url}\n"; } echo $string; Resultado: Alunos: https://www.link.com/admin/alunos/ notas: https://www.link.com/admin/notas/ Por fim, você só precisaria enviar essa string na URL, mas você não pode simplesmente inserir essa string, pois ela contém caracteres que iriam deformar a requisição do file_get_contents. Você precisa utilizar urlencode. Assim: file_get_contents($path . "/sendmessage?chat_id=" . $chatId . '&text=' . urlencode( $string )); O urlencode converte caracteres como espaços, quebras de linha, barras, em suas representações amigáveis para o tráfego na URL :D
-
[Resolvido] Somar dados recuperados de uma API
Matheus Tavares respondeu ao tópico de biakelly em PHP
Olá @biakelly Show demais! =D Sim, recomendo que você dê atenção a esse assunto, pois é realmente muito útil e não é tão difícil, mas que bom que conseguiu resolver com arquivos. Vou marcar aqui como resolvido. Até mais :) -
Certo, entendi. Acredito que uma forma mais fácil de resolver isso seja com GROUP e COUNT através do seu banco de dados, se você estiver trabalhando com MariaDb/Mysql, PostgreSQL, por exemplo, mas desconsiderando essa opção, no PHP você poderia fazer assim: 1 - Pegue os dados da sua fonte. Você deve ter um array parecido com esse: $interacoes = [ [ 'funcionario' => 'Joao', 'empresa' => 'Google', ], [ 'funcionario' => 'Maria', 'empresa' => 'Face', ], [ 'funcionario' => 'Joao', 'empresa' => 'Padaria', ], [ 'funcionario' => 'Alfredo', 'empresa' => 'Google', ], [ 'funcionario' => 'Gilberto', 'empresa' => 'Google', ], [ 'funcionario' => 'Gilberto', 'empresa' => 'Google', ], [ 'funcionario' => 'Maria', 'empresa' => 'Face', ], [ 'funcionario' => 'Joao', 'empresa' => 'Google', ], [ 'funcionario' => 'Gilberto', 'empresa' => 'Google', ], [ 'funcionario' => 'Joao', 'empresa' => 'Google', ], ]; Daí se eu entendi direito, você quer contar as ocorrências de Funcionário X Empresa. Existem diversas formas de se fazer isso. Com orientação a objetos seria com certeza a mais intuitiva e menos frágil a confusões, outras formas seriam utilizando array_combine, array_values, array_keys, array_column e array_unique. Todas essas funções lhe poderiam ser úteis, e por isso reocomendo a leitura: https://www.php.net/manual/pt_BR/function.array-combine.php https://www.php.net/manual/pt_BR/function.array-column.php Com foreach manualmente acaba ficando mais performático, pois as funções que citei acima são basicamente foreach nativos, ou seja, você acabaria fazendo diversos loops para chegar à solução. Eu particularmente, apesar de gostar muito dessas ferramentas, tendo a evitá-las por essa razão. Bom, o próximo passo seria agrupar os usuários, as empresas e suas contagens, isso você pode fazer assim: $contadorInteracoes = []; foreach( $interacoes as $interacao ) { $funcionario = $interacao[ 'funcionario' ]; $empresa = $interacao[ 'empresa' ]; if ( !isset( $contadorInteracoes[ $funcionario ] ) ) $contadorInteracoes[ $funcionario ] = []; if ( !isset( $contadorInteracoes[ $funcionario ][ $empresa ] ) ) $contadorInteracoes[ $funcionario ][ $empresa ] = 0; ++$contadorInteracoes[ $funcionario ][ $empresa ]; } print_r( $contadorInteracoes ); Mas esse bando de isset está incomodando, né? Sem eles vamos ficar recebendo erros, pois não podemos atribuir uma chave enraizada de um array se ela não existe. Por sorte temos o recurso de atribuição por referência, que pode simplificar isso pra gente: $contadorInteracoes = []; foreach( $interacoes as $interacao ) { $funcionario = $interacao[ 'funcionario' ]; $empresa = $interacao[ 'empresa' ]; $contador =& $contadorInteracoes[ $funcionario ][ $empresa ];// atribuição por referência $contadorInteracoes[ $funcionario ][ $empresa ] = ++$contador; } print_r( $contadorInteracoes ); Veja mais detalhes sobre esse operador: https://www.php.net/manual/pt_BR/language.references.whatdo.php#language.references.whatdo.assign Essa técnica me permitiu a definição enraizada dos valores sem me preocupar com a existência deles, do contrário o código exigiria alguns operadores null coalescing, operadores Elvis, ifs, isset, empty ou algo assim, como no primeiro exemplo. Se ficar com dúvidas em relação a isso, eu posso me aprofundar um pouco mais. A saída desse exemplo seria essa: Array ( [Joao] => Array ( [Google] => 3 [Padaria] => 1 ) [Maria] => Array ( [Face] => 2 ) [Alfredo] => Array ( [Google] => 1 ) [Gilberto] => Array ( [Google] => 3 ) ) Espero que seja isso que você estava precisando :)
-
Help - Como pegar array de um formulário e inserir no banco
Matheus Tavares respondeu ao tópico de unset em PHP
Olá amigo, tudo bem? Minha resposta faz exatamente isso. Veja: Estrutura do banco: Consulta (inserção múltipla): Como a tabela ficou após a consulta: Você precisa apenas adicionar as outras colunas na string da query. No meu exemplo inicial eu não sabia a estrutura das suas colunas, então fiz utilizando apenas a cidade_id, já nas fotos utilizei mais colunas, conforme seu código. Basta adaptar a primeira linha com $sql :) -
Olá amigo, tudo bem? Seja bem-vindo. Gostaria de ajudar você, mas infelizmente não entendi sua dúvida =/ Se puder dar alguns exemplos e postar um trecho relevante do seu código, seria melhor.
-
Olá @Jack Oliveira, tudo bem? Vou lhe apresentar uma função bem legal do PHP, a parse_url: <?php $url1 = 'https://www.facebook.com/gilberto.gil'; $url2 = 'https://instagram.com/gilberto.gil/posts'; $url3 = 'https://twitter.com/gilberto.gil?parametro_qualquer=123'; $parsed_url1 = parse_url( $url1 ); $parsed_url2 = parse_url( $url2 ); $parsed_url3 = parse_url( $url3 ); print_r( $parsed_url1 ); print_r( $parsed_url2 ); print_r( $parsed_url3 ); Saída: Array ( [scheme] => https [host] => www.facebook.com [path] => /gilberto.gil ) Array ( [scheme] => https [host] => instagram.com [path] => /gilberto.gil/posts ) Array ( [scheme] => https [host] => twitter.com [path] => /gilberto.gil [query] => parametro_qualquer=123 ) Massa né? Bom, assim facilita bastante pra pegar o usuário. Basta pegar o path, retirar a primeira barra e cortar a partir da próxima barra. Algo assim: <?php function getSocialUser( $uri ) { $parsed = parse_url( $uri ); $path = $parsed[ 'path' ];// Usuário, mas com caracteres que devem ser filtrados $host = str_replace( 'www.', '', $parsed[ 'host' ] );// Retiramos o 'www.' $host_name = explode( '.', $host )[ 0 ];// Separamos por '.' e pegamos a primeira parte $allowed_hosts = [ 'twitter', 'facebook', 'instagram' ];// Hosts permitidos if ( !in_array( $host_name, $allowed_hosts ) ) return false;// Se não estiver entre os permitidos, retorne falso (ou exception) return strtok( ltrim( $path, '/' ), '/' );// retorna o usuário filtrado } $url1 = 'https://www.facebook.com/gilberto.gil'; $url2 = 'http://instagram.com/gilberto.gil/posts'; $url3 = 'https://twitter.com/gilberto.gil?parametro_qualquer=123'; $url4 = 'https://google.com/gilberto.gil?parametro_qualquer=123'; echo ( getSocialUser( $url1 ) ?: 'Inválido' ) . "\n"; echo ( getSocialUser( $url2 ) ?: 'Inválido' ) . "\n"; echo ( getSocialUser( $url3 ) ?: 'Inválido' ) . "\n"; echo ( getSocialUser( $url4 ) ?: 'Inválido' ) . "\n"; Saída: gilberto.gil gilberto.gil gilberto.gil Inválido Observe que os testes contemplam exemplos com http, https, parâmetros arbitrários, url com caminho excedente, com www e sem www. Veja esse código rodando: https://3v4l.org/Uib0j
-
Bom, mas você não pode ser tão leigo, só precisa de um empurrãozinho, afinal de contas seu sistema já está funcionando e selecionando os usuários, atribuindo seus dados em sessões, certo? Ao menos que eu tenha entendido errado. Bom, nesse caso, poste o código que faz o login do usuário nesse momento. É basicamente a partir de modificações nele que podemos fazer o que você quer, e nisso nós podemos ajudar você.
-
Olá @Xicara, tudo bem? Você pode sim fazer como você sugere. Isso seria feito através de cron jobs, porém não seria a melhor solução. O ideal é você criar uma tabela adicional chamada assinaturas, vips, planos, ou algo assim. Nessa tabela você teria: #id, &id_usuario, tipo_plano (1 a 5), inicio_plano, fim_plano Daí você relaciona o usuário com seu último plano e verifica se está dentro de início_plano e fim_plano, que são colunas representando o intervalo de vigência dos planos. Dessa forma você não precisa modificar nada no seu banco, apenas validar a assinatura do usuário com IFs ou outras operações simples, entende?
-
Somar valores sorteados por um dado
Matheus Tavares respondeu ao pergunta de Felper em Perguntas e respostas rápidas
Você gostaria de primeiro sortear um número de 1 a 6 (um dado) e depois somar o valor ao somadado, é isso? Bom, se eu tiver entendido agora, seria assim: // Veja mais sobre Math.random: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Math/random function jogaDado() { return parseInt( Math.random() * ( 6 - 1 ) + 1 ); } let soma_dado = 0; let valor_sorteado = 0; valor_sorteado = jogaDado();// 1 a 6 aleatório soma_dado += valor_sorteado;// soma_dado vai assumir o valor do dado valor_sorteado = jogaDado();// jogamos novamente e pegamos outro valor soma_dado += valor_sorteado;// agora soma_dado vai somar o valor anterior com o último dado -
Tente exibir a string do seu file_get_contents para ver se está correta: echo $path . "/sendmessage?chat_id=" . $chatId . "&text={$text}"; Com esse echo você vai ver exatamente o que está sendo enviado para dentro do file_get_contents e assim verificar se está coerente com o que você desejava. Ao meu ver é o principal ponto do seu código que poderia apresentar problemas (caso alguma variável esteja incorreta, ela impactaria em toda a função). Se não encontrar nada de errado, faça o mesmo com as demais variáveis. Utilize print_r ou var_dump nelas. Exemplo: print_r( $update );
-
[Resolvido] Somar dados recuperados de uma API
Matheus Tavares respondeu ao tópico de biakelly em PHP
Olá @biakelly :) É muito gratificante ler isso! Fico muito feliz :D É um prazer ajudar. Não é sempre que consigo estar mais ativo no fórum, mas é um hobby que tenho há alguns anos. A maior parte do meu conhecimento vem justamente disso. Quando ajudo alguém, constantemente me pego consultando um manual, uma referência, pensando em soluções, e isso reforça o meu próprio aprendizado. Não sou professor, mas presto consultorias. Também pretendo montar um blog futuramente, mas antes tenho outros projetos, então o blog vai demorar um pouquinho ainda. Novamente, muito obrigado :) Sim, seria uma operação de subtração, que você deve fazer com bcsub para manter o foco na precisão da apresentação dos cálculos. Veja: https://www.php.net/manual/en/function.bcsub.php Você precisa descobrir o endpoint (endereço de requisição) para coletar o saldo dessa carteira. Daí você usa o Guzzle, extrai essa informação, depois usa o bcsub que disse acima para subtrair o valor que calculamos por esse saldo. Você sabe o endpoint? Sua ideia é perfeitamente razoável, e na verdade uma sugestão minha, mas eu particularmente não faria em um arquivo, pois operações ao disco são sempre mais lentas do que em memória, então: 1 - Memória, com APCu (recomendado) ou Memcached. Veja: https://www.php.net/manual/en/book.apcu.php https://www.php.net/manual/en/book.memcached.php O problema é que para ambas você precisa da instalação do módulo. No xampp por exemplo é assim: https://stackoverflow.com/questions/24448261/how-to-install-apcu-in-windows https://www.phpflow.com/php/how-to-install-apc-cache-on-wamp-and-xampp/ Esse é o método mais recomendado, pois é o mais performático, mas a necessidade da instalação (tanto na sua máquina de desenvolvimento quanto no servidor, se já não tiver instalado) pode ser um problema. 2 - Banco de dados. Qualquer coisa rápida e prática. SQLite, mongo ou MariaDb / Mysql mesmo. 3 - Por fim, o método mais lento e menos confiável, mas definitivamente o mais simples: arquivo. Para salvar e pegar o valor depois em arquivo você só precisa de 2 funções: file_put_contents e file_get_contents. Daí você faz exatamente o que você disse: Cronjob rodando a cada X minutos, se preocupando em não permitir a execução simultanea e na hora de exibir você consulta da memória, banco ou arquivo. Esse processo todo demonstra um sistema de cache. Amplamente utilizado em sites com muita visitação, como portais de notícias, por ex. Legal. Que bom que funcionou aí. Depois de implementar o cache e a subtração vai ficar 100% :D -
Não estou conseguindo mudar a imagem de acordo com a hora apresentada no if/else.
Matheus Tavares respondeu ao tópico de stefanyprs em Javascript
Olá @stefanyprs, tudo bem? Seu código está bem perto de funcionar como você gostaria, mas observe as seguintes linhas: var msg = window.document.getElementById('msg') var img = window.document.getElementsByClassName('imagem'); Percebe que a primeira função está no singular? getElementById => Pegar elemento pelo id. getElementsByClassName => Pegar elementos pelo nome de classe. Isso significa que o retorno deve ser um array, ou seja, um conjunto de elementos, e não apenas 1, como na primeira função. Para evitar lidar com esse problema, o ideal é você adicionar um id na imagem e selecioná-la através de seu id, como em msg. Outra forma de fazer isso é acessando o primeiro elemento do conjunto (apenas por se tratar do único elemento com classe imagem). Isso você faz assim: var img = window.document.getElementsByClassName('imagem')[ 0 ]; Se tivesse mais elementos, você acessaria alterando o índice dentro dos colchetes. Outro detalhe é que não precisa do window.document. É uma redundância para apenas document. Então poderia ser escrito assim também: var msg = document.getElementById('msg') var img = document.getElementsByClassName('imagem')[ 0 ]; Veja em funcionamento: https://jsfiddle.net/Lvpc0wfk/1/ -
[Resolvido] Erro ao enviar form com PHP 8.0.6
Matheus Tavares respondeu ao tópico de merovingio em PHP
Olá @merovingio, tudo bem? Seja bem-vindo! Que bom que já conseguiu resolver o problema, mas vou complementar um pouco: 1 - Veja a mensagem de erro: Fatal error: Uncaught Error: Attempt to assign property "name" on null O que ele nos diz é que houve um erro fatal ao tentar atribuir "name" em null. Quem seria name e quem seria null? Name seria o valor (string) que sua $key está carregando nessa iteração e null seria a chave get ou post, que nesse caso não existe, pois não foi declarada/instanciada. Ou seja: $obj->get->$key, onde get era para ser um objeto, mas como você ainda não havia definido ele, ele era null, ou vazio/nulo. Resumindo: <?php $x = new \stdClass; $x->get->teste = 1; print_r( $x );// fatal error, pois get não existe Solução: <?php $x = new \stdClass; $x->get = new \stdClass; $x->get->teste = 1; print_r( $x );// agora sim É claro que o que eu disse para get também vale para post. No caso as linhas de atribuição deveriam estar fora do seu foreach. A forma que você encontrou para solucionar é mais elegante que utilizando os foreach, mas apenas até o momento em que você não manipula ou consulta essas variáveis (você está apenas fazendo uma cópia). E por fim, sugiro que não utilize o operador de supressão de erros, @. É uma má prática, pois os nossos erros nos ajudam a aprender. Devemos conhecê-los para não repeti-los no futuro :) error_reporting( E_ALL ); para exibir os erros em desenvolvimento, sempre. error_reporting( 0 ); para suprimir TODOS os erros aos nossos usuários, quando a aplicação estiver no ar. Esse é o comportamento ideal. -
Help - Como pegar array de um formulário e inserir no banco
Matheus Tavares respondeu ao tópico de unset em PHP
E um adendo... se você está trabalhando com inteiros / ids, essa sanitização está insegura. Utilize FILTER_SANITIZE_NUMBER_INT, assim removendo caracteres que não sejam inteiros para você. Veja: https://www.php.net/manual/pt_BR/filter.constants.php -
Help - Como pegar array de um formulário e inserir no banco
Matheus Tavares respondeu ao tópico de unset em PHP
Olá amigo. Você precisa apenas ter uma tabela que armazena as cidades selecionadas. Vamos chamar de cidades_selecionadas, que possui um #id auto_increment e o id (provavelmente chave estrangeira) representando a &cidade. Bom, agora você prepara a consulta, de acordo com os dados que você já possui: Sintaxe da inserção múltipla no Mysql: INSERT INTO `table` ( `col1`, `col2` ) VALUES ( 1, 'teste' ), ( 2, 'foo' ), ( 3, 'bar' ); Sua inserção portanto seria algo assim: <?php $ids = [ 2, 4, 10, 130 ]; if ( sizeof( $ids ) > 0 ) { $sql = 'INSERT INTO `cidades_selecionadas` (`cidade`) VALUES ('; $sql .= implode( '), (', $ids ); $sql .= ')'; echo $sql; } Saída (sua consulta): INSERT INTO `cidades_selecionadas` (`cidade`) VALUES (2), (4), (10), (130) -
Olá @biakelly. Então... precisava saber qual o erro que está dando para ver o que pode estar acontecendo, mas o que consigo ver de antemão é que está faltando um carectere de aspas aqui: define( 'ROUTES', [ 'prices', symbol', // <---- antes de symbol devia ter um ' ] ); Se não for esse problema, vou precisar de mais informações pra poder ajudar você :)
-
[Resolvido] Consulta Mysqli não retorna resultados
Matheus Tavares respondeu ao tópico de Marcos Vinícius em MySQL
Show, @Marcos Vinícius. Fico feliz que tenha solucionado a questão. :) -
[Resolvido] Somar dados recuperados de uma API
Matheus Tavares respondeu ao tópico de biakelly em PHP
Oi @biakelly :D Algumas APIs oferecem uma seção à parte dos resultados onde são expostas metainformações, ou seja, informações alheias aos resultados, mas relacionadas à resposta da requisição em si. Isso é comum quando trabalhamos com APIs grandes como do Twitter, Facebook, Google, etc. E por que estou falando sobre isso? Bom, porque na minha afobação ao tentar interpretar os resultados eu acabei ignorando uma coisa que estava na minha cara: a resposta da requisição DIZ exatamente o link que você deve chamar para obter o próximo conjunto de registros, ou seja, a próxima página. Veja essa print, que ilustra o que estou dizendo: Bom. Agora vamos à parte divertida: Código! 1 - O primeiro passo é instalar o Guzzle. Ele diminuirá drasticamente a quantidade de linhas de código que precisamos programar. Isso pode ser feito via Composer (recomendadíssimo) ou apenas baixando o zip do repositório oficial: Repositório: https://github.com/guzzle/guzzle Zip: https://github.com/guzzle/guzzle/archive/refs/heads/master.zip Instruções no site oficial: https://docs.guzzlephp.org/en/stable/overview.html#installation 2 - Se o Guzzle estiver instalado e tiver sido inicializado corretamente, primeiro definimos as configurações padrões das nossas futuras requisições: $client = new GuzzleHttp\Client([ 'base_uri' => 'https://api.trongrid.io/v1/',// URL base para as requisições relativas 'timeout' => 10.0, ]); 3 - Como vamos repetir o processo de requisitar na API, vamos encapsular essa lógica em uma função: // Função anônima para fazer uso do "use", que nos dá acesso ao construtor de requisição do Guzzle $requestPage = function ( $uri ) use ( $client ) { $response = $client->get( $uri );// Fazemos a requisição $content = $response->getBody()->getContents();// Selecionamos o conteúdo da resposta // Retornamos o conteúdo em formato de objeto (sem o decode, $content seria apenas uma string) return json_decode( $content ); }; 4 - Show. Agora vamos fazer uma função que será responsável pelo somatório preciso desses números gigantes que vamos lidar: function getTokensSum( $tokens ) { $sum = 0; foreach ( $tokens as $token ) $sum = bcadd( $sum, current( $token ) );// bcadd é uma soma (+), mas com maior foco na precisão return $sum; }; 5 - Vamos agora definir algumas variáveis iniciais: $i = 0;// Quantidade de requisições feitas. Apenas informativo $total = 0;// Nosso somatório começa em 0 $max_requests = 100000;// Garantia de que não vamos fazer requsições infinitas $rest_time = 500000;// 0,5 seg (500.000 usec) de descanso entre cada requisição para respeitar a API $first_page = 'TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq'; $uri = "contracts/{$first_page}/tokens?only_confirmed=true&only_unconfirmed=true&order_by=balance,desc&limit=200"; 6 - Aqui vem o loop. Rodamos sequencialmente todas as requisições de acordo com o meta da próxima página e executamos a função do somatório para acumular o total, que é o nosso objetivo: do { ++$i;// Incrementamos a quantidade de requisições $body = $requestPage( $uri ); $tokens = $body->data;// aqui são os itens em forma de objetos (instâncias de \stdClass) $total = bcadd( $total, getTokensSum( $tokens ) );// 0 + 123123123 + 456456456... $meta = $body->meta; printf( "Página: %d. Somatório: %s\n", $i, $total ); if ( isset( $meta->links->next ) ) $uri = $meta->links->next;// Definimos a URI da próxima página else { $uri = false;// Como não vai mais haver URI (uri=false), o while vai ser encerrado em seguida... echo 'Encerrado :)'; } usleep( $rest_time ); } while( --$max_requests >= 0 && $uri );// Pare quando não houver próx. pág. ou alcançar o limite de requisições 7 - ... é isso. Vamos ver a saída: [...] Página: 321. Somatório: 999989999998544365675 Página: 322. Somatório: 999989999998609511160 Página: 323. Somatório: 999989999998654020937 Página: 324. Somatório: 999989999998688034206 Página: 325. Somatório: 999989999998708163201 Página: 326. Somatório: 999989999998722618884 Página: 327. Somatório: 999989999998731141588 Página: 328. Somatório: 999989999998739362169 Página: 329. Somatório: 999989999998744533851 Página: 330. Somatório: 999989999998746466850 Página: 331. Somatório: 999989999998747035083 Página: 332. Somatório: 999989999998747149932 Página: 333. Somatório: 999989999998747159904 Página: 334. Somatório: 999989999998747161478 Encerrado :) Esse é o número que você queria: 999989999998747161478. Levou 5 minutos e 2 segundos para executar esse script aqui, mas lembre-se de que limitei uma requisição a cada 0,5 segundo. Você pode personalizar esse valor de acordo com as regras da API, mas nunca deixe zerado: https://developers.tron.network/reference#rate-limits Aqui está o código completo. Qualquer dúvida é só postar :) <?php require_once 'vendor/autoload.php';// inicializa o Guzzle através do Composer $client = new GuzzleHttp\Client([ 'base_uri' => 'https://api.trongrid.io/v1/',// URL base para as requisições relativas 'timeout' => 10.0, ]); // Função anônima para fazer uso do "use", que nos dá acesso ao construtor de requisição do Guzzle $requestPage = function ( $uri ) use ( $client ) { $response = $client->get( $uri );// Fazemos a requisição $content = $response->getBody()->getContents();// Selecionamos o conteúdo da resposta // Retornamos o conteúdo em formato de objeto (sem o decode, $content seria apenas uma string) return json_decode( $content ); }; function getTokensSum( $tokens ) { $sum = 0; foreach ( $tokens as $token ) $sum = bcadd( $sum, current( $token ) );// bcadd é uma soma (+), mas com maior foco na precisão return $sum; }; $i = 0;// Quantidade de requisições feitas. Apenas informativo $total = 0;// Nosso somatório começa em 0 $max_requests = 100000;// Garantia de que não vamos fazer requsições infinitas $rest_time = 500000;// 0,5 seg (500.000 usec) de descanso entre cada requisição para respeitar a API $first_page = 'TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq'; $uri = "contracts/{$first_page}/tokens?only_confirmed=true&only_unconfirmed=true&order_by=balance,desc&limit=200"; do { ++$i;// Incrementamos a quantidade de requisições $body = $requestPage( $uri ); $tokens = $body->data;// aqui são os itens em forma de objetos (instâncias de \stdClass) $total = bcadd( $total, getTokensSum( $tokens ) );// 0 + 123123123 + 456456456... $meta = $body->meta; printf( "Página: %d. Somatório: %s\n", $i, $total ); if ( isset( $meta->links->next ) ) $uri = $meta->links->next;// Definimos a URI da próxima página else { $uri = false;// Como não vai mais haver URI (uri=false), o while vai ser encerrado em seguida... echo 'Encerrado :)'; } usleep( $rest_time ); } while( --$max_requests >= 0 && $uri );// Pare quando não houver próx. pág. ou alcançar o limite de requisições // O total estará armazenado em $total. Agora é só usar :) -
Humm sim, entendi a questão. Tinha notado esse ponto, mas imaginei que fosse um problema na formatação da tabela, afinal de contas não via muito sentido de o índice 90, como no seu exemplo, representar simultaneamente moderado e severo. Vou lhe propor uma solução: 1 - Observe que na tabela não há nenhum índice menor do que 72 (com ausência de estresse). Isso significa que se a formula retorna 71, você não precisa consultar a tabela. Observe ainda que nenhum 72 se faz presente nos grupos de moderado / severo / crítico, apenas em ameno. Note ainda que 96 é outro número que está presente somente em um grupo: dessa vez o dos severos. Existe uma tendência de que os números estejam corretamente agrupados somente em um rótulo. Esses números você ignora. Todos os outros, vamos chamar de ambíguos. É este segundo grupo de valores que você deve catalogar em um array. Exemplo, novamente no PHP, que é onde me sinto confortável: const AMBIGUOUS = [ // Em 25 graus a 100% de UR temos um moderado: 250 => [ 100 => Stress::MODERATE ], // Já na linha dos 26,1 graus temos 3 ambíguos: 261 => [ 80 => Stress::SOFT, 90 => Stress::MODERATE, 100 => Stress::MODERATE ], // ... 433 => [ 30 => Stress::SEVERE ], 461 => [ 20 => Stress::MODERATE ], ]; No caso, Stress::SOFT, Stress::MODERATE e os demais são constantes que representam índices (0,1,2,3...). No PHP o que está dentro de colchetes é um array. O mesmo que new Array() em outras linguagens. No caso temos um array cujas chaves são as temperaturas em inteiros (representando as linhas na sua tabela) e valores são outros arrays (representando as colunas de umidade relativa, ainda na sua tabela). Lembrando que esse array será populado somente com os valores ambíguos, ou seja, que podem surgir em diferentes grupos de classificações. Bom... agora temos apenas 2 passos: 1 - Verificamos se o valor se encontra na tabela, e portanto deve ser recuperado no array (e não calculado). // Primeiro passo da lógica. Busca por ambiguidade: private function getAmbiguousStressRatingIndex() { $temp = $this->temp; $ur = $this->ur; if ( isset( self::AMBIGUOUS[ $temp ] ) && isset( self::AMBIGUOUS[ $temp ][ $ur ] ) ) return self::AMBIGUOUS[ $temp ][ $ur ];// int = índice do rótulo encontrado return false;// boolean false = não encontrou. Podia ser Exception, mas vamos facilitar o código } 2 - Não foi encontrado? Bom, é hora de calcular, pois esse cara não é ambíguo: // Utilizado apenas após confirmada a ausência de ambiguidade // ITU = (0,8 x TA + (UR/100) x (TA-14,4) + 46,4) private function getGeneralRatingIndex() { $temp = $this->temp / 10;// Estávamos trabalhando com valores inteiros para a temperatura. 244 => 24.4 $ur = $this->ur / 100; $ITU = .8 * $temp + $ur * ( $temp - 14.4 ) + 46.4; if ( $ITU < 72 ) return Stress::ABSENT; if ( $ITU < 79 ) return Stress::SOFT; if ( $ITU < 90 ) return Stress::MODERATE; if ( $ITU < 98 ) return Stress::SEVERE; return Stress::CRITICAL; } Por fim, temos a lógica de exibição baseada nas regras acima: $ambiguousRatingIndex = $this->getAmbiguousStressRatingIndex(); if ( $ambiguousRatingIndex !== false ) return sprintf( 'Classificação (por tabela de desambiguação): %s', self::RATING[ $ambiguousRatingIndex ] ); else { $rating = $this->getGeneralRatingIndex(); return sprintf( 'Classificação geral do estresse térmico por ausência de ambiguidade: %s', self::RATING[ $rating ] ); } Reunindo e organizando tudo que foi dito: <?php class Stress { const ABSENT = 0; // Ausente const SOFT = 1; // Ameno const MODERATE = 2; // Moderado const SEVERE = 3; // Severo const CRITICAL = 4; // Morte/Crítico const RATING = [ self::ABSENT => 'Ausência de estresse térmico', self::SOFT => 'Estresse térmico ameno', self::MODERATE => 'Estresse térmico moderado', self::SEVERE => 'Estresse térmico severo', self::CRITICAL => 'Estresse térmico crítico. Ocorrência de morte.', ]; const AMBIGUOUS = [ // Em 25 graus a 100% de UR temos um moderado: 250 => [ 100 => Stress::MODERATE ], // Já na linha dos 26,1 graus temos 3 ambíguos: 261 => [ 80 => Stress::SOFT, 90 => Stress::MODERATE, 100 => Stress::MODERATE ], // ... 433 => [ 30 => Stress::SEVERE ], 461 => [ 20 => Stress::MODERATE ], ]; public $temp;// int public $ur;// int public function __construct( $temp, $ur ) { $this->temp = $temp; $this->ur = $ur; } public function __toString() { $ambiguousRatingIndex = $this->getAmbiguousStressRatingIndex(); if ( $ambiguousRatingIndex !== false ) return sprintf( 'Classificação (por tabela de desambiguação): %s', self::RATING[ $ambiguousRatingIndex ] ); else { $rating = $this->getGeneralRatingIndex(); return sprintf( 'Classificação geral do estresse térmico por ausência de ambiguidade: %s', self::RATING[ $rating ] ); } } // Primeiro passo da lógica. Busca por ambiguidade: private function getAmbiguousStressRatingIndex() { $temp = $this->temp; $ur = $this->ur; if ( isset( self::AMBIGUOUS[ $temp ] ) && isset( self::AMBIGUOUS[ $temp ][ $ur ] ) ) return self::AMBIGUOUS[ $temp ][ $ur ];// int = índice do rótulo encontrado return false;// boolean false = não encontrou. Podia ser Exception, mas vamos facilitar o código } // Utilizado apenas após confirmada a ausência de ambiguidade // ITU = (0,8 x TA + (UR/100) x (TA-14,4) + 46,4) private function getGeneralRatingIndex() { $temp = $this->temp / 10;// Estávamos trabalhando com valores inteiros para a temperatura. 244 => 24.4 $ur = $this->ur / 100; $ITU = .8 * $temp + $ur * ( $temp - 14.4 ) + 46.4; if ( $ITU < 72 ) return Stress::ABSENT; if ( $ITU < 79 ) return Stress::SOFT; if ( $ITU < 90 ) return Stress::MODERATE; if ( $ITU < 98 ) return Stress::SEVERE; return Stress::CRITICAL; } } echo (string)( new Stress( 250, 100 ) ) . "\n";// 25,0 graus / 100% UR echo (string)( new Stress( 261, 80 ) ) . "\n";// 26,1 graus / 80% UR echo (string)( new Stress( 261, 90 ) ) . "\n";// 26,1 graus / 90% UR echo (string)( new Stress( 461, 20 ) ) . "\n";// 46,1 graus / 20% UR (seu exemplo) echo (string)( new Stress( 433, 30 ) ) . "\n";// 43,3 graus / 30% UR (seu exemplo) echo (string)( new Stress( 239, 40 ) ) . "\n"; echo (string)( new Stress( 317, 20 ) ) . "\n"; echo (string)( new Stress( 444, 80 ) ) . "\n"; Saída: Classificação (por tabela de desambiguação): Estresse térmico moderado Classificação (por tabela de desambiguação): Estresse térmico ameno Classificação (por tabela de desambiguação): Estresse térmico moderado Classificação (por tabela de desambiguação): Estresse térmico moderado Classificação (por tabela de desambiguação): Estresse térmico severo Classificação geral do estresse térmico por ausência de ambiguidade: Ausência de estresse térmico Classificação geral do estresse térmico por ausência de ambiguidade: Estresse térmico ameno Classificação geral do estresse térmico por ausência de ambiguidade: Estresse térmico crítico. Ocorrência de morte. Agora é com você: converter o código para a sua linguagem e popular a tabela (array) dos ambíguos. Essa é a forma mais performática que consigo imaginar no momento. Só seria interessante fazer alguns ajustes, dividir em mais classes com uma hierarquia mais inteligente, mas a ideia é essa aí. Se quiser testar em tempo real e fazer ajustes (testei bem pouco, pode ser que você encontre algum bug se testar mais): https://3v4l.org/vt7eP