关于建立图片服务器的构想

本blog文章如没特殊声明均为原创文章,转载请注明出处,谢谢!

关于图片服务器的优化基本都是采用独立的域名,使用独立的域名,不光是可以并发连接的问题,还有一个重要因素是可以避免 COOKIE 的影响。下面介绍几种方案来实现图片服务器。本人在硬件方面还是个菜鸟,不对之处请谅解!

使用同步软件拷贝数据
使用ftp传递数据,php也可以操作
使用samba来共享文件夹
使用NFS来共享文件夹
使用其他专业数据存储
使用socket来post上传数据
使用curl来上传数据
AJAX、FLASH跨域上传

共享方式
NFS:在图片服务器上使用NFS服务,其他服务器上绑定NFS的共享目录,目录权限是可读可写,这样来实现读写。
其他的共享方式应该都差不多吧,没研究,需要的自己google。

因为php是不能直接在不同服务器之间存取文件的,但是我们还是可以采用FTP方式远程传输,socket方式来POST文件的。

使用FTP远程传输
PHP是支持FTP的,给个FTP类里面,自己看着办吧,上传后调用FTP类,同步到FTP服务器中,好处是现有程序只需要在上传那段加上FTP上传就行了,坏处就是一定要支持FTP。

  1. <?php
  2.  
  3. //简单测试
  4. if(!empty($_FILES))
  5. {
  6.     move_uploaded_file($_FILES['pic']['tmp_name'],'ces.jpg');
  7.     $ftp = new FTP("222.***.***.15","FTP用户名","密码");
  8.     $ftp->filePut('/D:/ieliwb/ces.jpg','ces.jpg');
  9.     $ftp->closeFtp();
  10.     echo '上传成功';
  11. }
  12.  
  13. //FTP操作类 @ www.ieliwb.com
  14. class FTP {
  15.     public $conn;//连接句柄
  16.     /**
  17.     *构造函数
  18.     *@param $host,$port,$timeout,$username,$password
  19.     */
  20.     function __construct($host,$username,$password,$port = 21,$timeout = 90,$ssl_connect = false,$pasv = 1) {
  21.         if($ssl_connect != false){
  22.             $this->conn = ftp_ssl_connect($host,$port,$timeout) or die("无法连接FTP!");
  23.         }else{
  24.             $this->conn = ftp_connect($host,$port,$timeout) or die("无法连接FTP!");
  25.         }
  26.         if(!@ftp_login($this->conn,$username,$password)) die("用户名或密码错误!");
  27.         $this->setPasv($pasv);     //默认打开被动模式
  28.     }
  29.     /**
  30.     *获取ftp文件列表
  31.     *@param $dir
  32.     *@param $all
  33.     *@param $isforeach 是否遍历目录
  34.     */
  35.     function getList($dir = '.' , $all = false , $isforeach = false) {
  36.         $result = ($all == false) ? ftp_nlist($this->conn,$dir) : ftp_rawlist($this->conn,$dir);
  37.         if(!$isforeach) return $result;
  38.         foreach($result as $value){
  39.             if(is_dir("$dir/$value")){
  40.                 $this->getList("$dir/$value",$all,$isforeach);
  41.             }else{
  42.                 $result[] = $value;
  43.             }
  44.         }
  45.         return $result;
  46.     }
  47.     /**
  48.     *获取操作系统类型
  49.     */
  50.     function getSystype() {
  51.         return ftp_systype($this->conn);
  52.     }
  53.     /**
  54.     *获取文件大小
  55.     *@param $remote_file
  56.     */
  57.     function getFilesize($remote_file) {
  58.         return ftp_size($this->conn,$remote_file);
  59.     }
  60.     /**
  61.     *获取文件最后修改时间
  62.     *@param  $remote_file
  63.     */
  64.     function getFilemdtm($remote_file) {
  65.         return ftp_mdtm($this->conn,$remote_file);
  66.     }
  67.     /**
  68.     *改变文件属性
  69.     *@param $filename
  70.     *@param $mode
  71.     */
  72.     function setChmod($filename,$mode) {
  73.         if(function_exists('ftp_chmod')) {ftp_chmod($this->conn,$mode,$filename) or die("更改属性失败!");}
  74.         else{return $this->setSite('CHMOD '.$mode.' '.$filename);}
  75.     }
  76.     /**
  77.     *向服务器发送SITE命令
  78.     *@param $cmd
  79.     */
  80.     function setSite($cmd) {
  81.         ftp_site($this->conn,$cmd) or die("发送命令失败!");
  82.     }
  83.     /**
  84.     *请求运行一条FTP命令
  85.     *@param $cmd
  86.     */
  87.     function setExec($cmd) {
  88.         ftp_exec($this->conn,$cmd) or die("发送失败!");
  89.     }
  90.     /**
  91.     *获取当前目录
  92.     */
  93.     function getPwd() {
  94.         return ftp_pwd($this->conn);
  95.     }
  96.     /**
  97.     *返回上级目录
  98.     */
  99.     function setCdup() {
  100.         ftp_cdup($this->conn);
  101.     }
  102.     /**
  103.     *切换到指定目录
  104.     *@param $dir
  105.     */
  106.     function setChdir($dir) {
  107.         ftp_chdir($this->conn,$dir) or die("不能改变目录!");
  108.     }
  109.     /**
  110.     *创建一个树目录
  111.     *@param $path
  112.     *@return 目录名
  113.     */
  114.     function setMkdir($path) {
  115.         $path_arr  = explode('/',$path);              // 取目录数组
  116.         $file_name = array_pop($path_arr);            // 弹出文件名
  117.         $path_div  = count($path_arr);                // 取层数
  118.          foreach($path_arr as $val)                    // 创建目录
  119.         {
  120.              if(@ftp_chdir($this->conn,$val) == FALSE){
  121.                 @ftp_mkdir($this->conn,$val) or die("目录创建失败,请检查权限及路径是否正确!");
  122.                 @ftp_chdir($this->conn,$val);
  123.                }
  124.          }
  125.         for($i=1;$i<=$path_div;$i++)                  // 回退到根
  126.         {
  127.              @ftp_cdup($this->conn);
  128.          }
  129.     }
  130.     /**
  131.     *删除一个目录
  132.     *@param $dir
  133.     */
  134.     function setRmdir($dir) {
  135.         ftp_rmdir($this->conn,$dir) or die("删除失败!,请检查权限!");
  136.     }
  137.     /**
  138.     *重命名一个文件或目录|||||||||可以用作移动作用
  139.     *@param $from
  140.     *@param $to
  141.     */
  142.     function setRename($from,$to,$exists = true) {
  143.         if(!$exists) $this->setMkdir($to);
  144.         ftp_rename($this->conn,$from,$to) or die("重命名失败!请检查权限!");
  145.     }
  146.     /**
  147.     *删除一个文件
  148.     *@param $filename
  149.     */
  150.     function setDelete($path) {
  151.         ftp_delete($this->conn,$path) or die("删除文件失败!请检查权限!");
  152.     }
  153.     /**
  154.     *ftp文件上传
  155.     *@param $remote
  156.     *@param $local
  157.     *@param $mode
  158.     *@param $exists
  159.     */
  160.     function filePut($remote,$local,$mode = FTP_BINARY,$exists = true) {
  161.         if(!$exists) $this->setMkdir($remote);//目录不存在则创建
  162.         return ftp_put($this->conn,$remote,$local,$mode);
  163.     }
  164.     /**
  165.     *ftp文件下载
  166.     *@param $remote
  167.     *@param $local
  168.     *@param $mode
  169.     */
  170.     function fileGet($remote,$local,$mode = FTP_BINARY) {
  171.         return ftp_get($this->conn,$local,$remote,$mode);
  172.     }
  173.  
  174.     /**
  175.     *打开被动模式
  176.     *@param $pasv
  177.     */
  178.     function setPasv($pasv) {
  179.         ftp_pasv($this->conn,$pasv) or die("打开被动模式失败!");
  180.     }
  181.     /**
  182.     *关闭连接句柄
  183.     */
  184.     function closeFtp() {
  185.         ftp_close($this->conn) or die("不能关闭!");
  186.     }
  187.  
  188. }//End Class
  189. ?>
  190. <form name="myform" action="" method="POST" enctype="multipart/form-data" >
  191. <input type="file" name="pic" value="">
  192. <input type="submit">
  193. </form>

