码迷,mamicode.com
首页 > Web开发 > 详细

前端PHP入门-031-文件上传-六脉神剑

时间:2016-08-09 08:13:43      阅读:402      评论:0      收藏:0      [点我收藏+]

标签:

php.ini的设置

技术分享

php.ini的文件太多,找不到的时候你可以使用 Ctrl+F 搜索相关配置项。

配置项 功能说明
file_uploads on 为开启文件上传功能,off 为关闭
post_max_size 系统允许的POST传参的最大值
upload_max_filesize 系统允许的上传文件的最大值
memory_limit 内存使用限制

建议设置:

file_size(文件大小) < upload_max_filesize < post_max_size < memory_limit

另外,需要注意的是脚本执行时间。

max_execution_time: 单位为

这个参数是设定脚本的最大执行时间。
也可以根据需求做适当的改变。
通常不需要来修改,系统默认值即可。
超大文件上传的时候,可能会涉及到这一项参数的修改。

  • 上传时间太长了,会超时。
  • 如果你将此项参数设为0,则是不限制超时时间,不建议使。

完成了php.ini的相关配置,我们就可以开始试着完成第一次文件上传了。

上传步骤

一 判断是否有错误码

系统返回的错误码详解:

错误码 说明
0 无误,可以继续进行文件上传的后续操作。
1 超出上传文件的最大限制,upload_max_filesize = 2M php.ini中设置,一般默认为2M。可根据项目中的实际需要来修改
2 超出了指定的文件大小,根据项目的业务需求指定上传文件的大小限制
3 只有部分文件被上传
4 文件没有被上传
6 找不到临时文件夹,可能目录不存在或没权限
7 文件写入失败,可能磁盘满了或没有权限

注:错误码中没有5。

二 自定义判断是否超出文件大小范围

在开发上传功能时。我们作为开发人员,除了php.ini中规定的上传的最大值外。

我们通常还会设定一个值,是业务规定的上传大小限制。

例如:

新浪微博或者QQ空间只准单张头像图片2M。而在上传图册的时候又可以超过2M来上传。
所以说,它的系统是支持更大文件上传的。
此处的判断文件大小,我们用于限制实际业务中我们想要规定的上传的文件大小。

三 判断后缀名和mime类型是否符合

在网络世界里面也有坏人。他们会把图片插入病毒,在附件中上传病毒,他们会在网页中插入病毒或者黄色图片。
我们需要对于上传的文件后缀和mime类型都要进行判断才可以。

  1. MIME(Multipurpose Internet Mail Extensions)是多用途互联网邮件扩展类型。
  2. 它是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会`自动使用指定应用程序`来打开。
  3. 多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

在判断后缀和MIME类型的时候,我们会用到PHP的一个 函数in_array() ,该函数传入两个参数。
第一个参数是要判断的值;
第二个参数是范围数组。

我们用这个函数来判断文件的后缀名和mime类型是否在允许的范围内。

四 生成文件名

我们的文件上传成功了,不会让它保存原名。

因为,有些人在原名中有敏感关键词会违反我国的相关法律和法规。

解决方案: 我们可以采用date()mt_rand()或者unique()生成随机的文件名。

五 判断是否是上传文件

文件上传成功时,系统会将上传的临时文件上传到系统的临时目录中。产生一个临时文件。

同时会产生临时文件名。我们需要做的事情是将临时文件移动到系统的指定目录中。

而移动前不能瞎移动,或者移动错了都是不科学的。移动前我们需要使用相关函数判断上传的文件是不是临时文件。

is_uploaded_file()传入一个参数($_FILES中的缓存文件名),判断传入的名称是不是上传文件。

六 移动临时文件到指定位置

临时文件是真实的临时文件,我们需要将其移动到我们的网站目录下面了。

让我们网站目录的数据,其他人可以访问到。

我们使用:move_uploaded_file()

这个函数是将上传文件移动到指定位置,并命名。
传入两个参数:

  • 第一个参数是指定移动的上传文件;
  • 第二个参数是指定的文件夹和名称拼接的字符串。

文上传表单

上传文件必须在网页中准备好一个form表单。[Ajax上传其实也是通过表单]
这是一个简单的HTML页面表单,form表单为文件内容准备了一个专用的类,当选择 的 type=file 时,默认为上传文件内容。

