Jedi Tux

Estudando e Revisando com o Anki

Posted in Desktop, Dicas by Fernando Basso on 3 de março de 2014

Há mais ou menos um mês tenho utilizado o Anki para revisar tudo o que por algum um motivo preciso memorizar. O resultado está sendo extraordinário.

A imagem abaixo mostra uma hora de estudo, mas foi um caso a parte. Normalmente, uns 20 minutos por dia são suficientes.

 

Um dia de revisão com o Anki

JavaScript – Sites Úteis e Interessantes

Posted in Sem categoria by Fernando Basso on 12 de fevereiro de 2014

JavaScript, Laços, Closures e Escopo

Posted in JavaScript by Fernando Basso on 11 de fevereiro de 2014

A função abaixo itera sobre um laço for, mas o resultado não é o esperado.

function fn() {
    var arr = [],
        i   = 0;

    for ( ; i < 3; ++i ) {
        arr[ i ] = function() {
            return i + 10;
        }
    }
    return arr;
}
var res = fn();

O objetivo do laço é popular o array, fazendo com que cada posição contenha uma função, de forma que seja possível chamar as funções dessa forma:

res[ 0 ](); // 10.
res[ 1 ](); // 11.
res[ 2 ](); // 12.

O problema é que devido à maneira que o escopo é tratado em Javascript, os resultados são 13, 13 e 13 em vez dos esperados 10, 11, 12.

O que aconteee é que em JavaScript as variáveis tem seu valor estabelecido no momento em que são usadas, e não no momento em que são declaradas. No caso do return i + 10, o i só é interpretado quando executamos res[ 0 ](), res[ 1 ](), etc. A função assinada a cada índice do array guarda apenas uma referência ao escopo onde foram definidas. Mais tarde, quando essas funções são realmente chamadas, elas vão encontrar o valor do i, que é 3 (último incremento antes da condição do laço retornar falso) e usar aquele valor.

Uma maneira de resolver o problema é usando uma closure para “forçar” o escopo e retornar uma função que guarda os valores desejados do i. Para isso vamos utilizar uma IIFE (immediately invoked function expression) que aceita o i como parâmetro e assim cria um novo escopo onde o valor correto do i é lembrado quando cada função retornada for finalmente chamada.

Essa é a versão “semi-correta”.

function fn() {
    var arr = [],
        i   = 0;
    for ( ; i < 3; ++i ) {
        arr[ i ] = function( n ) {
            return function() {
                return n + 10;
            }
        }( i ));
    }
    return arr;
}

var res = fn();
console.log( res[ 0 ]() ); // 10
console.log( res[ 1 ]() ); // 11
console.log( res[ 2 ]() ); // 12

Por que “semi-correta”? Porque estamos criando uma nova função a cada volta do laço. Isso é desnecessário e custa mais ciclos do processador. Vamos criar uma versão onde a função já fica pronta, apenas esperando para ser usada.

function fn() {

    // Note que addTen retorna uma função que por sua vez retorna o arg + 10.
    function addTen( arg ) {
        return function() {
            return arg + 10;
        };
    }

    var arr = [],
        i   = 0;
    for ( ; i < 3; ++i ) {
        arr[ i ] = addTen( i );
    }
    return arr;
}

var res = fn();
console.log( res[ 0 ]() ); // 10
console.log( res[ 1 ]() ); // 11
console.log( res[ 2 ]() ); // 12

Veja que na função addTen, seria incorreto especificar argumento para a função interna – aquela que é retornada, pois não teríamos como passar o argumento sem chamar a função. Nesse caso, estaríamos retornando o valor da função, e não a função em si.

    function addTen( arg ) {
        // ERRADO!
        return function( n ) { // Não especifique argumento na assinatura da função.
            return n + 10;
        }; // Teriamos que usar ( arg ) nessa linha.
    }

O melhor é deixar assim (como no exemplo correto):

    function addTen( arg ) {
        return function() {
            return arg + 10;
        };
    }

Graças ao conceito de “closures”, mesmo arg não sendo passada como parâmetro na função interna (aquela que é retornada), ela ainda assim é acessível.

May the force be with you.

JavaScript – Validar Email e Mostrar Mensagem SEM alert()

Posted in JavaScript by Fernando Basso on 21 de julho de 2013

O email é validado tanto no evento blur do campo de email quanto no event submit do formulário. Uma mensagem é adicionada ou removida conforme a validade ou não do email.

A mensagem é criada com document.createTextNode() e é inserida em uma div que é criada com document.CreateElement(). Para completar o processo também são utilizados os métodos appendChild() e removeChild().

Qualquer dúvida ou sugestão pode ser feita através dos comentários.

script.js


// O código poderia estar melhor organizado, mas optei por deixar
// assim para que não ficasse demasiado complicado.

