• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 222
  • Last Modified:

Server connections and file lookup using PHP form!!!

Hi experts!  Alright, this may be a little wordy, so bear with me here ;)

I am looking to create a download.php page that contains a form.  In this form, there is a drop down menu (containing four values).  I want each of these values to label a different server to connect to.

Underneath the drop down menu is a textfield that asks the user to input the filename (with extension) of the file they tend to look up within the selected server (the server they selected in the drop down menu).

My intention is after the server and filename are submitted, a connection is made to the server that was selected in the drop down menu.  I want the script to scan the server for that filename (plus extension).  If there is a match, it pulls that file and places in within a certain directory on my webserver.  If not, it disconnects and tells the user there was no file on that server with the specified filename.

So, I'll start with that, and if I can get that working, I'll move on to more complex things afterwords...Any help is highly appreciated!!!  Can anyone help me with a jump start?  Will I need to create a database for the different servers, since the form uses values to differentiate between the fou?  It sounds pretty confusing, and I'm new to PHP.

Here is the form I am using in case you need to see how I set it up.

FORM
=================
<form name="form1" method="post" action="">
                     
              <p align="left"></p>
                      <table width="100%">
                        <tr>
                          <td width="30%">&nbsp;</td>
                          <td width="40%" rowspan="6">&nbsp;</td>
                          <td width="30%" rowspan="6">&nbsp;</td>
                        </tr>
                        <tr>
                          <td><font color="#FF0000" size="-2" face="Arial, Helvetica, sans-serif">Select
                            Dialer:</font></td>
                        </tr>
                        <tr>
                          <td><select name="select" id="select">
                              <option value="dialer_1">Dialer 1</option>
                              <option value="dialer_2">Dialer 2</option>
                              <option value="dialer_3">Dialer 3</option>
                              <option value="dialer_4">Dialer 4</option>
                            </select></td>
                        </tr>
                        <tr>
                         
                  <td><font color="#FF0000" size="-2" face="Arial, Helvetica, sans-serif">Filename
                    (<font color="#000000">with</font> <font color="#000000">extension</font>):</font></td>
                        </tr>
                        <tr>
                          <td><input name="filename" type="text" id="filename"></td>
                        </tr>
                        <tr>
                          <td><input type="submit" name="Submit" value="Retrieve file"></td>
                        </tr>
                      </table>
                   </p>
                    </form>
0
dialeradmin
Asked:
dialeradmin
  • 6
  • 4
1 Solution
 
MasonWolfCommented:
Ok, you're asking 3 separate questions.

First, how to connect to a server:
<?php
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
?>

Whether you want to save these variables to a simple configuration file (better for a small number of connections like you have) or a database (better for the case where you might increase the number of servers offered) is entirely in your hands.

Now, once you've connected to the server, you need the ability to search it to find a particular file.

Here's a function that SHOULD do that, but to be fair I don't have a handy way of testing it myself, so there may very well be bugs:


function findFile($conn_id, $folder,$filename)
{
      $results = array();
      $contents = ftp_nlist($conn_id, $folder);
      foreach($contents AS $file)
      {
            if(ftp_chdir($conn_id,$file))
            {
                  $result = findFile($conn_id,$folder.'/'.$file,$filename);
                  if(is_array($result))
                  {
                        foreach($result AS $retval)
                        {
                              $results[] = $retval;
                        }
                  }
                  else if($result !== false)
                  {
                        $results[] = $result;
                  }
                  ftp_cdup($conn_id);
            }
            else
            {
                  if(strcmp($file,$filename)==0)
                  {
                        $results[] = $folder.'/'.$file;
                  }
            }
      }
      if(count($results)>0)
      {
            if(count($results)==1)
                  return $results[0];
            else
                  return $results;
      }
      else
            return false;
}

To find every instance of a file name "example.txt" on a given server, first connect to it, and then call the function as:
$filelocations = findFile($conn_id, '.', 'example.txt');

If $filelocations is a string, there was only 1 place where that file was found. If it's an array, then the file was found in multiple locations (you'll probably want to provide a list of locations containing the match). If it is 'false', then the file just was not found.

