用户
 找回密码
 入住 CI 中国社区
搜索
查看: 8458|回复: 12
收起左侧

[其它 Other] FTP类的疑问及替代办法

[复制链接]
发表于 2009-6-23 12:00:10 | 显示全部楼层 |阅读模式
CI的FTP类定义是:CodeIgniter's FTP Class permits files to be transfered to a remote server. Remote files can also be moved, renamed, and deleted. The FTP class also includes a "mirroring" function that permits an entire local directory to be recreated remotely via FTP.
如果按这个定义,那么“permits files to be transfered to a remote server”应该可以理解成在任一计算机上上传任意本地文件到FTP服务器的指定目录下。但经过实际动手,却发现CI的FTP类根本不是这么个意思。这个类只能使用于服务器,既CI的APP运行的机器上。这与通常意义上的设计需求有着本质的区别。因为,执行FTP操作的目的是在任一客户端将文件上传服务器指定目录下,而绝非在服务器上操作。换句话说,如果都能操作服务器了,还用FTP干么呢?直接拷贝一下就欧克了。因此,建议CI的这个FTP类,应该进行整改。
由于PHP本身最大执行30秒的限制,通过表单上传大文件是个比较可怕的噩梦,而且各服务器提供商对最大上传限制和最大表单数据肯定有限制。因此,使用FTP上传体格比较大的文件是不二的选择。
因为CI的FTP类不好用,自己重新写了一个FTP操作应用,很简单,现在贴出来,希望能对大家有帮助。
PHP复制代码
  function ftp()
  {
      if(empty($this->webinfo->ftpserver) || empty($this->webinfo->ftpuser) || empty($this->webinfo->ftppwd))
      {
        show_error('您并未设定FTP服务器域名、IP地址、用户名及密码等信息');
      }
      $ftpid = $this->uri->segment(4,0);
      $updateid = $this->input->post('updateid');
     
      $workDir = "C:\\temp_upload\\";
      $tmpName = basename($_FILES['file']['tmp_name']);
 
      move_uploaded_file($_FILES['file']['tmp_name'], $workDir.$tmpName) or die("移动上传文件到临时目录失败,请检查临时目录是否存在,是否有写权限!");
      $conn = ftp_connect($this->webinfo->ftpserver) or die ("连接FTP服务器失败,请检查设定的FTP服务器域名或IP地址");
      ftp_login($conn, $this->webinfo->ftpuser, $this->webinfo->ftppwd) or die("登录FTP服务器失败,请检查设定的用户名及密码");
     
      $destDir = '/uploads/media/';
     
      $upload = ftp_put($conn, $destDir.$_FILES['file']['name'], $workDir.$tmpName, FTP_BINARY);
      if($upload)
      {
        header ( 'Content-Type: text/html; charset=utf-8' );
          print "<script>window.alert('上传成功,请录入该相册的其他属性!');</script>";
      }
      else
      {
        show_error('FTP上传相册出现异常,请返回重新操作,或向开发者报告bug。spt119@163.com');
      }
        ftp_close($conn);
        unlink($workDir."/".$tmpName) or die("删除 temp_upload 目录下临时文件失败,请管理员手动删除该文件");
   
    $this->load->view('admin/admingallaryadd');
    $this->load->view('admin/admin_foot');
  }
复制代码

评分

参与人数 1威望 +5 收起 理由
Hex + 5 原创内容

查看全部评分

发表于 2009-6-23 12:17:05 | 显示全部楼层
感谢楼主提供的代码!

不过,我查看了一下 FTP 类库的代码,确实是有连接远程服务器的代码,为什么不能连接到远程 FTP 服务器呢?
 楼主| 发表于 2009-6-23 14:25:20 | 显示全部楼层
我也是感觉非常奇怪,开始还以为是自己的代码和FTP服务器配置有问题。因总返回“unable to locate the source file”错误,在CI的google里一查,http://codeigniter.com/forums/viewthread/46711/#223673。才明白CI的FTP与我们理解的FTP是两回事。
其中有个回帖的内容如下:
be careful, you misunderstood the capabilities of the ftp-library (i must admit that naming of the variables and the documentation are not that good in this case)