window.onload = function() {

    ////////////////////////////////////////////////////////////////////////////
    // FUNÇÕES UTILIZADAS NA VALIDAÇÃO ////////////////////////////////////////

    function checkEmail(email) {
        var re = /^([\w_\-\.])+@([\w_\-\.])+\.([\w]{2,4})$/;
        return !re.test(email) ? false : true;
    }

    function validacao(email) {
        if (!checkEmail(email)) {
            // Só vamos colocar a mensagem se a div#msg ainda não existe.
            if (document.getElementById('msg') == null) {
                // Cria uma tag 'div'.
                var div = document.createElement('div');
                // Coloca id='msg' na div.
                div.id = 'msg';
                // Cria um texto.
                var msg = document.createTextNode('Email inválido...');
                // Coloca o texto dentro da div.
                div.appendChild(msg);
                // Coloca a div como último 'child' do formulário.
                testForm.appendChild(div);
            }
            return false;
        }
        else {
            var divMsg = document.getElementById('msg');
            // Se o usuário já acertou o email, a div é removida, mas se ele
            // faz focus e blur novamente no email, e a div#msg já não existe,
            // daria erro tentar remover algo que não existe.
            if (divMsg != null) {
                testForm.removeChild(divMsg);
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    // A VALIDAÇÃO /////////////////////////////////////////////////////////////

    // Pega o form pelo atributo 'name'.
    var testForm = document.forms['test-form'];

    // Valida no blur do campo email
    form.email.onblur = function() {
        validacao(this.value); // Passa o texto do campo email.
    };

    // E também valida no submit do formulário.
    form.onsubmit = function() {
        return validacao(this.email.value);
        // A função 'validacao()', além de colocar e remover a mensagem
        // conforme necessário, ainda retorna true/false dependendo da
        // validade do email. Se o email não é válido, temos que prevenir
        // que o formulário seja submetido, por isso o 'return' nesse caso.
    };

};

form.html



<meta charset="utf-8" />
 Mensagem de Validação de Formulário
        	<link href="style.css" rel="stylesheet" /><script type="text/javascript" src="script.js"></script></pre>
<section><form id="form" method="post" name="test-form">
<div><label for="email">E-Mail:</label>
 <input id="email" type="text" name="email" /></div>
<div><label for="senha">Senha:</label>
 <input id="senha" type="text" name="senha" /></div>
<div><label for="btn-enviar"> </label>
 <input id="btn-enviar" type="submit" name="btn-enviar" value="OK" /></div>
 <!--
<div id='msg'>Email inválido...</div>
--></form></section>
<pre>

style.css

html {
    font-size: 0.9em;
    font-family: 'Tahoma', 'Verdana', 'Arial';
    color: gray;
}
body {
    width: 600px;
    margin: 0 auto;
}
section {
    width: 500px;
    margin: 50px 0 0 0;
    background: #efefef;
    padding: 20px;
}
form {
    width: 400px;
    margin: 0 auto;
}
form div {
    margin: 10px 0 10px 0;
}
div label {
    display: block;
    width: 100px;
    text-align: right;
    margin-right: 8px;
    float: left;
}
div input {
    color: dimgray;
    padding: 7px;
    border: 1px solid lightgray;
    box-shadow: 2px 2px 11px 0 #EFEFEF inset;
}
div input[type='text'] {
    width: 200px;
}
#msg {color: red;
    font-size: 0.8em;
    margin: 10px 0 0 110px;
}

Código no github:

https://github.com/FernandoBasso/devplace/tree/master/javascript/valida-email-msg

Tagged with: , ,

JavaScript – Limpar Campos de Texto de Formulário – onfocus, onblur

Posted in JavaScript by Fernando Basso on 16 de julho de 2013

Exemplo de limar campos de texto de formulário quando o usuário foca no campo, e coloca o texto default
se o campo ficar vazio no evento ‘blur’.

clear-text.js

// Espera o DOM ficar pronto...
window.onload = initAll;

function initAll() {

    // Pega o forumlário pelo valor do atributo 'name'.
    var f = document.forms.contato;
    // Cria um array com os elementos a serem verificados.
    var arrCampos = [ f.nome, f.email ];

    // Salva o valor original de cada campo.
    for (var i = 0; i < arrCampos['length']; ++i) {
        arrCampos[i].origVal = arrCampos[i].value;
    }
    // Executa as ações de tirar e colocar o texto, conforme necessário.
    for (var i = 0; i < arrCampos['length']; ++i) {
        arrCampos[i].onfocus = tiraTexto;
        arrCampos[i].onblur  = colocaTexto;
    }
}

///////////////////////////////////////////////////////////////////////
// Aqui definimos a função que limpa o texto, mas só se o valor ///////
// for diferente do valor original. ///////////////////////////////////
function tiraTexto() {
    this.value = (this.value == this.origVal) ? '' : this.value;
}
///////////////////////////////////////////////////////////////////////
// Coloca o texto de volta caso o usuário deixou em branco ////////////
function colocaTexto() {
    if (this.value == '') { this.value = this.origVal; }
}

form.html

<!DOCTYPE html>
<html lang='pt-br'>
  <head>
    <meta charset='utf-8'>
    <title>Limpar campos de formulário com JavaScript</title>
    <link href='style.css' rel='stylesheet'>
    <script src='clear-text.js'></script>
  </head>
  <body>

    <section>
      <form name='contato' method='post' action='#'>
        <div>
          <label for='nome'>Nome:</label>
          <input type='text' name='nome' id='nome' value='Mestre Yoda...'>
        </div>
        <div>
          <label for='email'>E-Mail:</label>
          <input type='text' name='email' id='email' value='yoda@jedi.tux...'>
        </div>
        <div>
          <label for='submit'>&nbsp;</label>
          <input type='submit' name='submit' value='OK'>
        </div>
      </form>
    </section>

  </body>
</html>

style.css

html {
    font-family: 'Verdana', 'Arial', 'Serif';
    font-size: 0.9em;
    color: #4f4f4f;
    background: #cfcfcf;
}
section {
    width: 500px;
    margin: 0 auto;
    background: #efefef;
    padding: 30px;
    border-radius: 5px;
}
form {
    width: 400px;
    margin: 0 auto;
}
form div {
    margin: 10px 0;
}
div label {
    display: block;
    width: 100px;
    float: left;
    text-align: right;
    margin-right: 10px;
}
div input {
    border: 1px solid lightgray;
    width: 200px;
    padding: 5px;
}
div input[type='submit'] {
    width: 100px;
    padding: 4px;
}
div input[type='submit']:hover {
    cursor: pointer;
}

Código no github:https://github.com/FernandoBasso/devplace/tree/master/javascript/limpa-campos

OpenSource-WebDevDesign – Canal na Freenode

Posted in Sem categoria by Fernando Basso on 18 de outubro de 2012

Canal IRC para Desenvolvedores e Designers Web – Gimp, Inkscape, HTML/CSS/JavaScript e outros.

O objetivo desse canal é ser um ponto de troca de experiências e conhecimento para web designers e web developers, focando software livre, como gimp, inkscape, e linguagens de programação voltadas ao tema. Uma das políticas é que nada relacionado a TI é off-topic.
Busco parceiros e a ajuda outros sites relacionados aos assuntos propostos acima para colaborarem e ajudarem no canal. Não tenho intenção de ser o “dono” do canal. Não há necessidade de um “moderador”, já que praticamente não há off-topic. O que é necessário é bom senso e respeito a opinião e ao conhecimento dos demais, seja ele extenso ou limitado.

/join #Opensource-WebdevDesign

Atualização do PostgreSQL para 9.2 – Arch Linux

Posted in Dicas, Servers by Fernando Basso on 28 de setembro de 2012

----------------------------------------------------
bash-4.2, vaio@nando, Fri Sep 28 07:37:53 
$PWD="~/"  
$ sudo rc.d start postgresql 
[sudo] password for nando: 
:: Starting PostgreSQL

[BUSY] pg_ctl: could not start server
               Examine the lot output

    vim /var/log/postgresql.log

FATAL:   database files are incompatible with server 6009
DETAIL:  The data directory was initialized by PostgreSQL version 9.1, which
is not compatible with this version 9.2.1.

-------------------------------------------------------------------------------

http://www.postgresql.org/docs/current/static/upgrading.html

NOTA: É possível fazer isso com a versão 9.2, mas como no meu caso eu nem consegui
inicializar o postgresql com ela, fiz com a 9.1 mesmo.

    sudo pacman -U /var/cache/pacman/pkg/postgresql-9.1.4-1-i686.pkg.tar.xz


Primeiro de tudo, salvar o banco de dados atual, com a versão 9.1 do postgresql
rodando:

    pg_dumpall > postgresql_backup_completo.sql

Mas aí teve algo errado, pois ele ficava peding a senha do usuário linha após
linha, e com
    pg_dumpall -U postgres ...

aconteceu a mesma coisa.

vim ~/.pgpass
localhost:5432:db_nando:nando:1234

Mas pra fazer o backup de tudo, temos que deixar o campo que especifica
a database com "*":
localhost:5432:*:nando:1234

http://www.postgresql.org/docs/9.2/static/libpq-pgpass.html

On Unix systems, the permissions on .pgpass must disallow any access to world
or group; achieve this by the command chmod 0600 ~/.pgpass. If the permissions
are less strict than this, the file will be ignored. On Microsoft Windows,
it is assumed that the file is stored in a directory that is secure, so no
special permissions check is made.


(08:29)  gciolli: Should ~/.pgpass allow my to just type psql and connect 
                     without any further iteration?
(08:31)  FernandoBasso: .pgpass only takes care of not having to type the 
                     password, all the other options are handled via environment 
                     variables like PGUSER, etc.

http://www.postgresql.org/docs/9.2/static/libpq-envars.html

Pode ser no bashrc.
export PGUSER=myFavouritePostgresUser
export PGDATABASE=db_nando

Agora já devemos estar podento digitar apenas "psql" pra logar sem
ter que especificar o password nem a database.

--------------------------- // ----------------------- // -----------------

Agora deve funcionar:
    pg_dumpall > postgressql_backup_completo_upgrade_para_9.2

    sudo rc.d stop postgresql (arch linux)

    cd /var/lib/postgres
    mv data bkp_data_9.1

    rc.d start postgresql
    rc.d stopt postgresql

    cp bkp_data_9.1/pg_hba.conf data/
    cp bkp_data_9.1/postgresql.conf data/


    vim data/pg_hba.conf

E seta
    host    all     all    127.0.0.1/32     md5
para
    host    all     all    127.0.0.1/32     trust

por que os passwords e usuários não vão funcionar mais.

    psql -U postgres


Criamos um usuário:

    CREATE ROLE admin WITH LOGIN PASSWORD 'admin' CREATEDB CREATEROLE; 
    ALTER USER admin VALID UNTIL 'infinity';

Colocamos uma senha para o superuser postgres:
    ALTER USER postgres WITH PASSWORD 'serect_passwd';

Recuperar os dados (deu alguns avisos aqui, mas funcionou tudo mesmo assim):

    psql -d postgres -f postgresql_backup_completo.sql

Coloca os 'trust' para 'md5' novamente no arquivo pg_hba.conf.

Reinicia o postgres e já deve estar tudo ok.


For further reading:

https://wiki.archlinux.org/index.php/PostgreSQL#Upgrading_PostgreSQL


http://www.postgresql.org/docs/current/static/upgrading.html

Idea – Java IDE + Vim

Posted in Dicas by Fernando Basso on 15 de setembro de 2012

Idea Java IDE e ideaVim

 

Recentemente iniciei meus estudos de Java, e realmente, por mais que eu prefira o Vim para tudo, é tortura querer programar Java nele, pois tem toda aquela história de packages, classes, access modifiers, imports, e tudo mais, e uma IDE especial para Java é muito mais prática do que o meu querido Vim.
Para mim, o problema com as IDEs é o editor, que são horríveis. Qualquer conhecedor de Vim (ou Emacs) sabe do que eu estou falando. As IDEs podem ter um milhão de qualidades, mas o editor não é uma delas, pelo menos não nas IDEs das quais eu já tive conhecimento até hoje.

Já tentei plugins para o Eclipse (eclim, vimplugin) e Netbeans (jVi). Ajudam bastante mas não consegui me adaptar a nenhum deles. Lendo na web acabei por encontrar alguém mencionando em um fórum dessa IDE chamada Idea, eu que havia um excelente plugin que oferece mode de edição igual ao Vim para ela. Resolvi testar.

http://www.jetbrains.com/idea/features/index.html

Idea – Instalação

No Arch Linux, basta instalar o pacote, pois está nos repositórios oficiais (pelo visto há uma versão paga também).


sudo pacman -S intellij-idea-community-edition

É lógico que você precisa ter o JDK e JRE instalado. Aparentemente, a equipe de desenvolvimento não suporta o OpenJDK oficialmente, mas dizem que funciona normalmente. Eu, particularmente, tenho os pacotes jre e jdk instalados do AUR (wiki, aur).

Apenas para constar, eu gerencio os pacotes provenientes do AUR usando o excelente aurget (todo em bash). Funciona perfeitamente bem para mim.

Depois de instalado, basta rodar, tanto pelo terminal, ou através de algum run-dialog (geralmente Alt+F2) e digitar


idea.sh

É um script que reside em /usr/bin/ e inicia a IDE para nós.
Na momento de criar o primeiro projeto, você será perguntando sobre o caminho do JDK no sistema. Basta executar o seguinte comando para descobrir:


echo $JAVA_HOME

No meu caso, no Arch Linux, bastou colocar /opt/java/ e pronto.

ideaVim

File –> Settings –> Plugins, clique em “Browser repositories” e pesquise por “ideaVim”. Clique com o botão direito em cima do nome do plugin  e escolha “Download and install”. Pode fechar as duas janelas clicando em OK e você verá a informação do download na parte inferior da janela principal da IDE. Apos instalado, basta reiniciar IDE e o plugin já deve vir habilitado por padrão. Em “Tools” você vai ver uma opção para habilitar e desabilitar o plugin.
Uma coisa que gostei bastante é que até Visual-Block Selection funciona, algo que senti falta em outros plugins para outras IDEs. Uso isso muito para comentar pedaços inteiros de código quando necessário. Para quem não sabe, imagine que você quer comentar as primeiras 5 linhas de código, basta se posicionar na primeira coluna (caractere) da primeira linha (no modo normal), pressionar Ctrl-V, 5jI// e então pressionar <Esc>. Para remover faz-se a mesma seleção e digita-se algum comando de deleção, como o “x”, por exemplo.
Outra coisa que gostei é a maneira como a IDE usa uma leve linha pontilhada mostrando o abrir e fechar de blocos, embora ele mostre o qual { é o par que casa com um } e vice-versa destacando-os com uma cor diferente, assim como o Vim já faz por padrão.

Dicas

Ctrl+Shift+a permite que você pesquise por uma opção ou configuração. Tente pesquisar por plugins, por exemplo. Ctrl+Shift+n permite pesquisar e abrir arquivos.

Outra muito legal, é quando, digamos que você está no main() usando um método chamado listFuncionarios(). Com o cursor em cima do nome do método, digitar Ctrl+Alt+b leva você para a classe e local de definição do método. Isso muito útil já que muitas vezes, somente ao utilizarmos um método percebemos falhas e então temos que voltar nele e melhorar o código.

De vez em quando, acesse Help –> Productivity Guide, clique em “Used” de forma a deixar a setinha apontando para baixo, e dê uma olhada nas coisas para ver o que você usa mais, e o que você poderia estar usando mas não está.

Shortcuts são sempre bem vindos:

http://www.jetbrains.com/resharper/webhelp/Reference__Keyboard_Shortcuts.html

http://stackoverflow.com/questions/294167/what-are-the-most-useful-intellij-idea-keyboard-shortcuts
Se alguém quiser dar sugestões e dicas, pode mandar nos comentários (os créditos serão reconhecidos). Quem tiver algum post sobre issa excelente IDE, por favor não deixe de compartilhar também.

Tagged with: , , ,

PHP e MySQL funções para conexões e consultas

Posted in PHP by Fernando Basso on 20 de maio de 2012

TODO: em alguns pontos eu mencionei que alguma funções retornam um array, sendo que elas retorna um object com os dados da query. Concertar isso.

PHP e MySQL

Introdução

As principais funções para estabelecer uma conexão no banco de dados e selecionar uma database para usada são mysql_connect(), mysql_set_charset() e mysql_select_db();

Nas versões mais novas do MySQL essas (e outras) funções foram melhoradas (Improved) e hoje temos as funções mysqli_connect(), mysqli_set_charset() e mysqli_select_db().

MySQL – Básico

mysql_connect() e mysqli_connect

Essas funções abrem (ou reusam) uma conexão com um servidor MySQL. Os parâmetros mínimos (e os mais úteis) esperados pelo mysql_connect e mysqli_connect são o nome do host onde está o banco de dados mysql, o nome do usuário no banco de dados, e o password desse usuário. Não importa qual das funções você use, esses três parâmetros são os mesmos:

mysql_connect(‘localhost’, ‘admin’, ‘secretPass’);

ou

mysqli_connect(‘localhost’, ‘admin’, ‘secretPass’);

Essas duas funções retornam um identificador de link mysql quando a conexão foi bem sucedida, e FALSE quando houve algum tipo de erro. O identificador de link é usado para referenciar a conexão com o banco de dados toda vez que precisarmos executar uma query. Por esse motivo, sempre atribuímos valor retornado a uma variável para facilitar o seu uso posterior. Veja:

$dblinkid = mysqli_connet(‘localhost’, ‘admin’, ‘secretPass’);

Se a conexão foi bem sucedida, de agora em diante podemos usar a variável $dblinkid em outras funções para realizar queries. Exemplos serão mostrados em momentos oportunos.

mysql_set_charset() vs mysqli_set_charset()

Usadas para estabelecer o encoding da conexão, estas duas funções precisam dos parâmetros identificador de link e charset. O identificador de link nós já conhecemos, no exemplo anterior, colocamos ele na variável $dblinkid. Quanto ao charset, normalmente usamos utf8. O “problema” é que a ordem em que passamos esses argumentos muda. Veja nos exemplos como ficariam esses parâmetros e sua ordem:

mysql_set_charset(‘utf8′, $dblinkid);

ou

mysqli_set_charset($dblinkid, ‘utf8′);

Colocando esses parâmetros na ordem errada resulta um erro parecido com este:

Warning: mysqli_set_charset() expects parameter 1 to be mysqli,

string given in /caminho/para/arquivo.php

ou

Warning: mysql_set_charset() expects parameter 1 to be string,

object given in /caminho/para/arquivo.php

Os parâmetros são os mesmo, mas a ordem não. Lembre-se disso.

mysql_select_db() vs mysqli_select_db()

Funções usadas para especificar o banco de dados dentro de servidor MySQL. Os parâmetros esperados são o identificador de link (viu como ele é importante?) e o nome da database no servidor. Novamente, o que muda é a ordem, embora os parâmetros sejam os mesmos.

mysql_select_db(‘db_articles’, $dblinkid);

ou

mysqli_select_db($dblinkid, ‘db_articles’);

Se nada saiu errado nos três passos vistos até agora, a conexão foi estabelecida. Em todo caso, podemos e devemos verificar por erros para ter certeza, tornando o código mais robusto e confiável. Continue lendo.

 

 Verificando por Erros (mysql)

Em breve (é algo bem simples).

Queries – mysql_query vs mysqli_query

Colocamos uma query mysql em uma variável, por exemplo:

$sql = ‘SELECT id, nome FROM tb_pessoas’;

E usamos uma das funções para executar a query. Mais uma vez o que muda é apenas a ordem dos parâmetros.

mysql_query($sql, $dblinkid);

ou

mysqli_query($dblinkid, $sql);

Essas funções retornam FALSO em caso de erro. Por outro lado, queries bem sucedidas com SELECT (e alguns outros comandos sql) retornam um result object ou result set, que é um array contendo o resultado da query. Por esse motivo, atribuímos esse result object a uma variável para futura manipulação dos dados.

$result_set = mysqli($dblinkid, $sql);

O array retornado pode ser acessado por um punhado de funções, cada uma com sua particularidade, sendo que a escolha de uma vai depender do resultado desejado.

Extraindo dados do result object / result set) (mysql)

As principais funções para recuperar dados de um result set (que contém um array com os dados solicitados na query) são mysqli_fetch_assoc(), mysqli_fetch_row() e mysqli_fetch_array(). Outras duas funções que são úteis em diversas situações são mysqli_num_fields() e mysqli_field_name(). Todas essas funções também estão disponíveis na versão mais antigas – aquelas que não contém o “i” após “mysql” (mysqli).

Esta é a nossa tabela no banco de dados:

Note que temos três colunas, c_id, c_text, e c_author e sete tuplas, linhas ou rows (fileiras).

mysqli_fetch_row()

A função mysqli_fetch_row() espera um result set como parâmetro e retorna uma tupla em forma de array com índices numéricos. No caso da tabela acima, o array retornado teria o índice [0] como a coluna c_id, o índice [1] como c_text, e o índice [2] como c_author. Tenha em mente que se você mudar a ordem das colunas na query SQL, mudará o conteúdo que os [índices] irão acessar. Outro fator importante é que cada chamada subsequente dessa função retorna a próxima tupla/item/row do result set, e NULL quando não há mais tuplas restantes, e por esse motivo podemos usar essa função dentro de loops (já que loops dependem de verdadeiro ou falso decidir se sua execução será encerrado ou deve continuar). Cada vez que a função é chamada, o ponteiro interno é movido para o próximo registro da consulta (query). Essa funcionalidade é útil para que possamos mostrar todas as tuplas de uma determinada tabela. Veja:

/* Enquanto há elementos a serem atribuídos a variaável $minha_tupla,

* retorna o elemento propriamente dito, e um TRUE. */

while ($minha_tupla = mysqli_fetch_row($result_set) {

echo(‘<p>’); print_r($minha_tupla); echo(‘</p>’);

$output = $minha_tupla[1] // [1] é a coluna c_text.

inlcude(‘./output.html.php’);

}

No exemplo acima, cada vez que o while executar, a próxima tupla do result set (que é um array) será retornada e assinada à variável $minha_tupla, e então guardamos o valor do índice [1] (c_text) na variável $output. Essa variável é então mostrada através de um arquivo especial para isso, pois assim evitamos misturar html e php no mesmo código/arquivo. O conteúdo do arquivo output.html.php é simples:

<p><?php echo($output); ?></p>

A linha que contém o print_r() é usada para mostrar a estrutura da tupla. Útil para debugar.

mysqli_fetch_assoc()

Tudo o que falamos sobre mysqli_fetch_row() tambémse aplica para mysqli_fetch_assoc(). A diferença é que em vez de acessarmos os índices do array retornado com um valor numérico, usamos uma string, por que o array retornado é associativo (como o nome da função sugere).

while ($minha_tupla = mysqli_fetch_assoc($result_set) {

$output = $minha_tupla['c_author'];

include(‘./output.html.php’);

}

Note que passamos o exato nome da coluna na tabela mysql como o índice do array $minha_tupla.

mysqli_fetch_array()

Essa função é mais elaborada porque ele pode retornar tanto um array com índice numérico, associativo, ou ambos.

while ($tupla_array = mysqli_fetch_array($result_set, MYSQLI_BOTH)) {

$output = $tupla_array[2];

include(‘./output.html.php’);

$output = $tupla_array['c_text'];

include(‘./output.html.php’);

}

Veja um simples resumo dos três tipos.

/* Índice numérico. */

while ($tuple = mysqli_fetch_row($result_object)) {

$output = $tuple[1];

}

/* Índice associativo. */

while ($tuple = mysqli_fetch_assoc($result_object)) {

$output = $tuple['c_author'];

}

/* Índice ou numérico, ou associativo, ou ambos. */

while ($tuple = mysqli_fetch_array($result_object, MYSQLI_BOTH)) {

// MYSQLI_NUM

// MYSQLI_ASSOC

$output1 = $tuple[1];

$output2 = $tuple['c_author'];

}

Se encontrar um erro, quiser fazer uma sugestão, o seja lá o que for, pode postar nos comentários.

Indetação no Vim – Tabs e Espaços

Posted in Dicas, Linux, Vim by Fernando Basso on 11 de janeiro de 2012
======================================
= Indentação no Vim - Tabs e Espaços =
======================================

= Introdução =
--------------

Há duas maneiras de indentar um código fonte:
  1. com tabs reais, também chamado de hard tabs.
  2. com espaços no lugar de tabs (sim, o vim pode ser configurado para
     substituir uma tabulação por um certo número de espaços).

Há vantagens e desvantagens em cada um dos métodos. Há alguns artigos que
discutem o assunto na web, embora parece que mais pessoas preferem Espaços
no lugar de Hard Tabs, mas isso é pura questão de gosto, e cada caso é um
caso.

Basicamente temos as opções:
 1.     'tabstop' - altera a largura da tabulação (Tabs reais).
 2.   'expandtab' - causa espaços serem usados/inseridos no lugar de
                    caracteres Tab.
 2. 'softtabstop' - configura detalhadamente a quantidade de espaço a serem
                    inseridos quando a tecla Tab é pressionada.
 3.  'shiftwidth' - afeta o uso de ">>", "<<", modo normal, "Ctrl-t" e
                    "Ctrl-d" no Modo Insert, além de ter influência em como
                    indetação automática funciona.

Para iniciar , execute isso no vim:
    :set list 
    :set listchars=tab:T_ 

A partir de agora, toda vez que o vim "enxergar" um Tab real, ele vai
mostrar algo como "T_____" no lugar do tab, para que o Tab fique 
visualmente percebível.

Pra desabilitar basta fazer:
    :set nolist 


= Indentação com Hard Tabs Apenas =
-----------------------------------

Por padrão, o vim vem configurado com:
  tabstop = 8 
  softtabstop = 0 
  shiftwidth = 8 
  noexpandtab 

Independente da sua configuração, digite esta linha para testar
(simplesmente coloca os valores default):
    :set tabstop=8 softtabstop=0 shiftwidth=8 noexpandtab 
 
O que acontece então?
 1. Com essa configuração, pressionar a tecla Tab no modo insert insere um
    caractere Tab real, com largura de 8 colunas. 
 2. Nesse caso, o  deleta o caractere Tab (deleta 8 colunas), o
    que visualmente parece que vários espaços foram deletados ao mesmo tempo.
 3. No modo Normal, usar >> e <> e <> e <> e << insere ou deleta *4* espaços. O mesmo
    occorre ao se pressionar Ctrl-t e Ctrl-d no modo Insert.

= Espaços = Caso 4 =
--------------------

Mas (note o NOexpandtab): 
    :set tabstop=8 softtabstop=4 shiftwidth=4 noexpandtab 

Agora, 'noexpandtab' não está habilitado, e portanto, pressionar 
insere um Tab real (e não espaços no lugar do Tab). Se pressionar Tab, e
'tab=8', um Tab terá largura de 8 colunas.

Como você sabe, ">>", "<>" duas vezes.
Você vai notar que ele se transforma em um Tab real. Isso porque "tabstop=8"
e "shiftwidth=4", etão, 4 + 4 = 8. Se "tabstop=12", por exemplo, então
pressionar ">>" 3 vezes se gera uma Tab real, porque 4 + 4 + 4 = 12.  

Isso tudo acontece porque 'softtabstop' tem precedência sobre 'tabstop'.
Então, quando pressionamos, por exemplo, "Ctrl-t" uma vez, ele insere 4
espaços, mas quando pressionamos "Ctrl-t" uma segunda vez, ele diz "Hmm,
isso está igual a "largura" do 'tabstop', e então os 8 espaços são
deletados e um Tab real é inserido. Quando usamos , "Ctrl-d" ou
"<<", o processo inverso ocorre.


= Misturando - Caso 5 =
-----------------------

Vamos deixar 'tabstop' igual 4, com 'expandtab' desabilitado:
    :set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab 

 1. Agora, como 'tabstop' está igual 'shiftwidth' e 'expandtab', quando
    , ">>" ou "Ctrl-t" for pressionado, uma Tab real será inserida
    pois o Vim notou que as configurações estão iguais. Quando as
    configurações estão iguais.

NOTE que tabs reais e espaços antigos no arquivo continuam sendo o que eram.
O que pode mudar é o tamanho das Tabs reais, mas não o fato de serem Tabs
reais ou não. O que já era Tab real continua sendo Tab real, e o que era
(grupos) de espaços continuam sendo (grupos) de espaços (grupos de espaços
que por venturam tenham sido inseridos em lugar de Tabs reais).

= Possíveis Escolhas =
======================

= Hard Tabs (Tabs Reais) =
--------------------------
Quem prefere trabalhar com Tabs reais, uma boa escolha é deixar 'tabstop'
igual 'shiftwidth', pois eles trabalharão de maneira consistente e
homogênea. Espaços não serão usados.

= Espaços em vez de Tabs Reais =
--------------------------------
Deixar 'softtabstop' igual 'shiftwidth' assegura que ">>", "<<",
"Ctrl-t" e "Ctrl-d" adicionem e removam Tabs (não reais, pois agora é
substituída por espaços) com o mesmo comportamento de se adicionar e deletar
tabs pressionando a tecla  e . Ou seja, todos eles vão
adicionar ou remover o mesmo número de espaços - vão funcionar de forma
homogênea. Pode-se também, nesse caso (e alguns acham aconselhável), deixar
'tabstop' com o mesmo valor de 'shiftwidth' e 'softtabstop'.

-------------------------------------------------------------------------------

= Notas Finais =
---------------------

Saiba que o Vim permite configurar tudo isso de acordo com o 'filetype'. Por
exemplo, é possível configurar que arquivos "html" utilizem 2 espaços no
lugar do Tab, um arquivo em "C" utilize 4 espaços no lugar de um Tab, e
ainda, quando um arquivo "bash" for editado, um Tab real de 6 colunas seja
usado. Ou seja, quando o arquivo é aberto, o vim usa as configurações
predefinidas automaticamente.

Alguns exemplos.

Vamos criar os diretórios necessários:
    mkdir --parents ~/.vim/after/ftplugin/ 

Para HTML:
Criar o um arquivo chamado "html.vim" dentro do último diretório criado:
    vim ~/.vim/after/ftplugin/html.vim 

E coloque o seguinte conteúdo dentro do arquivo:
    set softtabstop=2 expandtab shiftwidth=2 


Para CSS:
Criar o arquivo css.vim, no mesmo diretório que do exemplo anterior:
    vim ~/.vim/after/ftplugin/css.vim 

E cole o seguinte conteúdo:
    set softtabstop=4 expandtab shiftwidth=4 


Para "bash", com Hard Tabs:
    vim ~/.vim/after/ftplugin/bash.vim 
E cole:
    set tabstop=6 softtabstop=6 shiftwidth=6 noexpandtab 


= Dica final =
--------------

Se você optar por usar Espaços no lugar de tabs, há uma maneira de inserir
Tabs reais sem ter que mudar temporariamente a configuração. Isto é
conseguido inserindo-se caracteres não imprimíveis literalmente. 

No vim, isso é muito fácil. Basta pressionar "Ctrl-v" no modo Inserte, e
então pressionar a tecla Tab em seguida. Passo-a-passo:

            vim --> abre o vim no terminal (poderia ser o gvim).
              i --> entra no modo insert na posição onde está o cursor.
         Ctrl-v --> pressionar a combinação "ctrl-v". Vai aparecer um
                    caractere parecido com um "^". Neste momento, o Vim está
                    esperando você digitar o caractere que termina a
                    sequência, no nosso exemplo, um .
           --> pressione Tab.
  "hello world" --> escreva "hello world" por que esse é um encantamento que
                    garante que você aprenda o conteúdo. Sempre foi assim em
                    todas as linguagens, e essa é a razão. São palavras
                    mágicas.

Como mesmo exemplo você poderia inserir um caractere  ou 
literalmente no texto.

Aqui está o arquivo que fiz no Vim, mas convertido para html. Tive que renomear para .pdf para fazer o upload. Depois de baixar, troque a extensão para .html novamente e abra no seu navegador favorito. Está bem colorido, facilitando a leitura.
Indentando_Código_Fonte_no_VIM

Referências:
------------
    
  No Vim:
    :help 'softtabstop'
    :help 'tabstop'
    :help 'shiftwidth'
    :help 'expandtab'

http://vimcasts.org/


http://vim.wikia.com/wiki/Indenting_source_code

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.