• 技术文章 >后端开发 >php教程

    深入PHP FTP类的详解

    2016-06-23 13:05:35原创375
    深入PHP FTP类的详解

    http://www.jb51.net/article/38408.htm

    FTP是一种文件传输协议,它支持两种模式,一种方式叫做Standard (也就是Active,主动方式),一种是 Passive (也就是PASV,被动方式)。 Standard模式 FTP 的客户端发送 PORT 命令到FTP server。Passive模式FTP的客户端发送 PASV命令到 FTP Server。下面介绍一个这两种方式的工作原理:

    Standard模式

    FTP 客户端首先和FTP Server的TCP 21端口建立连接,通过这个通道 发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。 PORT命令包含 了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口发送数据。 FTP server必须和客户端建立一个新的连接用来传送数据。

    Passive模式

    在建立控制通道的时候和Standard模式类似,当客户端通过这个通道发送PASV 命令的时候,FTP server打开一个位于1024和5000之间的随机端口并且通知 客户端在这个端口上传送数据的请求,然后FTP server 将通过这个端口进行数据的传送,这个时候FTP server不再需要建立一个新的和客户端之间的连接。

    使用PHP操作FTP-用法

    复制代码代码如下:

    // 联接FTP服务器

    $conn = ftp_connect(ftp.server.com);

    // 使用username和password登录ftp_login($conn, “john”, “doe”);

    // 获取远端系统类型ftp_systype($conn);

    // 列示文件$filelist = ftp_nlist($conn, “.”);

    // 下载文件ftp_get($conn, “data.zip”, “data.zip”, FTP_BINARY);

    // 关闭联接ftp_quit($conn);

    //初结化一个FTP联接,PHP提供了ftp_connect()这个函数,它使用主机名称和端口作为参数。在上面的例子里,主机名字为 “ftp.server.com”;如果端口没指定,PHP将会使用“21”作为缺省端口来建立联接。

    //联接成功后ftp_connect()传回一个handle句柄;这个handle将被以后使用的FTP函数使用。$conn = ftp_connect(ftp.server.com);

    //一旦建立联接,使用ftp_login()发送一个用户名称和用户密码。你可以看到,这个函数ftp_login()使用了 ftp_connect()函数传来的handle,以确定用户名和密码能被提交到正确的服务器。ftp_login($conn, “john”, “doe”);

    // close connectionftp_quit($conn);

    //登录了FTP服务器,PHP提供了一些函数,它们能获取一些关于系统和文件以及目录的信息。ftp_pwd()

    //获取当前所在的目录$here = ftp_pwd($conn);

    //获取服务器端系统信息ftp_systype()$server_os = ftp_systype($conn);

    //被动模式(PASV)的开关,打开或关闭PASV(1表示开)ftp_pasv($conn, 1);

    //进入目录中用ftp_chdir()函数,它接受一个目录名作为参数。ftp_chdir($conn, “public_html”);

    //回到所在的目录父目录用ftp_cdup()实现ftp_cdup($conn);

    //建立或移动一个目录,这要使用ftp_mkdir()和ftp_rmdir()函数;注意:ftp_mkdir()建立成功的话,就会返回新建立的目录名。ftp_mkdir($conn, “test”);

    ftp_rmdir($conn, “test”);

    //上传文件,ftp_put()函数能很好的胜任,它需要你指定一个本地文件名,上传后的文件名以及传输的类型。比方说:如果你想上传 “abc.txt”这个文件,上传后命名为“xyz.txt”,命令应该是这样:ftp_put($conn, “xyz.txt”, “abc.txt”, FTP_ASCII);

    //下载文件:PHP所提供的函数是ftp_get(),它也需要一个服务器上文件名,下载后的文件名,以及传输类型作为参数,例如:服务器端文件为his.zip,你想下载至本地机,并命名为hers.zip,命令如下:ftp_get($conn, “hers.zip”, “his.zip”, FTP_BINARY);

    //PHP提供两种方法:一种是简单列示文件名和目录,另一种就是详细的列示文件的大小,权限,创立时间等信息。

    //第一种使用ftp_nlist()函数,第二种用ftp_rawlist().两种函数都需要一个目录名做为参数,都返回目录列做为一个数组,数组的每一个元素相当于列表的一行。$filelist = ftp_nlist($conn, “.”);

    //函数ftp_size(),它返回你所指定的文件的大小,使用BITES作为单位。要指出的是,如果它返回的是 “-1”的话,意味着这是一个目录$filelist = ftp_size($conn, “data.zip”);

    ?>

    FTP类

    复制代码代码如下:

    /**

    * 仿写CodeIgniter的FTP类

    * FTP基本操作:

    * 1) 登陆; connect

    * 2) 当前目录文件列表; filelist

    * 3) 目录改变; chgdir

    * 4) 重命名/移动; rename

    * 5) 创建文件夹; mkdir

    * 6) 删除; delete_dir/delete_file

    * 7) 上传; upload

    * 8) 下载 download

    *

    * @author quanshuidingdang

    */

    class Ftp {

    private $hostname = ”;

    private $username = ”;

    private $password = ”;

    private $port = 21;

    private $passive = TRUE;

    private $debug = TRUE;

    private $conn_id = FALSE;

    /**

    * 构造函数

    *

    * @param array 配置数组 : $config = array(‘hostname’=>”,’username’=>”,’password’=>”,’port’=>”…);

    */

    public function __construct($config = array()) {

    if(count($config) > 0) {

    $this->_init($config);

    }

    }

    /**

    * FTP连接

    *

    * @access public

    * @param array 配置数组

    * @return boolean

    */

    public function connect($config = array()) {

    if(count($config) > 0) {

    $this->_init($config);

    }

    if(FALSE === ($this->conn_id = @ftp_connect($this->hostname,$this->port))) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_connect”);

    }

    return FALSE;

    }

    if( ! $this->_login()) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_login”);

    }

    return FALSE;

    }

    if($this->passive === TRUE) {

    ftp_pasv($this->conn_id, TRUE);

    }

    return TRUE;}

    /**

    * 目录改变

    *

    * @access public

    * @param string 目录标识(ftp)

    * @param boolean

    * @return boolean

    */

    public function chgdir($path = ”, $supress_debug = FALSE) {

    if($path == ” OR ! $this->_isconn()) {

    return FALSE;

    }

    $result = @ftp_chdir($this->conn_id, $path);

    if($result === FALSE) {

    if($this->debug === TRUE AND $supress_debug == FALSE) {

    $this->_error(“ftp_unable_to_chgdir:dir[“.$path.”]”);

    }

    return FALSE;

    }

    return TRUE;}

    /**

    * 目录生成

    *

    * @access public

    * @param string 目录标识(ftp)

    * @param int 文件权限列表

    * @return boolean

    */

    public function mkdir($path = ”, $permissions = NULL) {

    if($path == ” OR ! $this->_isconn()) {

    return FALSE;

    }

    $result = @ftp_mkdir($this->conn_id, $path);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_mkdir:dir[“.$path.”]”);

    }

    return FALSE;

    }

    if( ! is_null($permissions)) {

    $this->chmod($path,(int)$permissions);

    }

    return TRUE;}

    /**

    * 上传

    *

    * @access public

    * @param string 本地目录标识

    * @param string 远程目录标识(ftp)

    * @param string 上传模式 auto || ascii

    * @param int 上传后的文件权限列表

    * @return boolean

    */

    public function upload($localpath, $remotepath, $mode = ‘auto’, $permissions = NULL) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    if( ! file_exists($localpath)) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_no_source_file:”.$localpath);

    }

    return FALSE;

    }

    if($mode == ‘auto’) {

    $ext = $this->_getext($localpath);

    $mode = $this->_settype($ext);

    }

    $mode = ($mode == ‘ascii’) ? FTP_ASCII : FTP_BINARY;

    $result = @ftp_put($this->conn_id, $remotepath, $localpath, $mode);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_upload:localpath[“.$localpath.”]/remotepath[“.$remotepath.”]”);

    }

    return FALSE;

    }

    if( ! is_null($permissions)) {

    $this->chmod($remotepath,(int)$permissions);

    }

    return TRUE;}

    /**

    * 下载

    *

    * @access public

    * @param string 远程目录标识(ftp)

    * @param string 本地目录标识

    * @param string 下载模式 auto || ascii

    * @return boolean

    */

    public function download($remotepath, $localpath, $mode = ‘auto’) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    if($mode == ‘auto’) {

    $ext = $this->_getext($remotepath);

    $mode = $this->_settype($ext);

    }

    $mode = ($mode == ‘ascii’) ? FTP_ASCII : FTP_BINARY;

    $result = @ftp_get($this->conn_id, $localpath, $remotepath, $mode);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_download:localpath[“.$localpath.”]-remotepath[“.$remotepath.”]”);

    }

    return FALSE;

    }

    return TRUE;}

    /**

    * 重命名/移动

    *

    * @access public

    * @param string 远程目录标识(ftp)

    * @param string 新目录标识

    * @param boolean 判断是重命名(FALSE)还是移动(TRUE)

    * @return boolean

    */

    public function rename($oldname, $newname, $move = FALSE) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    $result = @ftp_rename($this->conn_id, $oldname, $newname);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $msg = ($move == FALSE) ? “ftp_unable_to_rename” : “ftp_unable_to_move”;

    $this->_error($msg);

    }

    return FALSE;

    }

    return TRUE;}

    /**

    * 删除文件

    *

    * @access public

    * @param string 文件标识(ftp)

    * @return boolean

    */

    public function delete_file($file) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    $result = @ftp_delete($this->conn_id, $file);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_delete_file:file[“.$file.”]”);

    }

    return FALSE;

    }

    return TRUE;}

    /**

    * 删除文件夹

    *

    * @access public

    * @param string 目录标识(ftp)

    * @return boolean

    */

    public function delete_dir($path) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    //对目录宏的’/’字符添加反斜杠’\’$path = preg_replace(“/(.+?)\/*$/”, “\\1/”, $path);

    //获取目录文件列表$filelist = $this->filelist($path);

    if($filelist !== FALSE AND count($filelist) > 0) {

    foreach($filelist as $item) {

    //如果我们无法删除,那么就可能是一个文件夹

    //所以我们递归调用delete_dir()

    if( ! @delete_file($item)) {

    $this->delete_dir($item);

    }

    }

    }

    //删除文件夹(空文件夹)$result = @ftp_rmdir($this->conn_id, $path);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_delete_dir:dir[“.$path.”]”);

    }

    return FALSE;

    }

    return TRUE;}

    /**

    * 修改文件权限

    *

    * @access public

    * @param string 目录标识(ftp)

    * @return boolean

    */

    public function chmod($path, $perm) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    //只有在PHP5中才定义了修改权限的函数(ftp)

    if( ! function_exists(‘ftp_chmod’)) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_chmod(function)”);

    }

    return FALSE;

    }

    $result = @ftp_chmod($this->conn_id, $perm, $path);

    if($result === FALSE) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_unable_to_chmod:path[“.$path.”]-chmod[“.$perm.”]”);

    }

    return FALSE;

    }

    return TRUE;

    }

    /**

    * 获取目录文件列表

    *

    * @access public

    * @param string 目录标识(ftp)

    * @return array

    */

    public function filelist($path = ‘.’) {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    return ftp_nlist($this->conn_id, $path);}

    /**

    * 关闭FTP

    *

    * @access public

    * @return boolean

    */

    public function close() {

    if( ! $this->_isconn()) {

    return FALSE;

    }

    return @ftp_close($this->conn_id);}

    /**

    * FTP成员变量初始化

    *

    * @access private

    * @param array 配置数组

    * @return void

    */

    private function _init($config = array()) {

    foreach($config as $key => $val) {

    if(isset($this->$key)) {

    $this->$key = $val;

    }

    }

    //特殊字符过滤

    $this->hostname = preg_replace(‘|.+?://|’,”,$this->hostname);

    }

    /**

    * FTP登陆

    *

    * @access private

    * @return boolean

    */

    private function _login() {

    return @ftp_login($this->conn_id, $this->username, $this->password);

    }

    /**

    * 判断con_id

    *

    * @access private

    * @return boolean

    */

    private function _isconn() {

    if( ! is_resource($this->conn_id)) {

    if($this->debug === TRUE) {

    $this->_error(“ftp_no_connection”);

    }

    return FALSE;

    }

    return TRUE;

    }

    /**

    * 从文件名中获取后缀扩展

    *

    * @access private

    * @param string 目录标识

    * @return string

    */

    private function _getext($filename) {

    if(FALSE === strpos($filename, ‘.’)) {

    return ‘txt’;

    }

    $extarr = explode(‘.’, $filename);

    return end($extarr);

    }

    /**

    * 从后缀扩展定义FTP传输模式 ascii 或 binary

    *

    * @access private

    * @param string 后缀扩展

    * @return string

    */

    private function _settype($ext) {

    $text_type = array (

    ‘txt’,

    ‘text’,

    ‘php’,

    ‘phps’,

    ‘php4’,

    ‘js’,

    ‘css’,

    ‘htm’,

    ‘html’,

    ‘phtml’,

    ‘shtml’,

    ‘log’,

    ‘xml’

    );

    return (in_array($ext, $text_type)) ? ‘ascii’ : ‘binary’;}

    /**

    * 错误日志记录

    *

    * @access prvate

    * @return boolean

    */

    private function _error($msg) {

    return @file_put_contents(‘ftp_err.log’, “date[“.date(“Y-m-d H:i:s”).”]-hostname[“.$this->hostname.”]-username[“.$this->username.”]-password[“.$this->password.”]-msg[“.$msg.”]\n”, FILE_APPEND);

    }

    }

    /*End of file ftp.php*/

    /*Location /Apache Group/htdocs/ftp.php*/

    DEMO

    复制代码代码如下:

    require_once(‘ftp.php’);

    $config = array(

    ‘hostname’ => ‘localhost’,

    ‘username’ => ‘root’,

    ‘password’ => ‘root’,

    ‘port’ => 21

    );

    $ftp = new Ftp();

    $ftp->connect($config);

    $ftp->upload(‘ftp_err.log’,’ftp_upload.log’);

    $ftp->download(‘ftp_upload.log’,’ftp_download.log’);

    /*End of file ftp_demo.php*/

    /*Location: /htdocs/ftp_demo.php*/

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    上一篇:在Webstorm/Phpstorm中设置连接FTP,上传到服务器 下一篇:一次Debug的遐想
    大前端线上培训班

    相关文章推荐

    • PHP中的命名空间定义与使用(实例详解)• PHP中clone关键字和__clone()方法的使用(实例详解)• 带你分清类中的构造函数与析构函数• 五分钟带你了解PHP中的魔术方法(实例详解)• 怎样去搞定PHP类的继承?(总结分享)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网