Code Igniter’s FTP Class permits files to be uploaded, moved, renamed, and deleted on your server.

PHP can never directly access a user’s computer so CI can’t either ... the source-file must be located on the SAME server as your CI-app! it is only possible to use CI’s ftp library to upload files from the CI-app-server to ANOTHER ftp-server, not from a user’s computer to the CI-app-server

if you want to upload fotos, you have to use forms as usual ... i recommend using the file uploading class

大概意思是:
......(应该说,变量的定义和文档,在有关FTP类的说明方面是不太准确或贴切的。----这是官方自己总结的,因为这个发帖者的身份是 lab assistant)
接下来他有说到:PHP不能直接访问用户的计算机,对于基于PHP的框架技术CI来说,也同样不能。源文件(待传的FTP文件)必须与CI-APP程序均在同一台计算机上,FTP类才能正确工作。将与CI-APP程序同在一台服务器中的文件上传到另外一台FTP服务器中,FTP类上传功能才能正确执行,而从任一一台用户的计算机通过FTP类上传到CI-APP服务器,将会返回错误。
如果想上传照片等媒体文件(photos->被简化成fotos),必须使用表单以及文件上传类。

所以,貌似CI有远远程连接FTP的设置,与本文的设计要求,根本就是两回事。
发表于 2009-6-23 14:36:44 | 显示全部楼层
呵呵,原来你的理解是要在客户端通过 FTP 传递到服务器端?这肯定是不可能的,PHP 的 FTP 函数就是一个 FTP 客户端,他不可能接受别人的连接,他只能连接别的服务器,也就是服务器连接另外的服务器了。
还有,服务器是无法直接访问客户端的,必须通过上传这种途径。因为 PHP 的代码也是在服务器上执行的。
 楼主| 发表于 2009-6-23 14:51:23 | 显示全部楼层
恩。因为相册文件动辄3-5MB,或者更大,用表单传,实话说心里没有底气。因为PHP脚本有执行时间限制,大文件上传可以肯定会返回错误,上传不了。这才动心想集成FTP上传,主要的理解就是一些FTP上传程序,如FLASHXP,CUTEFTP等软件的模式,从本机上传任一文件到服务器中的指定目录。
但实际结果,是执行不了,所以又根据PHP手册手写了FTP功能。不过,折腾一圈,总算明白了CI的FTP类是怎么回事。
感谢HEX的提示与回复。希望这个文章能对有类似需求的朋友有些帮助。
发表于 2009-6-23 14:53:52 | 显示全部楼层
呵呵,一般浏览器上传大文件,不是用浏览器插件,就是用 Flash,总之都需要一些第三方的东西来支持。
很多网盘都是这么做的。很少有直接提供 FTP 功能的网盘,至少我没见过,呵呵
 楼主| 发表于 2009-6-23 18:36:10 | 显示全部楼层
这是客户要求的一个小程序,相册体积不会太大(但显然对于表单来说,有点大)。关于上传的插件,基本都是JAVA-APPLET小程序,但具体到怎么整合到CI里,还需要不少的功夫。FTP是个替代的简单的办法,对于眼下的应用是应该没有太大问题的,等忙活完这阵子,再琢磨琢磨插件,到时候有结果,发上来大家一起用。
感谢hex提醒。
发表于 2009-6-23 22:54:14 | 显示全部楼层
呵呵,浏览器端用 FTP,貌似不可行吧,至少 JS 没这个功能。。。。
 楼主| 发表于 2009-6-24 10:43:13 | 显示全部楼层
目前,已基本实现了这个功能。顶贴复制到代码,只包括FTP部分,还有很多逻辑判断及具体操作,我都省去了,免得大家看着迷糊。
设计要求,就是通过FTP上传任一本地文件到服务器的指定目录里,上传文件的大小以服务器提供商在php.ini里设置的“post_max_size”及“upload_max_filesize”参数为上限。
 楼主| 发表于 2009-6-24 10:44:38 | 显示全部楼层
这个ftp,与大家把代码ftp到服务器空间的原理一样。我们在自己的计算机上传代码程序到空间,不也是通过ftp么。这里我设计的,就是这个模式。

本版积分规则