Diferença entre dias

Vamos iniciar com uma função que realiza a diferença entre duas datas e retorna a quantidade de dias entre estas duas datas. Observe a Listagem 1.

Listagem 1. Função para diferenciação de dias


  <?php
  function diferenca_dias($inicial, $final) {    
      $inicial = strtotime($inicial); 
       // 07/04/2003 (mm/dd/aaaa) data menor
      $final = strtotime($final);    
       // 07/10/2003 (mm/dd/aaaa) data maior
      return ($final - $inicial) / 86400; 
      //transformação do timestamp em dias
  }
  ?>

O método acima é simples, mas muito eficaz. Dada a data inicial e final no formato DD/MM/YYYY ele faz o cálculo que é resultado em timestamp, mas converte para dias com a divisão por 86400 ao fim da função.

Limpador de Strings

Algo muito comum é converter uma palavra cheia de acentos para uma sem acentos, como no padrão americano. A nossa função limpaString tem esse objetivo: remover os acentos e caracteres como “ç” da nossa string. Observe a Listagem 2.

Listagem 2. Removendo acentos


  <?php
  function limpaString($string) {
      $array1 = array("á", "à", "â", "ã", "ä", "é", "è", "ê", "ë", "í", 
       "ì", "î", "ï", "ó", "ò", "ô", "õ", "ö", "ú", "ù", "û", "ü", "ç"
          , "Á", "À", "Â", "Ã", "Ä", "É", "È", "Ê", "Ë", "Í", "Ì", "Î", 
         "Ï", "Ó", "Ò", "Ô", "Õ", "Ö", "Ú", "Ù", "Û", "Ü", "Ç");
      $array2 = array("a", "a", "a", "a", "a", "e", "e", "e", "e", "i"
        , "i", "i", "i", "o", "o", "o", "o", "o", "u", "u", "u", "u", "c"
          , "A", "A", "A", "A", "A", "E", "E", "E", "E", "I", "I", "I",
           "I", "O", "O", "O", "O", "O",
             "U", "U", "U", "U", "C");
      $string = str_replace($array1, $array2, $string);
      $newstring = preg_replace("/[^a-zA-Z0-9\s_.]/", "", $string);
      return $newstring;
  }
  ?>

Simples, prático e eficaz. É algo muito comum para pesquisas no banco de dados com mais eficácia.

Remove diretórios recursivamente

A remoção de diretório em PHP é algo relativamente simples, mas e quando temos arquivos e diretórios dentro do diretório? Torna-se algo um pouco mais complexo, pois devemos remover todo conteúdo recursivamente, e este é o objetivo da nossa função na Listagem 3.

Listagem 3. Remover diretórios de forma recursiva


  function removeTreeRec($rootDir)
  /**
   *  Função recursiva para remover um diretório sem ter que apagar
     manualmente cada arquivo e pasta dentro dele *
   *
   */ {
      if (!is_dir($rootDir)) {
          return false;
      }
   
      if (!preg_match("/\\/$/", $rootDir)) {
          $rootDir .= '/';
      }
   
   
      $dh = opendir($rootDir);
   
      while (($file = readdir($dh)) !== false) {
          if ($file == '.' || $file == '..') {
              continue;
          }
   
   
          if (is_dir($rootDir . $file)) {
              removeTreeRec($rootDir . $file);
          } else if (is_file($rootDir . $file)) {
              unlink($rootDir . $file);
          }
      }
   
      closedir($dh);
   
      rmdir($rootDir);
   
      return true;
  }

A função acima é muito “perigoso”, por isso use com cuidado. Uma remoção errada pode causar um dano irreversível, pois se lembre, a função acima remove os diretórios e subdiretórios juntamente com todos os arquivos sem exitar.

Captura arquivos de um diretórios

Na função da Listagem 4 vamos capturar todos os arquivos do tipo que desejamos de um determinado diretório, ou seja, podemos utilizar esta função para capturar todas as imagens JPG do diretório '/home/usuario/Downloads/'.

Listagem 4. Função para capturar arquivos de diretório


  function get_files_dir($dir, $tipos = null){
        if(file_exists($dir)){
            $dh =  opendir($dir);
            while (false !== ($filename = readdir($dh))) {
                if($filename != '.' && $filename != '..'){
                    if(is_array($tipos)){
                        $extensao = get_extensao_file($filename);
                        if(in_array($extensao, $tipos)){
                            $files[] = $filename;
                        }
                    }
                    else{
                        $files[] = $filename;
                    }
                }
            }
            if(is_array($files)){
                sort($files);
            }
            return $files;
        }
        else{
            return false;
        }
  }
   
  function get_extensao_file($nome){
      $verifica = explode('.', $nome);
      return $verifica[count($verifica) - 1];
  }

