Vamos supor que você tenha um sistema que armazene documentos dos usuários em uma pasta no seu servidor, porém para manter uma estrutura mais organizada, você separa os documentos em sub-pastas de acordo com o ano. Normalmente você se preocupa em fazer backup do banco de dados, porém e os arquivos desta pasta?

É indiscutível que em qualquer sistema online que armazene arquivos no servidor possua uma estrutura de backup. Uma opção interessante é manter uma cópia desses arquivos em algum serviço de armazenamento na nuvem. Hoje em dia temos diversos serviços desse tipo, porém falaremos especificamente do Dropbox neste artigo.

Veremos neste artigo como copiar uma pasta que está no servidor para uma pasta no Dropbox de forma recursiva, ou seja, copiando todos os arquivos da pasta e de suas sub-pastas.

Registrando aplicativo no Dropbox

Primeiramente, se você não tem uma conta no Dropbox, deverá criar uma. Após criado a conta e fazer login, você deve ir até a área de desenvolvedores e registrar um novo aplicativo.

Imagem 1 – Criando aplicativo

Como precisamos de acesso aos arquivos, selecionamos a opção Dropbox API (1). No tipo de acesso selecionamos a opção App folder (2), pois não precisamos acessar todos os arquivos, apenas de uma pasta especifica para copiarmos nossos arquivos. Por último, escolhemos um nome (3) único para nosso aplicativo.

Após registrado o aplicativo, você será redirecionado para as configurações dele. Nessa página, precisaremos gerar um token, que será utilizado para termos acesso ao Dropbox a partir do nosso aplicativo.

Imagem 2 – Gerando token

Basta clicar no botão Generate e copiar o token que será gerado. Não passe esse token para ninguém, pois ele permite que uma pessoa acesse os arquivos do aplicativo no Dropbox.

Biblioteca para comunicação

Agora que já temos um token para acessar o Dropbox, vamos começar nosso aplicativo. Neste artigo, vamos utilizar a biblioteca da própria empresa para facilitar a comunicação com o serviço deles.

A biblioteca possui os seguintes requerimentos:

Para importar a biblioteca para nosso projeto, vamos utilizar o Composer (se você não estiver familiarizado com ele, dê uma olhada neste artigo). Portanto, vamos criar nosso composer.json.

Por fim, basta rodar composer install no terminal para baixar a biblioteca na pasta vendor. Feito isso, já podemos utilizá-la.

OBS: Se o servidor que você vai rodar o aplicativo utiliza Windows 32/64 bits ou Linux 32-bits, a biblioteca não vai funcionar, pois ela necessita de 64-bit integers. Porém, você pode comentar a exceção no arquivo \lib\Dropbox\RequestUtil.php da biblioteca como nesta sugestão. Não é o ideal, mas resolve o problema.

Criando classe para backup

Para facilitar ainda mais as coisas vamos criar uma classe que será responsável por fazer o envio dos arquivos para o Dropbox.

No construtor da nossa classe, vamos receber o token e o nome do aplicativo para que possamos instanciar um novo objeto da biblioteca do Dropbox.

Agora que já temos o objeto para comunicação com o Dropbox, vamos criar um método básico para enviar um único arquivo.

Armazenamos o arquivo passado por parâmetro em uma variável e então utilizamos o método uploadFile() da biblioteca para enviarmos o arquivo no caminho especificado do Dropbox. Por fim, para simplificar mostramos uma mensagem para saber que o arquivo foi copiado, porém o mais interessante seria registrar isso em um arquivo de log (utilizando monolog, por exemplo).

Agora que já temos um método para enviar um arquivo único, vamos criar o método para enviar uma pasta inteira de forma recursiva.

