Ir para conteúdo

proclnas

Membros
  • Total de itens

    3
  • Registro em

  • Última visita

Reputação

2 Neutral

1 Seguidor

Últimos Visitantes

87 visualizações
  1. [PHP] Splat Operator

    @Fernando Mercês, obrigado pelas boas vindas! A utilização do splat operator ajuda mto na portabilidade do código, o que significa que tiramos a responsabilidade do "caller" e deixamos por conta da função/método o tratamento dos dados. Lembrando sempre que cada caso uma necessidade, então vale a pena dar uma rabiscada antes pra ver se vale realmente a pena. Ahh... É muito comum vermos em frameworks esse tipo de prática. <?php function validateMail(...$hosts) { return array_filter($hosts, 'isValidMail'); } // Chamadas validateMail('foo@mentebinaria.com.br'); validateMail(['foo@mentebinaria.com.br'. 'bar@mentebinaria.com.br']); Abraço
  2. [Python] Queries SQL com Python e Records

    Fala galera! A algum tempo atrás precisei fazer algumas queries em tabelas para utilizar os resultados em outros processos. Lembro que no momento precisava de algo simples para que outros programadores pudessem dar manutenção no código, então resolvi desenvolver algo simples com python. Com a biblioteca padrão vi que precisava de muitas coisas e que era muito “complexo” estabelecer uma conexão com um banco seja lá qual fosse ele (Eu geralmente trabalho com mysql, postgresql ou sqlite) Na hora lembrei de um dos principios do Zen do python: Mesmo levando a regra em consideração, procurei outras alternativas para o trabalho proposto e assim encontrei a excelente biblioteca Records. Do mesmo criador da biblioteca requests. A introdução já adianta o que vem pela frente: Com o mesmo principio da biblioteca requests, a records foi desenvolvida em cima da seguinte filosofia: Para quem já utilizou requests sabe que realmente é simples fazer uma requisição http e essa mesma facilidade se aplica a Records. Se ainda não utilizou, o convido para que possa testar!!! A partir da instalação irei mostrar alguns exemplos de utilização com alguns dados fakes (mock data). Para que sirva de overview e quem sabe sirva também como “criador” de coragem para seu próximo projeto. Instalação No momento que escrevo o texto, utilizo python em sua versão 2.7.x. É recomendado instalar a bibiloteca via pip: Para demonstrar ações simples, criei um banco com algumas informações sobre conferências. Conexão Para criar a conexão com o banco precisamos utilizar um Dialect Estou utilizando postgtresql então prossigo da seguinte forma: Para facilitar criei um método que retorna a instância do db: import records # Importar a biblioteca # Criação de constantes ADAPTER = 'postgresql' USER = 'postgres' PASSWORD = 'postgres' HOST = 'localhost' DATABASE = 'mydb' def get_db(): """ Método para conexão com o banco """ return records.Database( '{}://{}:{}@{}/{}'.format(ADAPTER, USER, PASSWORD, HOST, DATABASE) ) try: db = get_db() ... except Exception as e: print e.message Agora já podemos executar ações no nosso banco. SELECT Para executar um select em uma tabela: rows = db.query('select * from bar') Formas de leitura dos resultados O banco que irei utilizar possui as seguintes tabelas: Uma linha por vez: rows = db.query('SELECT * FROM conferences') print rows[0] <Record {"id_conf": 1, "title": "DEF CON"}> Iteração: rows = db.query('SELECT * FROM conferences') for row in rows: print row Saída: <Record {"id_conf": 1, "title": "DEF CON"}> <Record {"id_conf": 2, "title": "H2HC"}> <Record {"id_conf": 3, "title": "BLACKHAT"}> <Record {"id_conf": 4, "title": "OWASP"}> <Record {"id_conf": 5, "title": "RSA"}> <Record {"id_conf": 6, "title": "TROOPERS"}> <Record {"id_conf": 7, "title": "NUIT DU HACK"}> <Record {"id_conf": 8, "title": "BSIDES"}> <Record {"id_conf": 9, "title": "PHPCONF"}> <Record {"id_conf": 10, "title": "PYCONF"}> Todos os resultados de uma vez (Para utilização futura): rows = db.query('SELECT * FROM conferences') print rows.all() Saída [<Record {"id_conf": 1, "title": "DEF CON"}>, <Record {"id_conf": 2, "title": "H2HC"}>, ...] Baseado nisso podemos então conhecer um pouco mais de nossas tabelas: rows = db.query('SELECT * FROM conferences LIMIT 4') for row in rows: print row <Record {"id_conf": 1, "title": "DEF CON"}> <Record {"id_conf": 2, "title": "H2HC"}> <Record {"id_conf": 3, "title": "BLACKHAT"}> <Record {"id_conf": 4, "title": "OWASP"}> rows = db.query('SELECT * FROM speakers LIMIT 4') for row in rows: print row <Record {"id_speaker": 1, "name": "BSDaemon"}> <Record {"id_speaker": 2, "name": "C00F3r"}> <Record {"id_speaker": 4, "name": "Stefan Esser"}> <Record {"id_speaker": 5, "name": "Nikita Popov"}> rows = db.query('SELECT * FROM talks LIMIT 4') for row in rows: print row <Record {"id_talk": 1, "id_conf": 1, "id_speaker": 1, "title": "KIDS - Kernel Intrusion Detection System"}> <Record {"id_talk": 4, "id_conf": 1, "id_speaker": 6, "title": "Exploiting nginx logrotate"}> <Record {"id_talk": 5, "id_conf": 1, "id_speaker": 9, "title": "Improving crypto"}> <Record {"id_talk": 6, "id_conf": 1, "id_speaker": 14, "title": "Kernel exploitation in a nutshell"}> No último snippet se repararem irão ver que possuímos apenas os id’s das tabelas: conferences (id_conf) e speakers(id_speaker). É comum vermos esse tipo de Relacionamento. Para ligar os dados podemos executar um JOIN simples e saber quem é o speaker, e a conferencia no qual ele irá apresentar essa talk: print 'Speakers agenda' raw = 'SELECT conferences.title as conf, speakers.name as speaker, ' \ 'talks.title as talk FROM talks ' \ 'JOIN conferences ON conferences.id_conf = talks.id_conf ' \ # Aqui relacionamos talks com conferences para pegar o nome da conferencia 'JOIN speakers ON speakers.id_speaker = talks.id_speaker ' \ # E aqui relacionamos talks com speakers para pegar o nome do speaker 'ORDER BY conferences.title' rows = db.query(raw) for row in rows: print 'Conf: {}, Speaker: {}, Talk: {}'.format( row['conf'], row['speaker'], row['talk'] ) Saída Speakers agenda Conf: BLACKHAT, Speaker: Rodrigo Strauss, Talk: Soft driver exploitation Conf: DEF CON, Speaker: KingCope, Talk: Kernel exploitation in a nutshell Conf: DEF CON, Speaker: Diego Aranha, Talk: Improving crypto Conf: DEF CON, Speaker: Dawid Golunski, Talk: Exploiting nginx logrotate Conf: DEF CON, Speaker: BSDaemon, Talk: KIDS - Kernel Intrusion Detection System Conf: DEF CON, Speaker: Stefan Esser, Talk: Ios jailbreak Conf: H2HC, Speaker: Stefan Esser, Talk: Smashing php serialize Conf: OWASP, Speaker: C00F3r, Talk: "Web Spiders" - Automation para Web Hacking Conf: OWASP, Speaker: Merces, Talk: LULa project Conf: PHPCONF, Speaker: Gabriel Couto, Talk: PHP Gui Conf: PHPCONF, Speaker: Gabriel Couto, Talk: PHP Threading Conf: PHPCONF, Speaker: Julien Pauli, Talk: Exploiting zend engine Simples não? Podemos também executar queries com parâmetros seguros (parameter binding): rows = db.query( 'SELECT * FROM talks WHERE id_talk = :id_talk', False, id_talk=1 ) print rows[0] <Record {"id_talk": 1, "id_conf": 1, "id_speaker": 1, "title": "KIDS - Kernel Intrusion Detection System"}> UPDATE Para executar updates também não há segredos: print db.query( 'SELECT * FROM talks WHERE id_talk = :id_talk', False, id_talk=1 )[0] Saída <Record {"id_talk": 1, "id_conf": 1, "id_speaker": 1, "title": "KIDS - Kernel Intrusion Detection System"}> db.query( 'UPDATE talks SET id_conf = :id_conf WHERE id_talk = :id_talk', False, id_conf=3, id_talk=1 ) print db.query( 'SELECT * FROM talks WHERE id_talk = :id_talk', False, id_talk=1 )[0] Saída <Record {"id_talk": 1, "id_conf": 3, "id_speaker": 1, "title": "KIDS - Kernel Intrusion Detection System"}> Filtrando novamente nossa query agora completa teremos nossos resultados atualizados: print '\nSpeakers agenda' raw = 'SELECT conferences.title as conf, speakers.name as speaker, ' \ 'talks.title as talk FROM talks ' \ 'JOIN conferences ON ' \ 'conferences.id_conf = talks.id_conf ' \ 'JOIN speakers ON speakers.id_speaker = talks.id_speaker ' \ 'WHERE talks.id_conf = :id_conf ' \ 'ORDER BY conferences.title' rows = db.query(raw, False, id_conf=3) for row in rows: print 'Conf: {}, Speaker: {}, Talk: {}'.format( row['conf'], row['speaker'], row['talk'] ) Saída Speakers agenda Conf: BLACKHAT, Speaker: Rodrigo Strauss, Talk: Soft driver exploitation Conf: BLACKHAT, Speaker: BSDaemon, Talk: KIDS - Kernel Intrusion Detection System DELETE db.query( 'DELETE FROM talks WHERE id_conf = :id_conf', False, id_conf=3 ) # Talks by conference print '\nSpeakers agenda' raw = 'SELECT conferences.title as conf, speakers.name as speaker, ' \ 'talks.title as talk FROM talks ' \ 'JOIN conferences ON ' \ 'conferences.id_conf = talks.id_conf ' \ 'JOIN speakers ON speakers.id_speaker = talks.id_speaker ' \ 'WHERE talks.id_conf = :id_conf ' \ 'ORDER BY conferences.title' rows = db.query(raw, False, id_conf=3) for row in rows: print 'Conf: {}, Speaker: {}, Talk: {}'.format( row['conf'], row['speaker'], row['talk'] ) Saída Speakers agenda Exportação A biblioteca records possui integração completa com a biblioteca Tablib então é possível exportar data de várias formas. Retirei os exemplos abaixo da documentação oficial >>> print rows.dataset username|active|name |user_email |timezone --------|------|----------|-----------------|-------------------------- hansolo |True |Henry Ford|hansolo@gmail.com|2016-02-06 22:28:23.894202 ... CSV: >>> print rows.dataset.csv username,active,name,user_email,timezone hansolo,True,Henry Ford,hansolo@gmail.com,2016-02-06 22:28:23.894202 ... YAML: >>> print rows.dataset.yaml - {active: true, name: Henry Ford, timezone: '2016-02-06 22:28:23.894202', user_email: hansolo@gmail.com, username: hansolo} ... JSON: >>> print rows.dataset.json [{"username": "hansolo", "active": true, "name": "Henry Ford", "user_email": "hansolo@gmail.com", "timezone": "2016-02-06 22:28:23.894202"}, ...] Excel: with open('report.xls', 'wb') as f: f.write(rows.dataset.xls) Conclusão Esse foi um post introdutório. Sinta-se livre para deixar um comentário ou sugerir melhorias! Forte abraço! Referência https://www.kennethreitz.org/essays/introducing-records-just-write-sql https://github.com/kennethreitz/records http://docs.sqlalchemy.org/en/latest/dialects/ https://www.concise-courses.com/security/conferences-top-ten-must-go-to/ https://pt.wikipedia.org/wiki/Banco_de_dados_relacional#Relacionamentos
  3. [PHP] Splat Operator

    Olá guys, tudo em ordem? Meu primeiro post aqui no mente binária, que inclusive foca em php e que provavelmente irá ajudar aqueles que se aventuram na linguagem. Boa leitura! Em alguns momentos pode surgir a necessidade de se criar um método/função com argumentos variáveis. O próprio php possui funções que aceitam “n” argumentos, como por ex: var_dump isset Entre outros. A partir da versão 5.6 do PHP é possível utilizar o “splat operator (…)” que nos da a capacidade de criar método/funções com argumentos variáveis, entre outras coisas. Ex: <?php function evaluateString($callback, ...$strings) { $myStr = 'INITIAL: '; foreach ($strings as $stringPiece) { $myStr .= $stringPiece; } return call_user_func($callback, $myStr); } $strAllUp = evaluateString( 'strtoupper', 'rodrigo', ' nascimento' ); var_dump($strAllUp); // Saída: string(27) "INITIAL: RODRIGO NASCIMENTO" Ex de utilização: <?php function soma(...$numbers) { var_dump($numbers, count($numbers)); } soma(1, 2, 3, 4); // Saída array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) } int(4) // Quantidade de parâmetros recebidos pela função A partir dai podemos fazer algumas operações. Uma soma por exemplo utilizando o mesmo código acima: <?php function soma(...$numberss) { return array_sum($numbers); } var_dump(soma(5, 5, 5, 5)); // Saída int(20) E em alguns casos mais complexos podemos até fazer operações mais distintas: Consulta de arquivos: <?php function checkFiles(...$files) { return array_map(function($file){ return [$file => file_exists($file) ? 'Found' : 'Not found']; }, $files); } $busca = checkFiles( '1.txt', 'about.md', 'ex.php', 'foo.php' ); foreach ($busca as $arquivos) { foreach ($arquivos as $nomeArquivo => $status) echo sprintf('%s => %s' . PHP_EOL, $nomeArquivo, $status); } // Saída 1.txt => Not found about.md => Found ex.php => Found foo.php => Not found OBS: O exemplo acima é somente um exemplo e não visa substituir as capacidades nativas do php! (Não me diga…) (Nativamente o php trabalha mto bem com arquivos: GlobIterator entre outros…) Requisições http, gerar logs, etc: <?php function gerarLogs(...$urls) { array_walk($urls, function($url) { // lógica aqui... Requisições http, etc echo sprintf('[+] Gerando logs para: %s' . PHP_EOL, $url); }); } gerarLogs( 'http://www.google.com', 'http://php.net', 'http://theuselessweb.com' ); // Output [+] Gerando logs para: http://www.google.com [+] Gerando logs para: http://php.net [+] Gerando logs para: http://theuselessweb.com Utilizando type hinting com splat operator É possível especificar os tipos de argumentos esperados pela função utilizando type hiting normalmente: <?php function expectCarObject(Car ...$cars) { foreach ($cars as $car) { var_dump($car); } } class Car {} expectCarObject(new Car, new Car, new Car); // Saida object(Car)#1 (0) { } object(Car)#2 (0) { } object(Car)#3 (0) { } Caso seja passado parâmetros diferentes do tipo “Car” um fatal error será emitido pelo php. Unpacking de argumentos Com splat operator é possível também fazer unpacking de argumentos, o que significa que é possível escrever algo como: <?php function soma($numA, $numB) { return $numA + $numB; } $nums = [1, 2]; var_dump(soma(...$nums)); // Saída: int(3) Os exemplos estão longe de serem algo definitivo. Da próxima vez que for criar uma classe útil que possui métodos flexíveis, de uma chance ao splat operator. Dúvidas, sugestões, tomar uma breja? Deixe seu comentário! Forte abraço! Referências: splat operator - php.net func_num_args - php.net func_get_args - php.net StackOverflow - question1 StackOverflow - question2
×