form.html代码

  1. <html>
  2. <head>
  3. <meta charset="utf-8" />
  4. <title>单文件上传</title>
  5. </head>
  6. <body>
  7. <form action="file.php" method="post" enctype="multipart/form-data">
  8. <input type="file" name="file">
  9. <input type="submit" value="上传">
  10. </form>
  11. </body>
  12. </html>

注意事项:

  1. form 表单中的参数 method 必须为post。若为get是无法进行文件上传的
  2. enctype须为multipart/form-data

上传数据处理

form表单提交的文件内容指向了 action="file.php",在file.php中通过PHP代码,来处理上传文件。
我们选择一个名为图片进行上传。假设图片的名字为:pangsir.jpg,点击上传。
PHP为文件类数据准备了一个专用的系统函数$_FILES,上传文件的所有相关数据,都保存在这个系统函数中。

在PHP文件中,我们打印 $_FILES ,来观察这个数组的结构:

```php
<?php
//var_dump()或print_r()
//打印变量的相关信息,将变量的信息详细的展示出来
var_dump($_FILES);
?>

  1. 打印出来的结果的数组结构如下:
  2. ```php
  3. array (size=1)
  4. ‘file‘ =>
  5. array (size=5)
  6. //文件名
  7. ‘name‘ => string ‘pangsir.jpg‘ (length=7)
  8. //文件的mime类型
  9. ‘type‘ => string ‘image/jpeg‘ (length=10)
  10. //缓存文件,上传的图片即保存在这里
  11. ‘tmp_name‘ => string ‘E:\wamp\tmp\phpC32A.tmp‘ (length=23)
  12. //错误码,详见上面错误码介绍
  13. ‘error‘ => int 0
  14. //上传的文件大小
  15. ‘size‘ => int 225824

得到了上面的数组结构。

我们就可以开始文件的处理过程了。

第一步 : 判断错误码

  1. <?php
  2. if($_FILES[‘file‘][‘error‘] > 0){
  3. switch ($_FILES[‘file‘][‘error‘]) { //错误码不为0,即文件上传过程中出现了错误
  4. case ‘1‘:
  5. echo ‘文件过大‘;
  6. break;
  7. case ‘2‘:
  8. echo ‘文件超出指定大小‘;
  9. break;
  10. case ‘3‘:
  11. echo ‘只有部分文件被上传‘;
  12. break;
  13. case ‘4‘:
  14. echo ‘文件没有被上传‘;
  15. break;
  16. case ‘6‘:
  17. echo ‘找不到指定文件夹‘;
  18. break;
  19. case ‘7‘:
  20. echo ‘文件写入失败‘;
  21. break;
  22. default:
  23. echo "上传出错<br/>";
  24. }
  25. }else{
  26. //错误码为0,即上传成功,可以进行后续处理,处理流程见下文
  27. }
  28. ?>

我们可以根据错误码,来生成准确的错误提示。

第二步 : 判断文件是否超出大小