Now the last thing you want is to be able to let the user download the file.

Again, here is a function that SHOULD work.

function download($conn_id, $filelocation)
{
      $tmp_file = substr(md5(time()),0,8);
      $handle = fopen($tmp_file, 'w');
      $filename = array_pop(split('/',$filelocation));
      $ext = array_pop(split('.',$filename));
      if(ftp_fget($conn_id, $handle, $filelocation, FTP_BINARY, 0))
      {
           header('content-disposition: attachment; filename='.$filename);
         header('Content-Type: content='.$ext);
           header('Content-Length: '.filesize($tmp_file));
           readfile($tmp_file);
           return true;
      }
      else
           return false;
}

I hope that suits you. Let me know if it works. If only 1 or 2 of those functions does what you need, hopefully you'll still credit me with an assist once you get an answer that works completely.
0
 
dialeradminAuthor Commented:
Ok.  I'll try these methods out here in a little, but before I do that...couple questions.

Regarding what you said about connecting to the databases.  
   - I take it that using a drop down menu to select which server you would want to connect to would require creating a SQL database, right?
   - I'm confused as to when you say creating a configuration file for four different servers?
0
 
MasonWolfCommented:
Ok, basically, a database is just really cool filesystem with easy methods to access the data, modify it, delete it, and keep it secure. For any large project where lots of information needs to be stored and accessed constantly, a database is almost always the best way to go.

But in your case, you could very easily create a single file that defines a php array, and just include it at the start of your script, like so:

<?php
require_once('server_logins.php');
?>

Then, in that file, you could have something like:

<?php
$server_logins = array();
$server_logins['Dialer 1'] = array("Server"=>"67.18.42.199", "User"=>"Tom", "Pass"=>"5js%tys");
//more logins as needed
?>

To connect to a server, just have your user pick which server to connect to, and then:

<?
$server = $server_logins[$_POST['server']];
$conn_id = ftp_connect($server['Server']);
$login_result = ftp_login($conn_id, $server['User'], $server['Pass']);
?>

As far as the dropdown menu, just use the same thing you already have. It's fine.

If you still really want to do a database, you can, it just seems like a bit of a waste to me.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
dialeradminAuthor Commented:
Ok.  Your making sense.  Great instructions so far!!!
So, here is what I tried.  As for now, I'm just going to try to connect to Dialer 2 because that is the only one I have login information for so far.

Anyways, here is the steps I have taken so far.  Let me know if this looks right:

I created a file called: server_logins.php...It contains this code: (* represents my info)
================
<?php
$server_logins = array();
$server_logins['Dialer 2'] = array("Server"=>"********", "User"=>"********", "Pass"=>"*******");
//more logins as needed
?>

Next, I added this to the top of the page I currently have my form located on.  Disregard all php until you see:  required_once('server_logins.php');

download.php
====================
<?php
session_start();
include_once('log.php');

if (!isset($_SESSION['logged_in'] ))
{
    header("Location:access_denied.php");
}
require_once('server_logins.php');

$server = $server_logins[$_POST['select']];
$conn_id = ftp_connect($server['Server']);
$login_result = ftp_login($conn_id, $server['User'], $server['Pass']);
?>

And finally, here is the error it is giving me...any ideas?
==========
Warning: ftp_connect() [function.ftp-connect]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /opt/lampp/htdocs/dialer/download2.php on line 12

Warning: ftp_login() expects parameter 1 to be resource, boolean given in /opt/lampp/htdocs/dialer/download2.php on line 13
0
 
MasonWolfCommented:
Well, the error looks like what you would see if it can't find the ftp server. Check your spelling?

You should either use the numeric ip address or the domain name without any subdomain in front of it (i.e. "domain.com" not "www.domain.com")
0
 
dialeradminAuthor Commented:
Hmm, it seems like the server information is written correctly in server_logins.php...

Maybe it is giving me an error because I haven't included any of the functions yet in my PHP code that looks for a match of the input filename?  

But...I'll keep playing around with it.
0
 
