前面几则日志中讲述了在 PHP 中上传文件,相信大家对 PHP 中如何进行文件上传已经初步掌握。本文来继续探讨在 PHP 中上传文件的技术,不同的是,本次上传将仅限于图片文件的上传,并且将采用 Ajax 技术。

本例将要实现这样的效果:当用户选择图片,开始上传后,后台上传完成时,随即会显示到当前页面。由于,从开始上传到上传完成,再到图片显示均在一个页面上 完成(从表面上看)。所以使用 Ajax 技术是必须的。但如何使用这些操作在一个页面上来完成呢?考虑到这样的情况,当文件开始上传后,便开始打开 <form> 标签中 action 属性所指向的网页 (PHP 页),这样岂不起离开了原来的页面了么?幸好,有办法解决这个问题,这里我们使用 <iframe> 标签,并将 <form> 标签的 target 设置为该 <iframe>。

来梳理一下思路:在 HTM 页中添加 <form> 和 <iframe>,设置 <form> 的 target 属性为这个 <iframe>;当文件上传开始后,就直接在当前页面的这个 <iframe> 中进行上传。而这个上传操作完成后,PHP 页又后通过 Javascript 来调用 Ajax 中的 XMLHttpRequest 对象,来完成最后的图片显示工作。这样看来,我们的目的就达到了。这里再补充一点,由于并不想让用户看到多余的东西在页面中,所以应该把 <iframe> 隐藏。

本实例一共包括三个文件和一个供上传图片用的文件夹。三个文件分别是:
                uppic.htm 显示上传表单,用户的操作以及图片的显示都在这个页面中;
                uppic.php 处理上传的 PHP 程序;
                showpic.php 负责显示图片的 PHP 程序。

来看 uppic.htm 中的内容:
<html>
<head>
   <script type="text/javascript">
    function uploadimg(theform){ 
     //提交当前表单    
     theform.submit();
    }
   
    function runajax(objId,serverPage){
     //创建 XMLHttpRequest 对象         
     var xmlhttp=false;
     if(window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
     }
     else{
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
     }
    
     xmlhttp.open("GET",serverPage);    
     xmlhttp.onreadystatechange=function(){     
      if(xmlhttp.readyState==4 && xmlhttp.status==200){     
       document.getElementById(objId).innerHTML=xmlhttp.responseText;
      }
     }
     xmlhttp.send(null);
    }
   </script>
</head>
<body>
   <div id="showpic">
   </div>
   <div id="myform">
    <form action="uppic.php" method="post" enctype="multipart/form-data" target="upframe" onsubmit="uploadimg(this); return false;">
     请选择一个图片上传:<input type="file" name="mypic" id="mypic" /><br />
     <br />
     <input type="submit" name="submit" value=" 上传 " />
    </form>
   </div>
   <iframe id="upframe" name="upframe" src="uppic.php" style="display:none;">
   </iframe>
</body>
</html>

其中的 JS 代码很简单,像所有的 Ajax 程序一样,无任何特别之处。在 <body> 中,主要包括三个部分:名为 showpic 的 <div>(图片上传完成后,用来显示图片)、<form> 和隐藏的 <iframe>(其 display 属性为 none)。并且在 <form> 中其 target 属性是 <iframe> 标签的名称。

来看 uppic.php 的代码:
<?php
//允许上传文件的 MIME 类型 
$allow_types=array(
   "image/jpeg",
   "image/pjpeg",
   "image/gif",
   "image/png"
);
$up_folder="ups"; // 图片保存的文件夹

if(isset($_FILES['mypic'])){
   //检测是否是图片文件 
   if(in_array($_FILES['mypic']['type'],$allow_types)){
    if($_FILES['mypic']['error']==0){
     $srcfile=$_FILES['mypic']['tmp_name'];
     $destfile=$up_folder."/".$_FILES['mypic']['name'];
     if(!move_uploaded_file($srcfile,$destfile)){
      echo "上传图片时发生错误";    
     }
     else{
      //没有发生错误 
     ?>
      <body onload="finishupload(parent,'<?php echo $destfile; ?>');">
       <img src="<?php echo $destfile; ?>" />
       <script type="text/javascript">
        function finishupload(theframe,thefile){
         var file="showpic.php?img=" + thefile;        
         if(theframe.runajax){
          theframe.runajax("showpic",file);
         }
         else{
          alert("Error");
         }
        
        }
       </script>
      </body>
     <?php
     }
    }
   }
}
else{
   echo "Error";
}
?>

在没有发生错误的情况下,将来载入 Body,并执行 finishupload 函数。在这个函数中,程序所传的值分别是 parent 和目标文件名(图片上传到服务器上的文件名,包括其相对路径)。需要说明的是,由于这个页面是在 <iframe> 中呈现的,所以这里的 parent 就是指包含这个 <iframe> 的父级容器,也就是 uppic.htm 的窗口。由于在 uppic.htm 页面中定义了名为 runajax 的 Javascript 函数,所以通过调用 parent.runajax 就是调用它。而 runajax 中的一个参数说明了请求的页面:showpic.php。

来看 showpic.php 的代码:
<?php
if(isset($_GET['img'])){
   $file=$_GET['img'];
  
   if(!is_file($file) || !file_exists($file)){   
    echo "Error";
    exit;
   }
   else{
   ?>   
    <img src="<?php echo $file; ?>" />
   <?php
   }
}
?>