A função “get_extensao_file” auxilia a função principal “get_files_dir”, ou seja, ele retorna a extensão exata de um arquivo utilizando a função explode.

Validador de Proporção de Imagem – Aspect Ratio

Esta é uma funçao não muito comum, mas pode ser útil em diversos casos. Pense na seguinte situação: você tem um sistema onde são enviadas diversas imagens diárias, mas você, de forma alguma, pode distorcer as imagens enviadas pelo usuários.

Porém os tamanhos das imagens são muito diversificados e você precisa colocar essas imagens em um local onde todas tenham o mesmo tamanho. Imagine que João envia uma imagem de 1200x800 e Maria uma de 500x120, porém no local onde você deve por essas duas imagens ambas devem estar em 400x300, e obviamente as duas irão distorcer perdendo e muito a qualidade original.

Como resolver esse problema ? Trabalhando com Aspect Ratio. Em vez de definir que todos os usuários devem mandar imagens em 400x300, você pode dar “mais liberdade” a eles dizendo que as imagens podem ter proporção de 4:3, isso significa que de: 1200x900, 500x375 e assim por diante, podem ser redimensionadas para 400x300 sem distorção.

Mas como validamos se a imagem enviada pelo usuário tem o aspect ratio de 4:3 ? É para isso que utilizaremos a função da Listagem 5.

Listagem 5. Validando Aspect Ratio


  function isValidAspectRatio($largura, $altura, $proporcao){
      
      //Fórmula: proporcao x new width = new height   
      $novaAltura = $proporcao * $largura;
      
      /*
       * A tolerância de diferenças entre a altura da imagem e 
       * a altura que deveria ser será de 2.0, ou seja, se
       * a imagem passada tiver 2px de altura a mais do que 
       * a altura gerada pela fórmula, o aspectRatio será invalidado.
       */
      $diferencaCalculada = abs($novaAltura - $altura);
      
      if ($diferencaCalculada > 2.0){
          return false;
      }else{
          return true;
      }    
              
  }
  

Bom, a nossa função acima ainda tem algo chamado “tolerância de aspect ratio”. Pois imagine se o usuário tiver que enviar exatamente 500x375 pixels, nem um a menos nem um a mais. Acho que não precisamos de toda essa exatidão, então podemos abrir um intervalo de 2px para mais ou para menos, isso da a possibilidade de o usuário enviar uma imagem de 500x373 e ainda ser validada. Mas caso você ainda ache 2px muito pouco, pode abrir para 10px ou mais, fique a vontade, mais cuidado para não distorcer a imagem dando uma tolerância muito alta.

Imagine agora que o usuário não faz ideia de como deixar sua imagem de 1200x800 na proporção de 4:3, precisamos então criar funções específicas para auxilia-lo. Observe a Listagem 6.

Listagem 6. Funções para retornar altura e largura ideais


  function retornarAlturaProporcional($largura, $proporcao){
      
      //Fórmula: proporcao x new width = new height   
      return round($proporcao * $largura);    
              
  }
   
  function retornarLarguraProporcional($altura, $proporcao){
      
      //Fórmula:  new width = new height / (proporcao)    
      return round($altura / $proporcao);    
              
  }

Então, se o usuário tiver uma imagem de 1200x800 e quiser mudar a proporção para 4:3 sem distorcer, ele poderá usar uma das funções acima e verificar qual a altura ou largura proporcional, mudando apenas uma das dimensões da imagem. No caso 1200x800 tornar-se-ia 1200x900, assim como se quisesse manter os 800, o 1200x800 tornar-se-ia 1067x800. Teste e comprove.

Importante lembrar que a variável $proporcao nada mais é do que 4/3 = 1,33 (na verdade uma dízima periódica). Você poderia usar outras proporcionalidades como 16:9, 13:7 e assim por diante. Caso queira ficar mais por dentro dos cálculos realizadas para chegar a estas proporções, aconselhamos fortemente a leitura de artigos e livros sobre Aspect Ratio ou Proporção de Telas.

Com isso, o principal foco deste artigo foi demonstrar o uso de algumas funções úteis para projetos em PHP, muitos deles utilizados com muito frequência.

O Aspect Ratio na verdade é uma sugestão para melhoria de tratamento de imagens em sistemas que fazem uso de tal recurso, assim evitamos “amarrar” o usuário em imagens de tamanho fixo, trabalho com proporção sem distorcer a imagem. O foco maior foi neste aspecto, pois trata-se de um assunto não tão comum como as outras funções mencionadas nas seções anteriores, precisando assim de uma explicação mais detalhada e conclusiva ao ponto de deixar você leitor a par de toda informação necessária para uso deste recurso.