Mercado de trabalho – A vaga de PHP é sua…

As vezes vejo no Twitter algumas oportunidades de emprego para desenvolvedores, repasso algumas no twitter do O Desenvolvedor (follow us!) e tem algumas que são muito engraçadas tristes.

Exemplo de uma que li recentemente, de uma agência de SP e RJ:

Para uma vaga de web-developer Júnior:

Pré-requisitos:

  • Sólidos conhecimentos de HTML/CSS (W3C), JavaScript (Ajax), PHP e MySQL;

  • Experiência com administração remota de plataformas UN*X;

  • Entendimento de linguagens de programação de uso genérico (C/C++/Java/Perl/Python/etc);

  • Capacidade de elaborar soluções próprias em programação;

  • Possuir um portfólio online.

Desejável conhecimento de:

  • ActionScript 3;

  • Frameworks de JavaScript (jQuery/YUI/etc);

  • Shell scripting;

  • Especificações do protocolo HTTP/1.1;

  • Uso das APIs dos webservices (Flickr/Google/Twitter/YouTube/etc);

  • WordPress (elaboração de temas e/ou plugins).

 

Destaque para "linguagens de programação de uso genérico (C/C++/Java/Perl/Python)", especificações do protocolo HTTP/1.1 e shell scripting.

Oportunidade de trabalho…

A oportunidade existe desde que você seja um back-front-end developer com conhecimentos em gerenciamento e protocolo de redes, domine frameworks e algumas linguagenzinhas genéricas que vão do ASP, PHP, Python até o Cobol.

Profissional transformer
(ou o famoso tapa-buraco)

 

Mas nem tudo é tristeza, ainda existem algumas empresas que conseguem dividir e focar em pessoas com conhecimentos específicos. Mas só algumas, enquanto isso o Roberto Justus tem uma mensagem a você, que está procurando uma vaga de programador PHP:

 

E você, quer compartilhar sua opinião sobre o mercado de trabalho para programadores? Comenta aí!

Como pegar o IP de um usuário com o PHP

Sem rodeios, sem mimimi´s, este deve ser o post mais curto já visto aqui no O Desenvolvedor, uma função para pegar o IP do usuário utilizando o PHP.

Usando getenv (para pegar "variáveis do ambiente"):

// Example use of getenv()
$ip getenv("REMOTE_ADDR");

 

E usando a variável superGlobal $_SERVER


// Or simply use a Superglobal ($_SERVER or $_ENV)
$ip $_SERVER["REMOTE_ADDR"];

 

Pronto, simples assim.

Precisei disto para um controle em um método do novo And After e resolvi compartilhar, apesar já ser de conhecimento de qualquer um que domine o PHP pode ajudar alguns n00bs como eu, que ainda não conhecem a sintaxe de cabo a rabo.

 

Direto do PHP Manual

Gerador de senha aleatória em PHP [UPDATE]

Continuando com a série de posts sobre PHP, segue um script que foi útil para o desenvolvimendo do novo And After.

Por questões de segurança a senha dos usuários ficam criptografadas no banco (MD5) e o processo é irreversível (pelo menos em teoria) – isso impede a recuperação delas e cria a necessidade de regerar uma senha aleatória caso o usuário esqueça a sua.

Baseado em em um script da webtoolkit fiz algumas alterações (insignificantes) para atender exatamente ao que eu precisava, abaixo segue a função generatePassword que recebe um único parâmetro ($length) que indica o tamanho do password gerado.

 

function generatePassword($length) {
  $vowels = "aeiouyAEIOUY";
  $consonants = "bdghjmnpqrstvzBDGHJLMNPQRSTVWXZ0123456789";
  $password = "";
  $alt = time() % 2;
  for ($i = 0; $i < $length; $i++) {
    if ($alt == 1) {
       $password .= $consonants[(rand() % strlen($consonants))];
       $alt = 0;
    } else {
       $password .= $vowels[(rand() % strlen($vowels))];
       $alt = 1;
    }
  }
  return $password;
}

O script tem 2 conjuntos de caracteres (nas variáveis vowels e consoants) e intercala um caractere randômico de um grupo com um caractere randômico de outro grupo até a string (nosso password) atingir o tamanho requisitado.

[update]

O Carlos André Ferrari comentou uma outra função, com menos código porém sem intercalar os grupos de caracteres (vogais e consoantes) para gerar a senha, porém igualmente funcional:

function generatePassword($length=6) {
	return substr(str_shuffle("aeiouyAEIOUYbdghjmnpqrstvzBDGHJLMNPQRSTVWXZ0123456789"), 0, $length);
}

