Check if a file exists on the remote machine via FTP in PHP

Asked

Viewed 1,914 times

4

How can I check if a file exists on the remote machine using PHP via FTP (English) in order to act accordingly?

<?php
$ficheiro = 'public_html/banana.xml';

$id_ligacao = ftp_connect($servidor_ftp);

$login = ftp_login($id_ligacao, $utilizador, $password);

// verificar se ficheiro existe
if (ficheiro_existe($ficheiro)) { // função para ilustrar o conceito
  echo "existe!";
} else {
  echo "não existe!";
}

ftp_close($conn_id);
?>
  • The quick response is "use ftp_size()". The long answer is down below, with considerations about alternatives, including cache suggestion.

4 answers

2


I believe that using the file_exists function can solve your problem more simply:

if(file_exists('ftp://usuario:[email protected]:porta/caminho/do/arquivo')) ...
  • It does sound very simple, but am I subject to false negative? That is, if there is a problem establishing connection and/or problem with access credentials will indicate to me that the file does not exist, right?

  • Yeah, if you miss the password, you’ll never know if it even exists. I haven’t tried it, but I think in case of error it will return FALSE, but the $php_errormsg variable will have an error message.

2

The best suggestion (and apparently the most voted) is ftp_size, since it neither opens the file nor loads the entire listing of your folder.


I have not tested or compared restrictions, the fopen should also work elegantly, avoiding the "false negative" of file_exists (see @Zuul’s comment on @mlemos response) when we analyze errors.

Next we have the suggestion of ftp_nlist, which "kills the ant with elephant", but can have its array curled and then reused in other checks (!), ie, can be an optimal solution in certain cases.


ftp_file_exists() with last folder cache

The use of specialized FTP functions requires some preparation. Here I copy a part of the answer (also well approved!) from https://stackoverflow.com/a/9568577/287948

It’s a more convoluted version of @Paulorodrigues' reply, where I added the commented preparation and suggested cache before.

  function ftp_file_exists(
      $file,                     // o arquivo que se procura
      $path = "/SERVER_FOLDER/", //pasta onde ele está
      $ftp_server = "ftp.example.com",
      $ftp_user = "ftpserver_username", $ftp_senha = "ftpserver_password",
      $useCache = 1
  ) {

      static $cache_ftp_nlist=array();
      static $cache_assinatura='';

      $nova_assinatura = "$ftp_server$path";
      if (!$useCache || $nova_assinatura!=$cache_assinatura) {
          $useCache = 0;
          $nova_assinatura=$cache_assinatura;
           // setup da conexão
           $conn_id = ftp_connect($ftp_server) or die("Não pode conectar em $ftp_server");
           ftp_login($conn_id,$ftp_user,$ftp_senha);
           $cache_ftp_nlist = ftp_nlist($conn_id, $path);
           if ($cache_ftp_nlist===FALSE) die("erro no ftp_nlist");
      }

// verificando se o arquivo existe:
        $check_file_exist = $path.$file;
        if (in_array($check_file_exist, $cache_ftp_nlist)) {
            echo "EXISTE, achei: ".$check_file_exist." na pasta : ".$path;
        } else {
            echo $check_file_exist." não está na pasta : ".$path;   
        };
        // para debug: var_dump($cache_ftp_nlist);
// lembrar de fechar a conexão ftp
        if (!$useCache) ftp_close($conn_id);
        } //func
  // CUIDADO: o cache não pode ser usado se a pasta está sendo alterada!

Functions used:

  1. Login ftp_connect

  2. Suggestion from @Paulorodrigues to get the remote file via ftp_nlist

  3. ... same suggestion of in_array to see if the file is present.

  • Since your suggestion is ftp_size And it also seems like a good idea, if you can put in Portuguese the part that talks about it would be good. As for the second part of your answer, since it is the same as what Paulo Rodrigues had already answered, I think it can be withdrawn.

  • Note: If you like the solution on @mlemos you can vote on it to express your opinion on his reply ;)

  • Good morning! You were very fast, I’m adding cache fix... Ok, now you can comment :-)

0

How about with ftp_nlist?

$contents = ftp_nlist($id_ligacao, "public_html");

if (in_array($ficheiro, $contents)) {
    // existe
} else {
    // não existe
}
  • The solution looks good, but when dealing with a directory where there are for example 1000+ files, there will be no performance problems?

-1

You can use ftp_mlsd which will return the list of files and directories. Then just go through this list and check if the desired directory is contained in it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.