由于该页面仅负责显示图片,所以代码不多,要显示的图片是通过传递过来的类型为 GET 的 img 参数(在 Ajax 请求中附在 showpic.php 后面的 URL 参数)。程序道先对这个文件进行检查,如果不出错,就将图片显示出来,当图片显示出来之后,自然就作是 Ajax 的响应结果显示到 uppic.htm 中指定的位置了。

在 PHP 中结合 Ajax 技术进行图片上传的更多相关文章

  1. JSP+Servlet中使用jspsmartupload.jar进行图片上传下载

    JSP+Servlet中使用cos.jar进行图片上传 upload.jsp <form action="FileServlet" method="post&quo ...

  2. JSP+Servlet中使用cos.jar进行图片上传(文件上传亦然)

    链接:JSP+Servlet中使用jspsmartupload.jar进行图片上传下载 关于cos.jar,百度百科只有这么几句话(http://baike.baidu.com/subview/406 ...

  3. 【转载】【JAVA秒会技术之图片上传】基于Nginx及FastDFS,完成图片的上传及展示

    基于Nginx及FastDFS,完成商品图片的上传及展示 一.传统图片存储及展示方式 存在问题: 1)大并发量上传访问图片时,需要对web应用做负载均衡,但是会存在图片共享问题 2)web应用服务器的 ...

  4. Asp.net中FileUpload控件实现图片上传并带预览显示

    单一图片上传——“选择”+“上传”,.NET默认模式: 1.实现原理:     采用FileUpload控件默认的使用方式,先由“选择”按钮选择图片,然后单击“上传”按钮完成上传,并可在“上传”按钮的 ...

  5. django中博客后台将图片上传作为用户头像

    添加上传目录 # 如果不添加上传目录,仍然可以上传成功,默认为project目录,如果models.py定义了upload_to="目录名称",则会上传到"project ...

  6. 【原创】MVC项目中使用JQuery的upladify图片上传插件相关问题的解决方案

    一. 关于Uploadify Uploadify是一个jQuery插件,你可以很容易的为你的网站添加多个文件上传功能.有两个不同的版本(HTML5和Flash)允许你灵活选择为您的网站和回退方法正确实 ...

  7. 在ASP.NET项目中使用CKEditor +CKFinder实现图片上传功能

    前言 之前的项目中一直使用的是FCKeditor,昨天突然有个想法:为什么不试一下新的CKEditor呢?于是花了大半天的时间去学习它的用法,现在把我的学习过程与大家分享一下. 谈起FCKeditor ...

  8. ajax+node实现图片上传

    利用formData实现ajax上传图片后,保存图片到指定收藏夹,然后展示新重命名后的图片 html: <input type="file" id="uploadI ...

  9. Vue.js项目中使用 Ajax 和 FormDate 对象上传文件

    let param = new FormData(); param.append("paths", this.ruleForm.uploadPath); param.append( ...

随机推荐

  1. 立体匹配:关于理解middlebury提供的立体匹配代码后的精减

    Middlebury立体匹配源码总结 优化方法 图像可否预处理 代价计算可否采用BT方式 可选代价计算方法 可否代价聚合 可否MinFilter优化原始代价 WTA-Box 可以 可以 AD/SD 可 ...

  2. nyoj 88 汉诺塔(一)

    点击打开链接 汉诺塔(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝 ...

  3. 导出api文档

    Export,选中项目或者需要导出api的类,右键 java-->javadoc configure,选择C:\Program Files\Java\jdk1.6.0_29\bin\javado ...

  4. Party Games

    Party Games You've been invited to a party. The host wants to divide the guests into 2 teams for par ...

  5. 怎样用CODESOFT打印连续的条码标签?

    在实际工作中,经常会用CODESOFT条 码打印软件来实现打印连续的条码标签,将这些标签按递增或递减等方式连续打印.这样设置可大大提高用户的工作效率.实现在CODESOFT 2015打印连续条码标签, ...

  6. maven的版本管理笔记

    1. 版本管理 (1) 快照版本对应了项目的开发过程,往往对应了很长的时间:发布版本对应了项目的发布,因此仅仅代表某个时刻项目的状态. (2) 理想的发布版本应当对应项目某个时刻比较稳定的状态,包括源 ...

  7. 【caffe-windows】 caffe-master 之 cifar10 超详细

    本教程尽量详细,大多步骤都有图,如果运行出错,请先对照自己的文件是否和图上的一样,包括标点啊,空格啊,斜杠,反斜杠啊之类的小细节. 本例程是在 win10 64位   caffe-master     ...

  8. 使用OpenCV/python进行双目测距

    在做SLAM时,希望用到深度图来辅助生成场景,所以要构建立体视觉,在这里使用OpenCV的Stereo库和python来进行双目立体视觉的图像处理. 立体标定 应用标定数据 转换成深度图 标定 在开始 ...

  9. Sublime Text 2/3中Autoprefixer失效解决方法

    ###Sublime Text 2/3中Autoprefixer失效解决方法: 相信每个前端er都会使用Subl这款工具吧,因为它有上千款开源的插件,而且功能各异,这里给大家带来的是标题中Autopr ...

  10. Android开发-API指南-<intent-filter>

    <intent-filter> 英文原文:http://developer.android.com/guide/topics/manifest/intent-filter-element. ...