PHP Como verificar se um Array é 100% ASSOC

function isFullyAssoc($array) {
  return count(array_filter($array, 'is_string', ARRAY_FILTER_USE_KEY)) === count($array);
}

echo isFullyAssoc(['x' => 'xis', 'banana', 1, true]); // false
echo isFullyAssoc(['x' => 'xis', 'y' => 1, 'z' => true]); // true

Pois é, não sei quando você vai precisar validar se um array possui todos os elementos indexados com chave associativa, mas eu precisei hoje.

Independentemente da necessidade, achei legal apresentar esta solução por que não encontrei muito material navegando pela internet.

Como o PHP não possui uma função nativa para esta validação o jeito foi improvisar mesmo, então vamos explicar o conceito do enjambre.

Utilizamos ARRAY_FILTER para segregar todos os elementos cujos índices sejam do tipo STRING. Para isto basta informar a própria função IS_STRING do PHP como CALLBACK function.

Além disto temos que especificar para ARRAY_FILTER que queremos observar os índices, e não os valores, do array no processo de filtragem. Assim devemos informar o terceiro argumento ARRAY_FILTER_USE_KEYS.

No final basta comparar a quantidade de elementos filtrados com a quantidade de elementos da array original. Se houver divergência nesta comparação isto indica seguramente que algum índice do array original não era ASSOC.

Afinal de contas, ARRAY é masculino ou feminino? Vai saber, depois de escrito o texto percebi que mesclei os gêneros, mas no review final ficou menino mesmo!

PHP Array Destructuring… retornando array associativa para variáveis escalares

function func_return_array_assoc() {
  return [ 
    'index1' => 'content1',
    'index2' => true,
    'index3' => 1001,
    'index4' => 0.115,
    'index5' => null,
    'index6' => array(),
  ]; 
}

[
  'index2' => $my_bool_var,
  'index3' => $my_int_var,
  'index1' => $my_string_var,
] = func_return_array_assoc();

echo $my_int_var; // 1001 
echo $my_bool_var; // true
echo $my_string_var; // content1

Pois é pessoal, recentemente esta técnica de programação me chamou a atenção.

No início eu não conseguia compreender muito bem como isto funcionava, então tive de me aprofundar mais e acabei encontrando algo chamado Array Destructuring e o que apresento aqui neste artigo é apenas uma parte do que realmente é abrangido por este tema.

Primeiro vamos entender como funciona este mecanismo. Quando você iguala dois arrays associativos o PHP vai fazer um match dos índices nas duas arrays. Os índices que fizerem match serão igualados e os demais serão desprezados. Observe também que o match não é posicional, assim o array pode ser construído de forma diferente de cada lado.

A grande sacada vem na utilização de variáveis escalares na parte VALUE em um dos lados da array, desta forma durante o processo do match antes de tentar processar a igualdade o PHP primeiro atribui os valores nas variáveis.

Não conseguiu visualizar onde poderia usar esta técnica de forma eficiente?

Então responda, como é que uma função pode retornar mais de um valor? Certo, com um array ou um objeto. Mas e se construir um objeto está fora de cogitação (esforço desnecessário), onde recai a solução? Certo novamente, ARRAY.

E como você faz para receber o resultado de uma função que é um ARRAY? Boa! Você atribui o resultado a uma $variavel_array. Ou então, pode usar o famoso list para receber posicionalmente, certo?

Acho que agora deve ter caído a ficha… ao invés de usar o LIST do PHP para receber o array e atribuindo a variáveis escalares de forma posicional, esta técnica permite fazer isto através do match dos índices atribuindo somente os valores desejados sem se preocupar com o posicionamento.

Que loco! E pensar que já falei com muito dev que critica muito o ARRAY do PHP. Mais loco ainda….

Para quem quiser se aprofundar mais no tema recomendo dar uma olhada no blog Stitcher.io, segue o link:

https://stitcher.io/blog/array-destructuring-with-list-in-php

GIT Rebase com Git Pull durante atualização da Branch

git pull --rebase origin master --autostash

Quem se lembra de quando começou a trabalhar com GIT e tinha medo de fazer um rebase e melar a branch atual?

Pois é, o rebase na verdade é uma ação muito tranquila de ser executada, ainda mais se utilizarmos como opção de outro comando amplamente conhecido e dominado por todos.

Isso mesmo, fazer o rebase durante a atualização da branch é possível, e sinceramente, depois de ter aprendido esta forma não me recordo de ter utilizado o git rebase isoldamente.

Explicando o comando acima, fazer um git pull é super tranquilo certo? Você faz o pull quando precisa trazer as atualizações do servidor para a sua branch local, ponto. Mas o que acontece se você ja tem um commit nesta sua branch local?

Isso mesmo, para que o seu commit fique no topo da pilha você precisa fazer um rebase. Assim o Git gentilmente lhe dá a opção de fazer o rebase no mesmo momento de atualizar a branch.

