本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。
- <?php
-
- //简单测试
- if(!empty($_FILES))
- {
- move_uploaded_file($_FILES['pic']['tmp_name'],'ces.jpg');
- $ftp = new FTP("222.***.***.15","FTP用户名","密码");
- $ftp->filePut('/D:/ieliwb/ces.jpg','ces.jpg');
- $ftp->closeFtp();
- echo '上传成功';
- }
-
- //FTP操作类 @ www.ieliwb.com
- class FTP {
- public $conn;//连接句柄
- /**
- *构造函数
- *@param $host,$port,$timeout,$username,$password
- */
- function __construct($host,$username,$password,$port = 21,$timeout = 90,$ssl_connect = false,$pasv = 1) {
- if($ssl_connect != false){
- $this->conn = ftp_ssl_connect($host,$port,$timeout) or die("无法连接FTP!");
- }else{
- $this->conn = ftp_connect($host,$port,$timeout) or die("无法连接FTP!");
- }
- if(!@ftp_login($this->conn,$username,$password)) die("用户名或密码错误!");
- $this->setPasv($pasv); //默认打开被动模式
- }
- /**
- *获取ftp文件列表
- *@param $dir
- *@param $all
- *@param $isforeach 是否遍历目录
- */
- function getList($dir = '.' , $all = false , $isforeach = false) {
- $result = ($all == false) ? ftp_nlist($this->conn,$dir) : ftp_rawlist($this->conn,$dir);
- if(!$isforeach) return $result;
- foreach($result as $value){
- if(is_dir("$dir/$value")){
- $this->getList("$dir/$value",$all,$isforeach);
- }else{
- $result[] = $value;
- }
- }
- return $result;
- }
- /**
- *获取操作系统类型
- */
- function getSystype() {
- return ftp_systype($this->conn);
- }
- /**
- *获取文件大小
- *@param $remote_file
- */
- function getFilesize($remote_file) {
- return ftp_size($this->conn,$remote_file);
- }
- /**
- *获取文件最后修改时间
- *@param $remote_file
- */
- function getFilemdtm($remote_file) {
- return ftp_mdtm($this->conn,$remote_file);
- }
- /**
- *改变文件属性
- *@param $filename
- *@param $mode
- */
- function setChmod($filename,$mode) {
- if(function_exists('ftp_chmod')) {ftp_chmod($this->conn,$mode,$filename) or die("更改属性失败!");}
- else{return $this->setSite('CHMOD '.$mode.' '.$filename);}
- }
- /**
- *向服务器发送SITE命令
- *@param $cmd
- */
- function setSite($cmd) {
- ftp_site($this->conn,$cmd) or die("发送命令失败!");
- }
- /**
- *请求运行一条FTP命令
- *@param $cmd
- */
- function setExec($cmd) {
- ftp_exec($this->conn,$cmd) or die("发送失败!");
- }
- /**
- *获取当前目录
- */
- function getPwd() {
- return ftp_pwd($this->conn);
- }
- /**
- *返回上级目录
- */
- function setCdup() {
- ftp_cdup($this->conn);
- }
- /**
- *切换到指定目录
- *@param $dir
- */
- function setChdir($dir) {
- ftp_chdir($this->conn,$dir) or die("不能改变目录!");
- }
- /**
- *创建一个树目录
- *@param $path
- *@return 目录名
- */
- function setMkdir($path) {
- $path_arr = explode('/',$path); // 取目录数组
- $file_name = array_pop($path_arr); // 弹出文件名
- $path_div = count($path_arr); // 取层数
- foreach($path_arr as $val) // 创建目录
- {
- if(@ftp_chdir($this->conn,$val) == FALSE){
- @ftp_mkdir($this->conn,$val) or die("目录创建失败,请检查权限及路径是否正确!");
- @ftp_chdir($this->conn,$val);
- }
- }
- for($i=1;$i<=$path_div;$i++) // 回退到根
- {
- @ftp_cdup($this->conn);
- }
- }
- /**
- *删除一个目录
- *@param $dir
- */
- function setRmdir($dir) {
- ftp_rmdir($this->conn,$dir) or die("删除失败!,请检查权限!");
- }
- /**
- *重命名一个文件或目录|||||||||可以用作移动作用
- *@param $from
- *@param $to
- */
- function setRename($from,$to,$exists = true) {
- if(!$exists) $this->setMkdir($to);
- ftp_rename($this->conn,$from,$to) or die("重命名失败!请检查权限!");
- }
- /**
- *删除一个文件
- *@param $filename
- */
- function setDelete($path) {
- ftp_delete($this->conn,$path) or die("删除文件失败!请检查权限!");
- }
- /**
- *ftp文件上传
- *@param $remote
- *@param $local
- *@param $mode
- *@param $exists
- */
- function filePut($remote,$local,$mode = FTP_BINARY,$exists = true) {
- if(!$exists) $this->setMkdir($remote);//目录不存在则创建
- return ftp_put($this->conn,$remote,$local,$mode);
- }
- /**
- *ftp文件下载
- *@param $remote
- *@param $local
- *@param $mode
- */
- function fileGet($remote,$local,$mode = FTP_BINARY) {
- return ftp_get($this->conn,$local,$remote,$mode);
- }
-
- /**
- *打开被动模式
- *@param $pasv
- */
- function setPasv($pasv) {
- ftp_pasv($this->conn,$pasv) or die("打开被动模式失败!");
- }
- /**
- *关闭连接句柄
- */
- function closeFtp() {
- ftp_close($this->conn) or die("不能关闭!");
- }
-
- }//End Class
- ?>
- <form name="myform" action="" method="POST" enctype="multipart/form-data" >
- <input type="file" name="pic" value="">
- <input type="submit">
- </form>
以上只是说明如何实现图片和WEB分离的原理。在实际开发中,还要进行如:上传检测,水印,缩略图生成,冗余判断,延时间操作,图片路径记录等操作。但只要明白了原理其它的应该不在话下了吧:)
使用socket上传
客户端:
- <?php
- $fp = fsockopen("192.168.0.119", 1337, $errno, $errstr, 30);
- if (!$fp) {
- echo "$errstr ($errno)<br />\n";
- } else {
- $str = "filename:aajsad.php";
- fwrite($fp, $str);
- fwrite($fp, 'data:');
- $out = file_get_contents('jsad.php');
- fwrite($fp, $out);
- fwrite($fp,'dataend');
- }
- fclose($fp);
- ?>
服务端:
- <?php
- set_time_limit(0);
- $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- socket_bind($socket,'192.168.0.119',1337);
- socket_listen($socket,5);
- $path = "e:\\web\\";
- while (true)
- {
- $connection = socket_accept($socket);
- if($connection)
- {
- $BufferPond = array();
- $buffer = '';
- while($flag = socket_recv($connection, $buffer, 1024, 0))
- {
- if($buffer == 'NO DATA')
- {
- break;
- }
- if (false !== strpos($buffer,'filename:'))
- {
- $filename = substr($buffer,9);
- $filename = $path.$filename;
- $fp = fopen($filename,"wb");
- continue;
- }
- if ($buffer == 'data:')
- {
- continue;
- }
- if ($buffer == 'dataend')
- {
- break;
- }
- fwrite($fp,$buffer);
- fclose($fp);
- }
- socket_close($connection);
- }
- }
- socket_close($socket);
- ?>
curl基本基于socket的,原理同上。
AJAX、FLASH跨域上传
这方面不熟,就不说了
评论
发表新评论