在实际项目中,由于系统硬件的限制,以及存储设备的限制,不可能让用户无限制的上传文件,所以我们要对用户上传的文件大小进行限制。定义一个合适的限制大小,能让我们的应用更稳定的运行。

  1. //判断错误
  2. if($_FILES[‘file‘][‘error‘] > 0){
  3. //有错误可停止执行
  4. }else{
  5. //当前上传文件无误,运行本段代码
  6. //判断文件是否超出了指定的大小
  7. //单位为`byte`
  8. $MAX_FILE_SIZE = 100000;
  9. if($_FILES[‘file‘][‘size‘] > $MAX_FILE_SIZE){
  10. //判断,如果上传的文件,大小超出了我们给的限制范围,退上传并产生错误提示
  11. exit("文件超出指定大小");
  12. }

将我们指定的文件大小,定义为$MAX_FILE_SIZE,该变量的计数单位为byte,对应上传文件的 $_FILES[‘file‘][‘size‘]大小。示例代码中,限制大小约为100K及以下的文件。

第三步 : 判断文件的mime类型是否正确

所有的上传操作都需要判断用户上传的文件,是否符合要求,不可用的文件上传以后,对于线上应用的整体展示效果,会造成恶劣的影响。所以我们需要通过mime类型和后缀名,来判断用户上传的文件是否符合要求。

想一想:通过JS如何控制上传文件?

下面的示例代码中,我们假设当前的项目需求为指定上传图片,要求上传后缀名为GIF或者jpg的文件,当用户上传不符合要求的文件时,返回错误提示。

  1. /*判断后缀名和MIME类型是否符合指定需求
  2. 例如:
  3. 当前项目指定上传后缀为.jpg或.gif的图片,则$allowSuffix = array(‘jpg‘,‘gif‘);
  4. */
  5. $allowSuffix = array(‘jpg‘,‘gif‘);
  6. //定义允许的后缀名数组
  7. $myImg = explode(‘.‘, $_FILES[‘file‘][‘name‘]);
  8. /*
  9. explode() 将一个字符串用指定的字符切割,并返回一个数组,这里我们将文件名用‘.‘‘切割,结果存在$myImg中,文件的后缀名即为数组的最后一个值
  10. */
  11. $myImgSuffix = array_pop($myImg);
  12. /*
  13. 根据上传文件名获取文件的后缀名
  14. 使用in_array()函数,判断上传文件是否符合要求
  15. 当文件后缀名不在我们允许的范围内时退出上传并返回错误信息
  16. */
  17. if(!in_array($myImgSuffix, $allowSuffix)){
  18. exit("文件后缀名不符");
  19. }
  20. /*
  21. mime类型和文件后缀名的对应关系,我们可以通过很多途径查询到,为了避免用户自主修改文件后缀名造成文件无法使用。
  22. mime类型也必须做出限制检查mime类型,是为了防止上传者直接修改文件后缀名
  23. 导致文件不可用或上传的文件不符合要求。
  24. */
  25. //数组内容为允许上传的mime类型
  26. $allowMime = array(
  27. "image/jpg",
  28. "image/jpeg",
  29. "image/pjpeg",
  30. "image/gif"
  31. );
  32. if(!in_array($_FILES[‘file‘][‘type‘], $allowMime)){ //判断上传文件的mime类型是否在允许的范围内
  33. exit(‘文件格式不正确,请检查‘);
  34. //如果不在允许范围内,退出上传并返回错误信息
  35. }

第四步 : 生成指定的路径和文件名

按照项目的文件安排,生成文件存储路径,为了避免文件名重复而产生的错误,按照一定的格式,生成一个随机文件名。

  1. //指定上传文件夹
  2. $path = "upload/images/";
  3. /*
  4. 根据当前时间生成随机文件名,本行代码是使用当前时间 + 随机一个0-9的数字组合成文件名,后缀即为前面取到的文件后缀名
  5. */
  6. $name = date(‘Y‘).date(‘m‘).date("d").date(‘H‘).date(‘i‘).date(‘s‘).rand(0,9).‘.‘.$myImgSuffix;

第五步 : 判断是否是上传文件

is_uploaded_file()函数是专用的函数,来判断目标文件是否是上传文件。

  1. <?php
  2. //使用is_uploaded_file()判断是否是上传文件,函数介绍见上文
  3. if(is_uploaded_file($_FILEs[‘file‘][‘tmp_name‘])){
  4. }
  5. ?>

第六步,移动文件到指定位置

使用move_uploaded_file()函数,将文件移动到指定的位置并命名
需要注意的是,Linux系统中对目标目录是否有权限及磁盘空间是否足够,否则会导致上传操作失败。

  1. /*
  2. 使用move_uploaded_file()移动上传文件至指定位置,第一个参数为上传文件,第二个参数为我们在前面指定的上传路径和名称。
  3. */
  4. if(move_uploaded_file($_FILEs[‘file‘][‘tmp_name‘], $path.$name)){
  5. //提示文件上传成功
  6. echo "上传成功";
  7. }else{
  8. /*
  9. 文件移动失败,检查磁盘是否有足够的空间,或者linux类系统中文件夹是否有足够的操作权限
  10. */
  11. echo ‘上传失败‘;
  12. }
  13. }else{
  14. echo ‘不是上传文件‘;
  15. }
  16. }
  17. ?>