Tentei detalhar o máximo possível nos comentários, porém vamos tentar detalhar ainda mais:

  • Linha 17: Utilizamos a classe DirectoryIterator do PHP, que permite listar os arquivos e pastas de um caminho;
  • Linha 20: O método getMetadataWithChildren() da biblioteca retorna os dados de uma pasta, inclusive seus arquivos. Assim podemos comparar se o arquivo que estamos enviando já existe no Dropbox, para não precisar enviar novamente. O desempenho é melhor ao utilizar esse método para conseguir todos os dados da pasta de uma vez, ao invés de verificar arquivo por arquivo;
  • Linha 26 a 28: Quando utilizamos o DirectoryIterator,  além dos arquivos e pastas ele nos retorna ‘.’ e ‘..’, portanto se for esse o caso, ignoramos e passamos para o próximo item;
  • Linha 31 a 35: É aqui que a mágica da recursividade acontece. Se o item atual for uma pasta, chamamos o nosso método novamente, porém passamos como parâmetro esta pasta, assim todo o processo será feito novamente nesta pasta. E se esta pasta possuir sub-pastas, o método será chamado novamente, e assim sucessivamente, até chegar no último nível.
  • Linha 38 a 47: Por fim, testamos se o item atual é um arquivo. Se for, verificamos se ele já existe na pasta atual do Dropbox, utilizando o método checkIfRemoteFileExistsFromMetadata() que criaremos adiante. Se não existir, fazemos o upload dele utilizando o método uploadFile() que criamos anteriormente.

OBS: Esse método apenas copia os arquivos do servidor para o Dropbox, porém não apaga os arquivos do Dropbox, caso ele tenha sido excluído no servidor. Para isso seria necessário implementar um outro método que faria o processo inverso, passaria recursivamente pelos arquivos no Dropbox e se não existisse no servidor, apagaria ele.

Para finalizar, vamos criar o método para verificar se o arquivo já existe no Dropbox.

Utilizando a classe

Agora que já fizemos o trabalho pesado, basta utilizar a classe.

Acredito que nenhuma novidade aqui. Incluímos o arquivo de autoload do Composer e nossa classe. Utilizamos a função set_time_limit() para que o script possa ser executado até todos os arquivos serem copiados, já que esse processo pode ser bem longo. Por fim, instanciamos um objeto de nossa classe e chamamos o método para copiar a pasta documentos do servidor para a pasta documentos na raiz do Dropbox.

Para testar, vamos executar o arquivo que criamos através do terminal (você pode abrir pelo navegador também se preferir), você deverá ver um retorno parecido com o abaixo.

Vamos acessar o Dropbox agora para ver se os arquivos foram realmente enviados. Se deu tudo certo, você deve ver as pastas e os arquivos assim como na Imagem 3.

Imagem 3 – Arquivos no Dropbox

Automatizando o processo

Maravilha, conseguimos fazer backup dos nossos arquivos na nuvem, porém para isso acontecer você deverá executar o arquivo backup.php toda vez manualmente. Tudo bem, você pode chamar esse trecho de código em alguma momento no seu projeto ou então criar um botão para que o próprio usuário faça o backup. Porém, o ideal neste caso seria automatizar o processo.

Se o seu projeto estiver em uma hospedagem compartilhada, verifique se no painel você não tem a opção de criar um CronjobUm Cronjob é nada mais que uma tarefa agendada para a execução de um comando. Sendo assim, você poderia agendar um comando (cURL normalmente) para chamar o backup.php uma vez por semana, por exemplo.

Caso seu projeto esteja hospedado em um servidor Linux em uma VPS (Virtual Private Server) e você tem acesso ao servidor via SSH (Secure Shell), você pode criar um Cronjob manualmente.

Enfim, não vou entrar em detalhes sobre como criar um Cronjob, pois existem diversos tutoriais excelentes na internet, porém acredito que está seja a melhor solução para automatizar o processo. Caso você tenha dificuldades em montar a sintaxe do Cronjob, este site é de grande ajuda.

Conclusão

Neste artigo foi apresentado uma forma de fazer o backup em nuvem dos arquivos que estão no servidor. Utilizamos o Dropbox, porém o conceito se aplica a qualquer serviço, o que muda é apenas a biblioteca que utilizaremos para consultar e enviar os arquivos.

Vale lembrar que você deve ficar atento as limitações do serviço, como espaço de armazenamento e limite de requisições diárias. Em um projeto simples, com poucos arquivos ou arquivos leves isso não faz diferença, porém se você tiver muitos arquivos ou arquivos muito pesados, talvez você tenha que adaptar o código para esta situação.

Espero que de alguma forma este artigo tenha sido útil para que você possa fazer backup dos seus arquivos.

Código fonte disponível em: https://github.com/rafaelcouto/Post1498

Referências

Compartilhe
Share on Facebook0Share on Google+0Tweet about this on TwitterPin on Pinterest0Email this to someone