Quite sometime ago I ran into problems with some PHP installs, the exact problems escape me but there was various file permission problems and FTP seemed like the best solution.
I wrote a filesystem2FTP type class which solved my problems. Not sure if it's of any use as I did very little testing other than for my specific cases but you are free to use it, bits of it or completely ignore it (I've tacked a couple of usage examples on the end, note they are examples only and in no way constitute working secure scripts)...
Code: Select all
<?php
/******************************************************************************
* filename fs2ftp.cls.php
*
* description performs many common file systems functions via FTP to
* circumvent permissions problems on many PHP installations
*
* project none
*
* author redmonkey
*
* version 0.1
*
* license GPL, the GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html
*
* copyright 2005 redmonkey, all rights reserved
*
* license GPL
*
* notes this is not a FTP class
*
* notes reqiures that PHP's FTP functions are enabled
*
* file history
* ============
* 03/01/2004 v0.1 initial version
*
* notice this program is free software, you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version
*
* notice this program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
******************************************************************************/
/******************************************************************************
* the predefined constant DIRECTORY_SEPARATOR became available from PHP
* version 4.3.x (I think) so make it available for earlier versions
******************************************************************************/
if (!defined('DIRECTORY_SEPARATOR'))
{
/****************************************************************************
* has PHP_OS always been avilable? perhaps php_uname might be a better option
****************************************************************************/
switch(strtolower(substr(PHP_OS, 0, 3)))
{
case 'win':
define('DIRECTORY_SEPARATOR', '\\');
break;
/**************************************************************************
* blatant assumption that everything else uses '/'
**************************************************************************/
default :
define('DIRECTORY_SEPARATOR', '/');
break;
}
}
class fs2ftp
{
var $ftpserver; // your FTP server (usually localhost)
var $ftpuser; // your FTP username
var $ftppass; // your FTP password
var $ftproot; // full path from root of filesystem to root of your FTP server
var $passive; // set passive mode when connecting
var $conn_id; // connection id returned by ftp_connect
/**
* @return
* @param string _user your logon FTP username
* @param string _pass your FTP password
* @param string _root the full path from the root of the filesystem to the
* root of your FTP server (e.g. if your webserver root
* is /home/user/public_html then your FTP server root
* will most likely be /home/user
* @param string _server location of your FTP server (recommend using 'localhost')
* @param bool _pasv set passive mode on (true) or off (false)
* @desc constructor, initialise class variables and set users
* FTP connection details, this does not connect to the
* FTP server
*/
function fs2ftp($_user, $_pass, $_root, $_server = false, $_pasv = false)
{
if (!$this->ftproot = realpath($_root))
{
trigger_error('Failed to resolve FTP root path ' . $this->ftpserver, E_USER_ERROR);
return false;
}
$this->ftpserver = $_server == false ? 'localhost' : $_server; // FTP server address
$this->ftpuser = $_user; // FTP username
$this->ftppass = $_pass; // FTP password
$this->passive = $_pasv; // set passive mode on (true) off (false)
$this->conn_id = false; // connection id resource handle
}
/**
* @return bool true on success false otherwise
* @desc establish a connection and login to the FTP server
*/
function connect()
{
if ($this->conn_id != false)
{
return true;
}
if (!$this->conn_id = @ftp_connect($this->ftpserver))
{
trigger_error('Failed to connect to ' . $this->ftpserver, E_USER_WARNING);
return false;
}
if (!$this->_login())
{
return false;
}
if ($this->passive == true)
{
if (!$this->set_passive(true))
{
trigger_error('Failed to initialize passive mode', E_USER_WARNING);
return false;
}
}
return true;
}
/**
* @return bool true on success false otherwise
* @desc establish a login to the FTP server
*/
function _login()
{
if (@ftp_login($this->conn_id, $this->ftpuser, $this->ftppass));
{
return true;
}
$this->conn_id = false;
trigger_error('Failed to login to ' . $this->ftpserver . ' with username ' . $this->ftpuser, E_USER_WARNING);
return false;
}
/**
* @return bool true on success false otherwise
* @desc closes the connection to the FTP server
*/
function quit()
{
if (!$this->conn_id || !@ftp_quit($this->conn_id))
{
trigger_error('Connection already closed', E_USER_NOTICE);
return false;
}
$this->conn_id = false;
return true;
}
/**
* @return bool true on success false otherwise
* @param string _dir directory to create
* @desc creates a directory and sets permissions
*/
function mk_dir($_dir, $_mode = null)
{
if (!$this->connect())
{
$error_msg = 'Failed to create directory (' . $_dir . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$parent = realpath(dirname($_dir)))
{
trigger_error('Failed to create directory (' . $_dir . ') parent directory does not exist', E_USER_WARNING);
return false;
}
if (file_exists($parent . DIRECTORY_SEPARATOR . basename($_dir)))
{
$error_msg = 'Failed to create directory (' . $_dir . ') a file ';
$error_msg .= 'or directory with that name already exists';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
$dir = str_replace($this->ftproot, '', $parent . DIRECTORY_SEPARATOR . basename($_dir));
if (!@ftp_mkdir($this->conn_id, $dir))
{
trigger_error('Failed to create directory (' . $_dir . ')', E_USER_WARNING);
return false;
}
if (!is_null($_mode))
{
return $this->ch_mod($_dir, $_mode);
}
return true;
}
/**
* @return bool true on success false otherwise
* @param string _file file to set permissions on
* @desc sets permissions on _file
*/
function ch_mod($_file, $_mode)
{
if (!$this->connect())
{
$error_msg = 'Failed to set permissions on (' . $_file . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$file = realpath($_file))
{
trigger_error('Failed to set permissions on (' . $_file . ') no such file or directory', E_USER_WARNING);
return false;
}
$file = str_replace($this->ftproot, '', $file);
if (!@ftp_site($this->conn_id, 'CHMOD ' . decoct($_mode) . ' ' . $file))
{
trigger_error('Failed to set permissions on (' . $_file . ')', E_USER_WARNING);
return false;
}
return true;
}
/**
* @return bool true on success false otherwise
* @param string _file file to remove
* @desc deletes _file
*/
function rm($_file)
{
if (!$this->connect())
{
$error_msg = 'Failed to delete file (' . $_file . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$file = realpath($_file))
{
trigger_error('Failed to delete file (' . $_file . ') no such file exists', E_USER_WARNING);
return false;
}
$file = str_replace($this->ftproot, '', $file);
if (!@ftp_delete($this->conn_id, $file))
{
trigger_error('Failed to delete file (' . $_file . ')', E_USER_WARNING);
return false;
}
return true;
}
/**
* @return bool true on success false otherwise
* @param string _dir directory to remove
* @desc deletes _dir
*/
function rm_dir($_dir)
{
if (!$this->connect())
{
$error_msg = 'Failed to remove directory (' . $_dir . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$dir = realpath($_dir))
{
trigger_error('Failed to delete directory (' . $_dir . ') no such directory exists', E_USER_WARNING);
return false;
}
$dir = str_replace($this->ftproot, '', $dir);
if (!@ftp_rmdir($this->conn_id, $dir))
{
trigger_error('Failed to remove directory (' . $_dir . ')', E_USER_WARNING);
return false;
}
return true;
}
/**
* @return bool true on success false otherwise
* @param string _source file to copy
* @param string _destination destination including filename of the copied file
* @param int _mode transfer mode (either FTP_BINARY or FTP_ASCII)
* @desc copies the file specied by _source to _destination
*/
function cp($_source, $_destination, $_mode = FTP_BINARY)
{
if (!$this->connect())
{
$error_msg = 'Failed to copy file (' . $_source . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$ddir = realpath(dirname($_destination)))
{
trigger_error('Failed to copy file (' . $_source . ') destination directory does not exist', E_USER_WARNING);
return false;
}
$destination = str_replace($this->ftproot, '', $ddir . DIRECTORY_SEPARATOR . basename($_destination));
if (!@ftp_put($this->conn_id, $destination, $_source, $_mode))
{
trigger_error('Failed to copy file (' . $_source . ')', E_USER_WARNING);
return false;
}
return true;
}
/**
* @return bool true on success false otherwise
* @param string _source file to move
* @param string _destination destination including filename of the moved file
* @param int _mode transfer mode (either FTP_BINARY or FTP_ASCII)
* @desc moves a file specied by _source to _destination
*/
function mv($_source, $_destination)
{
if (!$this->connect())
{
$error_msg = 'Failed to copy file (' . $_source . ') FTP server has gone away';
trigger_error($error_msg, E_USER_WARNING);
return false;
}
if (!$source = realpath($_source))
{
trigger_error('Failed to move (' . $_source . ') source file does not exist', E_USER_WARNING);
return false;
}
if (!$ddir = realpath(dirname($_destination)))
{
trigger_error('Failed to move (' . $_source . ') destination directory does not exist', E_USER_WARNING);
return false;
}
$source = str_replace($this->ftproot, '', $source);
$destination = str_replace($this->ftproot, '', $ddir . DIRECTORY_SEPARATOR . basename($_destination));
if (!@ftp_rename($this->conn_id, $source, $destination))
{
trigger_error('Failed to move (' . $_source . ')', E_USER_WARNING);
return false;
}
return true;
}
/**
* @return bool true on success false otherwise
* @param bool _mode true to turn passive mode on, false for off
* @desc turns passive mode connection on or off
*/
function set_passive($_mode = true)
{
if (!$this->connect())
{
return false;
}
return @ftp_pasv($this->conn_id, $_mode);
}
}
?>
Example 1....
Code: Select all
<?php
include('./includes/fs2ftp.cls.php');
$FTP = &new fs2ftp('username', 'password', '/path/to/ftproot');
// making a directory and setting permissions
$FTP->mk_dir('testing', 0777);
// copying a file
$FTP->cp('ftpexample.ex1.php', 'testing/ftpexample.copy.ex1.php');
// create a file in the temp directory then move it
$file = tempnam(null, 'rm_');
$fp = fopen($file, 'wb');
fwrite($fp, 'some text');
fclose($fp);
$FTP->mv($file, 'testfile.txt');
unlink($file);
$FTP->quit();
?>
Example 2....
Code: Select all
<?php
//full path to upload directory (no trailing slashes)
$dir = '/full/path/to/upload/directory'; //Change this to the correct dir
//allowed MIME types
$types = array("image/gif","image/jpeg");
if(isset($_POST['submit']))
{
$uploaded = false;
$tmp_name = $_FILES['upload']['tmp_name'];
$new_name = $_FILES['upload']['name'];
//check MIME
if (in_array($_FILES['upload']['type'], $types))
{
//move file from tmp dir to upload directory
if (is_uploaded_file($tmp_name))
{
//Load up filesystem via FTP class
require('./includes/fs2ftp.cls.php');
$FTP = &new fs2ftp('username', 'password', '/path/to/ftproot');
if ($FTP->cp($tmp_name, $dir . '/' . $new_name))
{
$FTP->quit();
$uploaded = true;
}
}
}
if (!$uploaded)
{
// show error
echo "<small>File <strong><em></em></strong> Was Not Uploaded!</small><br />";
$name = $_FILES['upload']['name'];
$type = $_FILES['upload']['type'];
$size = $_FILES['upload']['size'];
$tmp = $_FILES['upload']['name'];
echo "Name: $name<br/ >Type: $typ<br />Size: $size<br />Tmp: $tmp";
}
else
{
echo " was uploaded sucessfully!";
}
}
?>
<form action="upload.php" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Upload Files</legend>
<input type="file" name="upload" />
</fieldset>
<input type="submit" name="submit" value="Upload Files" />
</form>