我们将这个文件片段整理成一整个文件:

  1. <?php
  2. if ($_FILES[‘file‘][‘error‘] > 0) {
  3. switch ($_FILES[‘file‘][‘error‘]) {
  4. //错误码不为0,即文件上传过程中出现了错误
  5. case ‘1‘:
  6. echo ‘文件过大‘;
  7. break;
  8. case ‘2‘:
  9. echo ‘文件超出指定大小‘;
  10. break;
  11. case ‘3‘:
  12. echo ‘只有部分文件被上传‘;
  13. break;
  14. case ‘4‘:
  15. echo ‘文件没有被上传‘;
  16. break;
  17. case ‘6‘:
  18. echo ‘找不到指定文件夹‘;
  19. break;
  20. case ‘7‘:
  21. echo ‘文件写入失败‘;
  22. break;
  23. default:
  24. echo "上传出错<br/>";
  25. }
  26. } else {
  27. $MAX_FILE_SIZE = 100000;
  28. if ($_FILES[‘file‘][‘size‘] > $MAX_FILE_SIZE) {
  29. exit("文件超出指定大小");
  30. }
  31. $allowSuffix = array(
  32. ‘jpg‘,
  33. ‘gif‘,
  34. );
  35. $myImg = explode(‘.‘, $_FILES[‘file‘][‘name‘]);
  36. $myImgSuffix = array_pop($myImg);
  37. if (!in_array($myImgSuffix, $allowSuffix)) {
  38. exit("文件后缀名不符");
  39. }
  40. $allowMime = array(
  41. "image/jpg",
  42. "image/jpeg",
  43. "image/pjpeg",
  44. "image/gif",
  45. );
  46. if (!in_array($_FILES[‘file‘][‘type‘], $allowMime)) {
  47. exit(‘文件格式不正确,请检查‘);
  48. }
  49. $path = "upload/images/";
  50. $name = date(‘Y‘) . date(‘m‘) . date("d") . date(‘H‘) . date(‘i‘) . date(‘s‘) . rand(0, 9) . ‘.‘ . $myImgSuffix;
  51. if (is_uploaded_file($_FILEs[‘file‘][‘tmp_name‘])) {
  52. if (move_uploaded_file($_FILEs[‘file‘][‘tmp_name‘], $path . $name)) {
  53. echo "上传成功";
  54. } else {
  55. echo ‘上传失败‘;
  56. }
  57. } else {
  58. echo ‘不是上传文件‘;
  59. }
  60. }
  61. ?>

多文件上传

介绍了PHP上传单个文件的过程。但是有些时候,为了使用方便,我们需要满足同时上传多个文件的需求。多文件上传原理相同,不过在处理数据时,需要对上传数据进行特殊处理。

  1. <html>
  2. <head>
  3. <meta charset="utf-8" />
  4. <title>单文件上传</title>
  5. </head>
  6. <body>
  7. <form action="morefile.php" method="post" enctype="multipart/form-data">
  8. <input type="file" name="file[]">
  9. <input type="file" name="file[]">
  10. <input type="submit" value="上传">
  11. </form>
  12. </body>
  13. </html>

这里是一个简易的上传页面,form表单同时提交了两个文件。我们 可以通过这个页面提交内容。

注意:

  1. input type="file" name="file[]"与之前相比file后多加了一个中括号

  2. 写了2个或者多个input type="file" name="file[]"

    我们使用 $_FILES 来接收文件信息,打印并查看数组:

    ```php
    <?php
    var_dump(FILES);//_FILES查看数组结构
    ?>

  1. 数组结构如下
  2. ```php
  3. array (size=1)
  4. ‘file‘ =>
  5. array (size=5)
  6. ‘name‘ =>
  7. array (size=2)
  8. //文件名
  9. 0 => string ‘psu.jpg‘ (length=7)
  10. 1 => string ‘qwe.jpg‘ (length=7)
  11. //文件mime类型
  12. ‘type‘ => array (size=2)
  13. 0 => string ‘image/jpeg‘ (length=10)
  14. 1 => string ‘image/jpeg‘ (length=10)
  15. //缓存文件
  16. ‘tmp_name‘ =>
  17. array (size=2)
  18. 0 => string ‘E:\wamp\tmp\phpF6D5.tmp‘ (length=23)
  19. 1 => string ‘E:\wamp\tmp\phpF6F5.tmp‘ (length=23)
  20. //文件错误信息
  21. ‘error‘ =>
  22. array (size=2)
  23. 0 => int 0
  24. 1 => int 0
  25. //文件大小
  26. ‘size‘ =>
  27. array (size=2)
  28. 0 => int 225824
  29. 1 => int 151651