以上只是说明如何实现图片和WEB分离的原理。在实际开发中,还要进行如:上传检测,水印,缩略图生成,冗余判断,延时间操作,图片路径记录等操作。但只要明白了原理其它的应该不在话下了吧:)

使用socket上传
客户端:

  1. <?php   
  2. $fp = fsockopen("192.168.0.119", 1337, $errno, $errstr, 30);   
  3. if (!$fp) {   
  4.     echo "$errstr ($errno)<br />\n";   
  5. } else {   
  6.     $str = "filename:aajsad.php";   
  7.     fwrite($fp, $str);   
  8.     fwrite($fp, 'data:');   
  9.     $out = file_get_contents('jsad.php');   
  10.     fwrite($fp, $out);   
  11.     fwrite($fp,'dataend');   
  12. }   
  13. fclose($fp);  
  14. ?>

服务端:

  1. <?php   
  2. set_time_limit(0);   
  3. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);   
  4. socket_bind($socket,'192.168.0.119',1337);   
  5. socket_listen($socket,5);   
  6. $path = "e:\\web\\";  
  7. while (true)  
  8. {  
  9. $connection = socket_accept($socket);  
  10. if($connection)  
  11. {  
  12.     $BufferPond = array();  
  13.     $buffer = '';  
  14.     while($flag = socket_recv($connection, $buffer, 1024, 0))  
  15.     {   
  16.          if($buffer == 'NO DATA')   
  17.          {   
  18.              break;  
  19.          }  
  20.          if (false !== strpos($buffer,'filename:'))  
  21.          {  
  22.             $filename = substr($buffer,9);  
  23.             $filename = $path.$filename;  
  24.             $fp = fopen($filename,"wb");   
  25.             continue;   
  26.          }   
  27.          if ($buffer == 'data:')   
  28.          {   
  29.             continue;   
  30.          }   
  31.          if ($buffer == 'dataend')   
  32.          {   
  33.             break;   
  34.          }   
  35.          fwrite($fp,$buffer);   
  36.          fclose($fp);   
  37.     }   
  38.     socket_close($connection);   
  39. }   
  40. }   
  41. socket_close($socket)
  42. ?>

curl基本基于socket的,原理同上。

AJAX、FLASH跨域上传
这方面不熟,就不说了

评论

发表新评论