[/update]

 

Se você quiser aumentar o nível de segurança pode inserir caracteres especiais em uma das variáveis da string usada…

Selecionando posts relacionados pelas tags (Code Igniter com Data Mapper)

Desenvolvendo o backend da nova versão do And After resolvi aprimorar o sistema de recomendações de posts relacionados do site e torná-lo mais relevante para os leitores.

Para acompanhar este post é necessário entender sobre relacionamento no banco de dados, saber um pouco como funciona o Data Mapper, a ferramenta ORM e também ter uma noção de relacionamento de tabelas com o Data Mapper.

Posts relacionados – Como funciona hoje?

Atualmente o sistema pega as tags de um post e, uma a uma, busca outros posts que utilizem a mesma tag. Estes posts são exibidos (sem repetição) e com um limite estipulado.

Isso significa que as últimas tags do post que o leitor está lendo podem ser ignoradas – pois possivelmente com as primeiras tags o sistema de relacionamento já tem posts suficientes para uma lista de recomendação.

 

Como deveria funcionar?

Para "afinar" o sistema de recomendação o ideal é levar em consideração todas as tags de dois posts que podem ser similares e ver quantas tags eles tem em comum. Quanto mais tags em comum, mais relacionado está o texto – porém não podemos esquecer de levar em consideração a data de publicação do mesmo, para evitar ficar exibindo apenas posts muito antigos.

 

Tecnologias

Estou utilizando PHP com o framework Code Igniter (tudo bonitinho com MVC) e banco de dados MySQL, a ferramenta ORM utilizada é o Data Mapper (leia também: como instalar e configurar o Data Mapper no Code Igniter).

Para atingir o objetivo criei a seguinte regra de negócio:

  • Percorrer cada tag que o post atual tem e buscar os posts recentes que contém esta mesma tag.
  • Atribuir um "ponto" para cada vez que um post é encontrado
  • Ordenar a lista de posts relacionados pelos "pontos" (número de vezes que um post retornou como relacionado do atual)

 

Vamos ao código! A função abaixo recebe duas variáveis: $post (o id do post que o usuário está lendo) e $limit (quantos posts relacionados devem retornar no array de resultado).

function getRelatedPost($post, $limit) {
  //Pega o post atual e suas tags
  $p = new Post();
  $p->select("id");
  $p->where("id", $post);
  $p->get(1);
  $tags = $p->tag->get();
  $arr = array();
  //Percorre as tags do post atual
  foreach($tags as $t){
    //pega os posts relacionados pela tag
    $related = new Post();
    $related->where_related_tag("id", $t->id);
    $related->where("id <>", $post);
    $related->order_by("creationDate DESC");
    $related->get($limit);
    //Se existirem posts, percorre cada post relacionado para esta tag
    if(!empty($related->id)){
      foreach($related as $pr){
        //Se o post já existir no array soma mais um ponto para ele
        //Se ele não existir cria ele no array com valor 1
        $id = $pr->id;
        if(!empty($arr[$id])){
          $arr[$id] = ($arr[$id]+1);
        }else{
          $arr[$id] = 1;
        }
      }
    }
  }
  //Ordena o array pelos pontos
  //e pega cada post relacionado para retornar como resultado
  arsort($arr, SORT_REGULAR);
  $relArr = array();
  foreach ($arr as $i => $value) {
    $relArr[] = $this->getPostById($i);
  }
  return($relArr);
}
 
 
 
Lembrando que estou utilizando a versão OverZealous do Data Mapper, que foi desenvolvida como um upgrade da versão padrão desta ferramenta.
 
E agora o que rola por trás deste código todo, que o Code Igniter retorna no benchmark para os curiosos de plantão:
 
 
SELECT `tags`.*
FROM (`tags`)
LEFT OUTER JOIN `posts_tags` as posts_tags ON `tags`.`id` = `posts_tags`.`tag_id`
LEFT OUTER JOIN `posts` as posts ON `posts`.`id` = `posts_tags`.`post_id`
WHERE `posts`.`id` = 8 
 
 
SELECT `posts`.*
FROM (`posts`)
LEFT OUTER JOIN `posts_tags` as posts_tags ON `posts`.`id` = `posts_tags`.`post_id`
LEFT OUTER JOIN `tags` as tags ON `tags`.`id` = `posts_tags`.`tag_id`
WHERE `tags`.`id` = 14
AND `posts`.`id` <> 8
ORDER BY `posts`.`creationDate` DESC
LIMIT 5 

 

Qualquer dúvida, correção ou melhoria no código comente! 🙂