我们可以看到,两个文件被存储在一个数组中,键名和上传单文件是相同。所以,需要我们用for()循环,来分别取出两个文件的需要用到的数据。

在$_FILES中同时保存了两个文件的数据,我们需要使用一个简单的循环,来读取单个文件的信息,并将文件移动到我们想要放的位置。

  1. for ($i=0; $i < count($_FILE[‘file‘][‘name‘]); $i++) {
  2. /*
  3. 用is_uploaded_file()函数判断是上传文件
  4. 并且没有出现错
  5. */
  6. if(is_uploaded_file($_FILEs[‘file‘][‘tmp_name‘][$i]) && $_FILEs[‘file‘][‘error‘][$i] == 0){
  7. if(move_uploaded_file($_FILEs[‘file‘][‘tmp_name‘][$i],‘upload/‘.$_FILE[‘file‘][‘name‘][$i])){
  8. //用move_uploaded_file()函数移动文件到指定的位置并使用文件原名
  9. echo "上传成功";
  10. }else{
  11. echo ‘上传失败‘;
  12. }
  13. }else{
  14. echo ‘上传失败‘;
  15. }
  16. }

详细的判断过程,参见单文件上传,这里只做了基本的判断,并没有对文件的大小及格式提醒。
请按照业务,自行判断文件大小及格式进行错误提醒。


扩展:文件进度条

当文件过大,或者用户网络状态一般,通常上传过程需要一段时间,如果这时候让用户白屏等待的话,相信大部分用户都会直接关掉应用,所以一个监控上传进度,并实时向用户报告的需求就被产品汪摆在了桌面上。
一个高逼格的上传进度提示,会让你的应用瞬间变成被仰望的存在。
PHP在5.4之前,总是需要安装额外的扩展才能监控到文件上传进度。
而从5.4开始,引入session.upload_progress[有点仿照Java的监听器]的新特性,我们只需要在php.ini中开启配置,即可通过session监控文件上传进度。在php.ini中。

注意:本章学习需要有session基础和javascript和ajax基础。

我们需要配置,注意查看和修改php.ini文件:

配置项 说明
session.upload_progress.enabled 是否启用上传进度报告(默认开启) 1为开启,0为关闭
session.upload_progress.cleanup 是否在上传完成后及时删除进度数据(默认开启, 推荐开启)
session.upload_progress.prefix[=upload_progress_] 进度数据将存储在_SESSION[session.upload_progress.prefix . _POST[session.upload_progress.name]]
session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] 如果_POST[session.upload_progress.name]没有被设置, 则不会报告进度.
session.upload_progress.freq[=1%] 更新进度的频率(已经处理的字节数), 也支持百分比表示’%’.
session.upload_progress.min_freq[=1.0] 更新进度的时间间隔(秒级)

开启了配置,我们可以通过session,来记录一个完整的文件上传进度。在session中,会出现一个如下结果的数组:

  1. $_SESSION["upload_progress_test"] = array(
  2. //请求时间
  3. "start_time" => 1234567890,
  4. // 上传文件总大小
  5. "content_length" => 57343257,
  6. //已经处理的大小
  7. "bytes_processed" => 453489,
  8. //当所有上传处理完成后为TRUE,未完成为false
  9. "done" => false,
  10. "files" => array(
  11. 0 => array(
  12. //表单中上传框的名字
  13. "field_name" => "file1",
  14. //上传文件的名称
  15. "name" => "test1.avi",
  16. //缓存文件,上传的文件即保存在这里
  17. "tmp_name" => "/tmp/phpxxxxxx",
  18. //文件上传的错误信息
  19. "error" => 0,
  20. //是否上传完成,当这个文件处理完成后会变成TRUE
  21. "done" => true,
  22. //这个文件开始处理时间
  23. "start_time" => 1234567890,
  24. //这个文件已经处理的大小
  25. "bytes_processed" => 57343250,
  26. ),
  27. 1 => array(
  28. "field_name" => "file2",
  29. "name" => "test2.avi",
  30. "tmp_name" => NULL,
  31. "error" => 0,
  32. "done" => false,
  33. "start_time" => 1234567899,
  34. "bytes_processed" => 54554,
  35. ),
  36. )
  37. );