MasonWolfCommented:
The error is definitely the result of not being able to find the server, though for what reason, I couldn't guess. I really hope you can troubleshoot this, sorry I don't know what else to say.
0
 
MasonWolfCommented:
I decided to set up my own server to test this on, and it's a good thing I did! There was a bug in the findFile function that was going to waste a whole lot of server time on what would generally be an infinite loop (though php is smart enough to have a cut-off to that sort of tomfoolery - it's still a pretty dang long time to finish).

Here is the complete, and working, set of functions.

function findFile($conn_id, $folder, $filename)
{
        error_reporting(1);
      $results = array();
      $contents = ftp_nlist($conn_id, '.');
      foreach($contents AS $file)
      {
              if($file == '.' || $file == '..')
                  continue;
           if(ftp_chdir($conn_id,$file))
           {
                  $result = findFile($conn_id,$folder.'/'.$file,$filename);
                  if(is_array($result))
                  {
                        foreach($result AS $retval)
                        {
                              $results[] = $retval;
                        }
                  }
                  else if($result !== false)
                  {
                        $results[] = $result;
                  }
                  ftp_cdup($conn_id);
            }
            else
            {
                  if(strcmp($file,$filename)==0)
                  {
                        $results[] = $folder.'/'.$file;
                  }
            }
      }
      if(count($results)>0)
      {
            if(count($results)==1)
                  return $results[0];
            else
                  return $results;
      }
      else
            return false;
}

function download($conn_id, $filelocation)
{
      $tmp_file = substr(md5(time()),0,8);
      $handle = fopen($tmp_file, 'w');
      $filename = array_pop(split('/',$filelocation));
      $ext = array_pop(split('.',$filename));
      if(ftp_fget($conn_id, $handle, $filelocation, FTP_BINARY, 0))
      {
                 $filesize = filesize($tmp_file);
           header('content-disposition: attachment; filename='.$filename);
           header('Content-Type: content='.$ext);
           header('Content-Length: '.$filesize);
           readfile($tmp_file);
               unlink($tmp_file);
           return $filesize;
      }
      else
        {
                 unlink($tmp_file);
           return "Download failed";
        }
}
function connectFindDownload($ftp_server, $ftp_user, $ftp_pass, $filename, $folder = '.')
{
      $conn_id = ftp_connect($ftp_server);
      $login_result = ftp_login($conn_id, $ftp_user, $ftp_pass);
      if(!$login_result)
      {
            return "connection failed";
      }
      else
      {
            ftp_chdir($conn_id,$folder);
            $filelocations = findFile($conn_id, $folder, $filename);
            if($filelocations != false)
            {
                  if(is_array($filelocations))
                  {
                        $filelocations = $filelocations[0];
                  }
                  if($folder != '.')
                        $filelocations = str_replace($folder.'/','',$filelocations);
                  return download($conn_id, $filelocations);
            }
            else
                  return "File not found";
      }
      ftp_close($conn_id);
}

Notice that in the case that more than one match is found for a particular filename, the "connectFindDownload" function simply defaults to the first response and triggers the download. You might want to change that.

Good luck to you!
0
 
MasonWolfCommented:
By the way, this is hands-down my favorite of any question I've answered so far. No doubt if I took more time with it, I could've done something a little more elegant, but this puppy is just brilliant for its utility. If you can, I recommend using the optional "$folder" parameter to speed up searching for a file on your server, if ever you happen to know where a particular folder might be found. With a large amount of content to search through on a given server, the findFile function can take a very long time to finish. (Imagine a slower version of the old Windows Search, all done through remote ftp transactions)

Also, you might want to modify the findFile function by having it 'break' as soon as it hits its first match (unless you plan on giving users the option of which matching file they want to download). Alternately, you might consider changing the findFile function so that instead of requiring an exact match, it can use a regular expression instead.

Whatever your eventual plans, I really appreciate such a fun challenge.
0
 
dialeradminAuthor Commented:
Thanks a lot...Sorry it took me a day or two to get back to you, I was gone over the weekend!  But I really do appreciate your help!  I'll definately work with everything you suggested!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now