A opção –autostash ajuda quando você possuir alterações ainda sem commit, assim você economiza mais um tanto e não precisa fazer o stash manual antes de atualizar a branch.

Mágico, não?

PHP Array Anônimo, uma técnica não tão conhecida assim…

echo [
    'index1' => 'content1',
    'index2' => 'content2',
    'index3' => 'content3',
    'index4' => 'content4',
]['index3'] ?? 'Conteúdo não encontrado';

Você consegue definir qual a saída obtida pelo código acima? Talvez não, mas não se preocupe você não está sozinho.

Esta técnica de programação nem possui um nome bem definido, o melhor que consegui identificar na internet seria Array Anônimo, mas ainda assim com muitas divergências de opiniões sobre o tema. Não importa, vamos entender como tirar proveito disto.

Primeiro vamos entender o código acima postando um exemplo mais simples.

echo [ 'index1' => 'content1']['index1'];

Melhorou? Que tal simplificar para algo mais usual, mais conhecido pelos devs.

$y = array('index1' => 'content1');
echo $y['index1'];

E agora? Ficou mais familiar? Reconhece esta sintaxe do PHP Array?

Então, Array Anônimo nada mais é do que utilizar o conteúdo de um Array sem ter que definir este conteúdo em uma variável nomeada. Vamos a mais um exemplo possível.

foreach ([
  'index1' => 'content1',
  'index2' => 'content2',
  'index3' => 'content3',
  'index4' => 'content4'
] as $index => $value) {
  echo 'Index: ' . $index . ' Value: ' . $value;
}

Até aqui o objetivo foi descrever o mecanismo do array anônimo. Acredito que foi possível entender o funcionamento do mecanismo através dos exemplos simplificados.

Mas qual a aplicação prática real desta técnica de programação? Para que serve? Como posso tirar proveito disto? Bom, a resposta é simples.

  • Qualidade de código (clean code)
  • Programação sem ramificações (branchless programming)

Para exemplificar esta aplicabilidade, vamos considerar o seguinte cenário. Temos uma aplicação que roda em múltiplos servidores e precisamos obter uma chave secreta dada uma lista de servidores.

class ServerSecret {
  public static function mySecret($servername) {
    return [ 
      'server1' => 'xyz',
      'server2' => 'wsx',
      'server3' => 'oiu',
    ][$servername] ?? self::throwInvalidServer($servername);
  }

  private static function throwInvalidServer(string $servername) {
    throw new \LogicException(
      sprintf('Servidor %s não foi encontrado', $servername);
    );
}

Pronto, temos aí uma aplicação concreta para o uso do Array Anônimo. Você não precisa se ater muito ao que o código está fazendo, até por que é possível obter o mesmíssimo resultado codificando sintaxes diferentes.

O mais importante de se observar é como o código foi organizado, limpeza, clareza, funcionalidade e principalmente a ausência de IFs e ramificações de códigos.

Para quem quiser se aprofundar um pouco mais no assunto recomendo pesquisar por Branchless Programming.

GIT Configurando comportamento padrão para Git Status e Git Push na linha de comando

git config --global status.showuntrackedfiles all
git config --global push.default current

Operar o Git através de ferramentas gráficas é muito fácil, mas este não é o ambiente nativo disponibilizado pela ferramenta.

Saber operar o Git pela linha de comando é o máximo, mas leva algum até você conseguir dominar a sintaxe e memorizar os principais comandos. Além disso, o ambiente pode ser configurado para se comportar adotando alguns padrões pré-estabelecidos que são muito usuais, assim você acaba economizando na digitação e também nos erros.

Os comandos acima são dois padrões que eu costumo configurar logo após instalar o Git.

A primeira configuração faz com que o comando git status mostre os arquivos novos criados que ainda não foram adicionados ao repositório. Sem este default configurado seria necessário informar um argumento opcional –untracked-files para visualizar os arquivos novos. Os comandos abaixo irão listar todos os arquivos novos.

git status -u
git status -uall
git status --untracked-files
git status --untracked-files=all

A segunda configuração faz com que o comando git push envie os commits para o servidor remoto atualizando a branch com o mesmo nome da branch local. Sem este default configurado seria necessário informar adicionalmente o local do repositório e o nome da branch remota. Os comandos abaixo representam a forma de fazer o push dos commits para a branch desejada, neste exemplo enviando para a mesma branch localmente posicionada.

git checkout master
git commit -m "commit your changes"
git push origin master

git checkout -b first-branch
git commit -m "commit your changes"
git push origin first-branch

Lembrando que você pode a qualquer momento verificar as configurações correntemente válidas para o seu ambiente ou ainda remover alguma configuração indesejada.

git config --list
git config --unset status.showuntrackedfiles 

Obviamente existem muitas outras personalizações que podem ser configuradas, mas estas duas eu considero essenciais para a operação do dia a dia.