这个数组详细记录了文件上传的进度,已经处理完的文件状态为true。下面,我们通过一个jQuery的AJAX实例,来学习一下文件上传进度的流程。

首先,在表单中,需要添加一个type=hidden 的 input 标签,标签 value 为自定义(建议使用有一定意义的值,因为这个值将要在后台用到)

  1. <form id="upload-form" action="upload.php" method="POST" enctype="multipart/form-data" style="margin:15px 0" target="hidden_iframe">
  2. <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="test" />
  3. <p><input type="file" name="file1" /></p>
  4. <p><input type="submit" value="Upload" /></p>
  5. </form>
  6. <div id="progress" class="progress" style="margin-bottom:15px;display:none;">
  7. <div class="label">0%</div>
  8. </div>

这里,添加了一个ID为progress的div,作为展示上传进度的容器。我们通过js的setTimeout(),定时执行ajax来获取文件上传进度,后台文件返回文件上传的进度百分比。

  1. <script src="../jquery/1.8.2/jquery.min.js"></script>
  2. <script type="text/javascript">
  3. function fetch_progress(){
  4. $.get(‘progress.php‘,{ ‘<?php echo ini_get("session.upload_progress.name"); ?>‘ : ‘test‘}, function(data){
  5. var progress = parseInt(data);
  6. $(‘#progress .label‘).html(progress + ‘%‘);
  7. if(progress < 100){
  8. setTimeout(‘fetch_progress()‘, 100); //当上传进度小于100%时,显示上传百分比
  9. }else{
  10. $(‘#progress .label‘).html(‘完成!‘); //当上传进度等于100%时,显示上传完成
  11. }
  12. }, ‘html‘);
  13. }
  14. $(‘#upload-form‘).submit(function(){
  15. $(‘#progress‘).show();
  16. setTimeout(‘fetch_progress()‘, 100);//每0.1秒执行一次fetch_progress(),查询文件上传进度
  17. });
  18. </script>

上面这段代码,就是通过JQ的ajax,每0.1秒返回一次文件上传进度。并把进度百分比在div 标签中显示。

后台代码,需要分为两个部分,upload.php处理上传文件。progress.php 获取session中的上传进度,并返回进度百分比。

这里文件上传就不再赘述,详细步骤参见上文,upload.php:

  1. <?php
  2. if(is_uploaded_file($_FILES[‘file1‘][‘tmp_name‘])){ //判断是否是上传文件
  3. //unlink($_FILES[‘file1‘][‘tmp_name‘]);
  4. move_uploaded_file($_FILES[‘file1‘][‘tmp_name‘], "./{$_FILES[‘file1‘][‘name‘]}"); //将缓存文件移动到指定位置
  5. }
  6. ?>

主要关注progress.php:

  1. <?php
  2. /*
  3. 开启session。请注意在session_start()之前,请不要有想浏览器输出内容的动作,否则可能引起错误。
  4. */
  5. session_start();
  6. //ini_get()获取php.ini中环境变量的值
  7. $i = ini_get(‘session.upload_progress.name‘);
  8. //ajax中我们使用的是get方法,变量名称为ini文件中定义的前缀 拼接 传过来的参数
  9. $key = ini_get("session.upload_progress.prefix") . $_GET[$i];
  10. //判断 SESSION 中是否有上传文件的信息
  11. if (!empty($_SESSION[$key])) {
  12. //已上传大小
  13. $current = $_SESSION[$key]["bytes_processed"];
  14. //文件总大小
  15. $total = $_SESSION[$key]["content_length"];
  16. //向 ajax 返回当前的上传进度百分比。
  17. echo $current < $total ? ceil($current / $total * 100) : 100;
  18. }else{
  19. echo 100;
  20. }
  21. ?>

到这里,文件进度的代码就已经完成了,配合前端,我们就可以做一个炫酷的文件上传功能啦!





前端PHP入门-031-文件上传-六脉神剑

标签:

原文地址:http://www.cnblogs.com/pangxiansheng/p/011e428af0f6c07acce16b6b800e7ee4.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!