单文件上传
前端页面

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload A File</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1024000" />
<input type="file" name="test_pic" />
<input type="submit" value="上传" />
</form>
</body>
</html>

后端实现upload.php

    <?php
/**
* Created by PhpStorm.
* Date: 2018/11/11
* Time: 14:06
*/ // 接收$_FILES数组
$key = 'test_pic';
$mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif'];//文件映射白名单
$extWhiteList = ['jpeg', 'jpg', 'png', 'gif'];//文件扩展名白名单
$allowSize = 2*1024*1024;
$destDir = './uploads'; $name = $_FILES[$key]['name']; // 源文件名称
$type = $_FILES[$key]['type']; // MIME 类型
$tmpName = $_FILES[$key]['tmp_name']; // 临时文件名称
$error = $_FILES[$key]['error']; // 错误信息
$size = $_FILES[$key]['size']; // 文件大小 字节 // 处理错误
// 0 - 无错误
if ($error > UPLOAD_ERR_OK) {
switch($error) {
// 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
case UPLOAD_ERR_INI_SIZE:
exit('文件大小超出了php.ini当中的upload_max_filesize的大小');
// 2 - 超出表单当中的MAX_FILE_SIZE的大小
case UPLOAD_ERR_FORM_SIZE:
exit('超出表单当中的MAX_FILE_SIZE的大小');
// 3 - 部分文件被上传
case UPLOAD_ERR_PARTIAL:
exit('部分文件被上传');
// 4 - 没有文件被上传
case UPLOAD_ERR_NO_FILE:
exit('没有文件被上传');
// 6 - 临时目录不存在
case UPLOAD_ERR_NO_TMP_DIR:
exit('临时目录不存在');
// 7 - 磁盘写入失败
case UPLOAD_ERR_CANT_WRITE:
exit('磁盘写入失败');
// 8 - 文件上传被PHP扩展阻止
case UPLOAD_ERR_EXTENSION:
exit('文件上传被PHP扩展阻止');
default:
exit('未知错误');
}
} // 限制文件的MIME
if (!in_array($type, $mimeWhiteList)) {
exit('文件类型' . $type . '不被允许!');
} // 限制文件的扩展名
$ext = pathinfo($name, PATHINFO_EXTENSION);
if (!in_array($ext, $extWhiteList)) {
exit('文件扩展名' . $ext . '不被允许!');
} // 限制文件大小
if ($size > $allowSize) {
exit('文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !');
} // 生成新的随机文件名称
// md5(rand());
$fileName = uniqid() . '.' . $ext; // 移动临时文件到指定目录当中并重新命名文件名
if (!file_exists($destDir)) {
mkdir($destDir, 0777, true);
}
if (is_uploaded_file($tmpName) && move_uploaded_file($tmpName, $destDir . '/' . $fileName)) {
echo "恭喜,文件上传成功";
} else {
echo "很抱歉,文件上传失败";
}

多文件上传,指定文件数量
前端页面

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Multiple Files</title>
</head>
<body>
<form action="multiple_upload.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1024000" />
<input type="file" name="test_pic1" />
<input type="file" name="test_pic2" />
<input type="file" name="test_pic3" />
<input type="submit" value="上传" />
</form>
</body>
</html>

后端实现multiple_upload.php

    <?php
/**
* Created by PhpStorm.
* Date: 2018/11/11
* Time: 14:54
*/ $errors = [];
$mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif'];
$extWhiteList = ['jpeg', 'jpg', 'png', 'gif'];
$allowSize = 2*1024*1024;
$destDir = './uploads'; foreach($_FILES as $key => $val) {
// name type tmp_name error size
// 接收$_FILES
$name = $_FILES[$key]['name']; // 源文件名称
$type = $_FILES[$key]['type']; // MIME 类型
$tmpName = $_FILES[$key]['tmp_name']; // 临时文件名称
$error = $_FILES[$key]['error']; // 错误信息
$size = $_FILES[$key]['size']; // 文件大小 字节 // 处理错误
// 0 - 无错误
if ($error > UPLOAD_ERR_OK) {
switch($error) {
// 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
case UPLOAD_ERR_INI_SIZE:
$errors[$key] = '文件大小超出了php.ini当中的upload_max_filesize的大小';
continue 2;
// 2 - 超出表单当中的MAX_FILE_SIZE的大小
case UPLOAD_ERR_FORM_SIZE:
$errors[$key] = '超出表单当中的MAX_FILE_SIZE的大小';
continue 2;
// 3 - 部分文件被上传
case UPLOAD_ERR_PARTIAL:
$errors[$key] = '部分文件被上传';
continue 2;
// 4 - 没有文件被上传
case UPLOAD_ERR_NO_FILE:
$errors[$key] = '没有文件被上传';
continue 2;
// 6 - 临时目录不存在
case UPLOAD_ERR_NO_TMP_DIR:
$errors[$key] = '临时目录不存在';
continue 2;
// 7 - 磁盘写入失败
case UPLOAD_ERR_CANT_WRITE:
$errors[$key] = '磁盘写入失败';
continue 2;
// 8 - 文件上传被PHP扩展阻止
case UPLOAD_ERR_EXTENSION:
$errors[$key] = '文件上传被PHP扩展阻止';
continue 2;
default:
$errors[$key] = '未知错误';
continue 2;
}
} // 限制MIME
if (!in_array($type, $mimeWhiteList)) {
$errors[$key] = '文件类型' . $type . '不被允许!';
continue;
} // 限制扩展名
$ext = pathinfo($name, PATHINFO_EXTENSION);
if (!in_array($ext, $extWhiteList)) {
$errors[$key] = '文件扩展名' . $ext . '不被允许!';
continue;
} // 限制大小
if ($size > $allowSize) {
$errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !';
continue;
} // 生成随机文件名称
$fileName = uniqid() . '.' . $ext; // 移动文件
if (!file_exists($destDir)) {
mkdir($destDir, 0777, true);
}
if (!is_uploaded_file($tmpName) || !move_uploaded_file($tmpName, $destDir . '/' . $fileName)) {
$errors[$key] = "很抱歉,文件上传失败";
continue;
}
} if (count($errors) > 0) {
var_dump($errors);
} else {
echo "文件全部上传成功";
}

多文件上传,不定文件数量
前端页面

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Multiple Files</title>
</head>
<body>
<form action="multiple_upload2.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="6024000" />
<input type="file" name="test_pic[]" />
<input type="file" name="test_pic[]" />
<input type="file" name="test_pic[]" />
<input type="submit" value="上传" />
</form>
</body>
</html>

后端实现multiple_upload2.php

    <?php
/**
* Created by PhpStorm.
* Date: 2018/11/11
* Time: 15:12
*/ $key = 'test_pic';
$mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif'];
$extWhiteList = ['jpeg', 'jpg', 'png', 'gif'];
$allowSize = 2*1024*1024;
$destDir = './uploads'; // 接收和处理$_FILES
if (!empty($_FILES[$key])) {
$files = [];
foreach($_FILES[$key]['name'] as $k => $v) {
$files[$k]['name'] = $v;
$files[$k]['type'] = $_FILES[$key]['type'][$k];
$files[$k]['tmp_name'] = $_FILES[$key]['tmp_name'][$k];
$files[$k]['error'] = $_FILES[$key]['error'][$k];
$files[$k]['size'] = $_FILES[$key]['size'][$k];
}
} $errors = [];
foreach($files as $file) {
// name type error size
$name = $file['name']; // 源文件名称
$type = $file['type']; // MIME 类型
$tmpName = $file['tmp_name']; // 临时文件名称
$error = $file['error']; // 错误信息
$size = $file['size']; // 文件大小 字节 // 处理错误
// 0 - 无错误
if ($error > UPLOAD_ERR_OK) {
switch($error) {
// 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
case UPLOAD_ERR_INI_SIZE:
$errors[$key] = $name . '文件大小超出了php.ini当中的upload_max_filesize的大小';
continue 2;
// 2 - 超出表单当中的MAX_FILE_SIZE的大小
case UPLOAD_ERR_FORM_SIZE:
$errors[$key] = $name . '超出表单当中的MAX_FILE_SIZE的大小';
continue 2;
// 3 - 部分文件被上传
case UPLOAD_ERR_PARTIAL:
$errors[$key] = $name . '部分文件被上传';
continue 2;
// 4 - 没有文件被上传
case UPLOAD_ERR_NO_FILE:
$errors[$key] = $name . '没有文件被上传';
continue 2;
// 6 - 临时目录不存在
case UPLOAD_ERR_NO_TMP_DIR:
$errors[$key] = $name . '临时目录不存在';
continue 2;
// 7 - 磁盘写入失败
case UPLOAD_ERR_CANT_WRITE:
$errors[$key] = $name . '磁盘写入失败';
continue 2;
// 8 - 文件上传被PHP扩展阻止
case UPLOAD_ERR_EXTENSION:
$errors[$key] = $name . '文件上传被PHP扩展阻止';
continue 2;
default:
$errors[$key] = $name . '未知错误';
continue 2;
}
} // 限制MIME类型
if (!in_array($type, $mimeWhiteList)) {
$errors[$key] = '文件类型' . $type . '不被允许!';
continue;
} // 限制扩展名
$ext = pathinfo($name, PATHINFO_EXTENSION);
if (!in_array($ext, $extWhiteList)) {
$errors[$key] = '文件扩展名' . $ext . '不被允许!';
continue;
} // 限制文件大小
if ($size > $allowSize) {
$errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !';
continue;
} // 生成随机文件名称
$fileName = uniqid() . '.' . $ext; // 移动文件
if (!file_exists($destDir)) {
mkdir($destDir, 0777, true);
}
if (!is_uploaded_file($tmpName) || !move_uploaded_file($tmpName, $destDir . '/' . $fileName)) {
$errors[$key] = "很抱歉,文件上传失败";
continue;
}
} if (count($errors) > 0) {
var_dump($errors);
} else {
echo "文件全部上传成功";
}

文件上传类封装 UploadFile.php
支持多文件或者单文件

    <?php
/**
* Created by PhpStorm.
* Date: 2018/11/11
* Time: 22:01
*/ class UploadFile
{ /**
*
*/
const UPLOAD_ERROR = [
UPLOAD_ERR_INI_SIZE => '文件大小超出了php.ini当中的upload_max_filesize的值',
UPLOAD_ERR_FORM_SIZE => '文件大小超出了MAX_FILE_SIZE的值',
UPLOAD_ERR_PARTIAL => '文件只有部分被上传',
UPLOAD_ERR_NO_FILE => '没有文件被上传',
UPLOAD_ERR_NO_TMP_DIR => '找不到临时目录',
UPLOAD_ERR_CANT_WRITE => '写入磁盘失败',
UPLOAD_ERR_EXTENSION => '文件上传被扩展阻止',
]; /**
* @var
*/
protected $field_name; /**
* @var string
*/
protected $destination_dir; /**
* @var array
*/
protected $allow_mime; /**
* @var array
*/
protected $allow_ext; /**
* @var
*/
protected $file_org_name; /**
* @var
*/
protected $file_type; /**
* @var
*/
protected $file_tmp_name; /**
* @var
*/
protected $file_error; /**
* @var
*/
protected $file_size; /**
* @var array
*/
protected $errors; /**
* @var
*/
protected $extension; /**
* @var
*/
protected $file_new_name; /**
* @var float|int
*/
protected $allow_size; /**
* UploadFile constructor.
* @param $keyName
* @param string $destinationDir
* @param array $allowMime
* @param array $allowExt
* @param float|int $allowSize
*/
public function __construct($keyName, $destinationDir = './uploads', $allowMime = ['image/jpeg', 'image/gif'], $allowExt = ['gif', 'jpeg'], $allowSize = 2*1024*1024)
{
$this->field_name = $keyName;
$this->destination_dir = $destinationDir;
$this->allow_mime = $allowMime;
$this->allow_ext = $allowExt;
$this->allow_size = $allowSize;
} /**
* @param $destinationDir
*/
public function setDestinationDir($destinationDir)
{
$this->destination_dir = $destinationDir;
} /**
* @param $allowMime
*/
public function setAllowMime($allowMime)
{
$this->allow_mime = $allowMime;
} /**
* @param $allowExt
*/
public function setAllowExt($allowExt)
{
$this->allow_ext = $allowExt;
} /**
* @param $allowSize
*/
public function setAllowSize($allowSize)
{
$this->allow_size = $allowSize;
} /**
* @return bool
*/
public function upload()
{
// 判断是否为多文件上传
$files = [];
if (is_array($_FILES[$this->field_name]['name'])) {
foreach($_FILES[$this->field_name]['name'] as $k => $v) {
$files[$k]['name'] = $v;
$files[$k]['type'] = $_FILES[$this->field_name]['type'][$k];
$files[$k]['tmp_name'] = $_FILES[$this->field_name]['tmp_name'][$k];
$files[$k]['error'] = $_FILES[$this->field_name]['error'][$k];
$files[$k]['size'] = $_FILES[$this->field_name]['size'][$k];
}
} else {
$files[] = $_FILES[$this->field_name];
} foreach($files as $key => $file) {
// 接收$_FILES参数
$this->setFileInfo($key, $file); // 检查错误
$this->checkError($key); // 检查MIME类型
$this->checkMime($key); // 检查扩展名
$this->checkExt($key); // 检查文件大小
$this->checkSize($key); // 生成新的文件名称
$this->generateNewName($key); if (count((array)$this->getError($key)) > 0) {
continue;
}
// 移动文件
$this->moveFile($key);
}
if (count((array)$this->errors) > 0) {
return false;
}
return true;
} /**
* @return array
*/
public function getErrors()
{
return $this->errors;
} /**
* @param $key
* @return mixed
*/
protected function getError($key)
{
return $this->errors[$key];
} /**
*
*/
protected function setFileInfo($key, $file)
{
// $_FILES name type temp_name error size
$this->file_org_name[$key] = $file['name'];
$this->file_type[$key] = $file['type'];
$this->file_tmp_name[$key] = $file['tmp_name'];
$this->file_error[$key] = $file['error'];
$this->file_size[$key] = $file['size'];
} /**
* @param $key
* @param $error
*/
protected function setError($key, $error)
{
$this->errors[$key][] = $error;
} /**
* @param $key
* @return bool
*/
protected function checkError($key)
{
if ($this->file_error > UPLOAD_ERR_OK) {
switch($this->file_error) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
case UPLOAD_ERR_PARTIAL:
case UPLOAD_ERR_NO_FILE:
case UPLOAD_ERR_NO_TMP_DIR:
case UPLOAD_ERR_CANT_WRITE:
case UPLOAD_ERR_EXTENSION:
$this->setError($key, self::UPLOAD_ERROR[$this->file_error]);
return false;
}
}
return true;
} /**
* @param $key
* @return bool
*/
protected function checkMime($key)
{
if (!in_array($this->file_type[$key], $this->allow_mime)) {
$this->setError($key, '文件类型' . $this->file_type[$key] . '不被允许!');
return false;
}
return true;
} /**
* @param $key
* @return bool
*/
protected function checkExt($key)
{
$this->extension[$key] = pathinfo($this->file_org_name[$key], PATHINFO_EXTENSION);
if (!in_array($this->extension[$key], $this->allow_ext)) {
$this->setError($key, '文件扩展名' . $this->extension[$key] . '不被允许!');
return false;
}
return true;
} /**
* @return bool
*/
protected function checkSize($key)
{
if ($this->file_size[$key] > $this->allow_size) {
$this->setError($key, '文件大小' . $this->file_size[$key] . '超出了限定大小' . $this->allow_size);
return false;
}
return true;
} /**
* @param $key
*/
protected function generateNewName($key)
{
$this->file_new_name[$key] = uniqid() . '.' . $this->extension[$key];
} /**
* @param $key
* @return bool
*/
protected function moveFile($key)
{
if (!file_exists($this->destination_dir)) {
mkdir($this->destination_dir, 0777, true);
}
$newName = rtrim($this->destination_dir, '/') . '/' . $this->file_new_name[$key];
if (is_uploaded_file($this->file_tmp_name[$key]) && move_uploaded_file($this->file_tmp_name[$key], $newName)) {
return true;
}
$this->setError($key, '上传失败!');
return false;
} /**
* @return mixed
*/
public function getFileName()
{
return $this->file_new_name;
} /**
* @return string
*/
public function getDestinationDir()
{
return $this->destination_dir;
} /**
* @return mixed
*/
public function getExtension()
{
return $this->extension;
} /**
* @return mixed
*/
public function getFileSize()
{
return $this->file_size;
} }

前端页面演示

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Upload Class</title>
</head>
<body>
<form action="TestUploadFile.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="10240000" />
<input type="file" name="test_pic[]" multiple="multiple"/>
<input type="submit" value="上传" />
</form>
</body>
</html>

后端配置演示TestUploadFile.php

    <?php
/**
* Created by PhpStorm.
* Date: 2018/11/11
* Time: 22:46
*/
require('UploadFile.php'); $upload = new UploadFile('test_pic');
$upload->setDestinationDir('./uploads');
$upload->setAllowMime(['image/jpeg', 'image/gif']);
$upload->setAllowExt(['gif', 'jpeg']);
$upload->setAllowSize(2*1024*1024);
if ($upload->upload()) {
var_dump($upload->getFileName());
var_dump($upload->getDestinationDir());
var_dump($upload->getExtension());
var_dump($upload->getFileSize());
} else {
var_dump($upload->getErrors());
} 文件下载
<?php
/**
* Created by PhpStorm.
* Date: 2018/11/12
* Time: 00:07
*/
//演示
//echo '<a href="./uploads/test.jpg">下载图片</a>'; // download.php?file=5be822d84c42a.jpeg // 接收get参数
if (!isset($_GET['file'])) {
exit('需要传递文件名称');
} if (empty($_GET['file'])) {
exit('请传递文件名称');
} // 获取远程文件地址
$file = './uploads/' . $_GET['file']; if (!file_exists($file)) {
exit('文件不存在');
} if (!is_file($file)) {
exit('文件不存在');
} if (!is_readable($file)) {
exit('文件不可读');
} // 清空缓冲区
ob_clean(); // 打开文件 rb
$file_handle = fopen($file, 'rb'); if (!$file_handle) {
exit('打开文件失败');
} // 通知浏览器
header('Content-type: application/octet-stream; charset=utf-8');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="' . urlencode(basename($file)) . '"'); // 读取并输出文件
while(!feof($file_handle)) {
echo fread($file_handle, 10240);
} // 关闭文档流
fclose($file_handle);

php文件上传与下载(附封装好的函数文件)的更多相关文章

  1. struts2学习(14)struts2文件上传和下载(4)多个文件上传和下载

    四.多个文件上传: 五.struts2文件下载: 多个文件上传action com.cy.action.FilesUploadAction.java: package com.cy.action; i ...

  2. WordPress文件上传与下载问题解决

    网上流传了一些修改WordPress文件上传大小限制的做法,大部分是一个版本,而且说得不够准确,特别是对于生手的指导性不强,本文总结了使用Wordpress博客的朋友在文件上传与下载时大小限制,及文件 ...

  3. 使用SpringMVC框架实现文件上传和下载功能

    使用SpringMVC框架实现文件上传和下载功能 (一)单个文件上传 ①配置文件上传解释器 <!—配置文件上传解释器 --> <mvc:annotation-driven>&l ...

  4. C#实现FTP文件的上传、下载功能、新建目录以及文件的删除

    本来这篇博文应该在上周就完成的,可无奈,最近工作比较忙,没有时间写,所以推迟到了今天.可悲的是,今天也没有太多的时间,所以决定给大家贴出源码,不做详细的分析说明,如果有不懂的,可以给我留言,我们共同讨 ...

  5. koa2基于stream(流)进行文件上传和下载

    阅读目录 一:上传文件(包括单个文件或多个文件上传) 二:下载文件 回到顶部 一:上传文件(包括单个文件或多个文件上传) 在之前一篇文章,我们了解到nodejs中的流的概念,也了解到了使用流的优点,具 ...

  6. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  7. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  8. JavaWeb学习总结,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  9. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

随机推荐

  1. [MacOS]MacOS字体文件位置

    $ cd /System/Library/Fonts $ ls Apple Braille Outline 6 Dot.ttf Noteworthy.ttc SFCompactText-Regular ...

  2. K8S ConfigMap使用

    k8s系列文章: 什么是K8S configmap是k8s的一个配置管理组件,可以将配置以key-value的形式传递,通常用来保存不需要加密的配置信息,加密信息则需用到Secret,主要用来应对以下 ...

  3. Java的七大排序

    一.各个算法的时间复杂度 二,具体实现 1.直接选择排序 基本思想:在长度为n的序列中,第一次遍历找到该序列的最小值,替换掉第一个元素,接着从第二个元素开始遍历,找到剩余序列中的最小值,替换掉第二个元 ...

  4. MySQL命令随手记之alter

    修改表名 alter table 表名 rename 新表名; //修改table名 添加.删除.修改字段 alter table 表名 add [column] 列名 数据类型; //添加colum ...

  5. js+vue、纯js 按条件分页

    听说大牛都从博客开始的... 人狠话不多,翠花上酸菜代码: 有注解基本上都看的懂!但是自己还是要注意以下几点,免得以后再浪费时间. #.vue 中监听事件 v-on:change=“vueChange ...

  6. vue垂死挣扎系列(一)——vue-cli快速搭建

    项目安装(windows10安装环境+vue-cli 2.x) 安装node 在官网上下载稳定版本的node node.js官网 一路傻瓜安装 测试是否安装成功 cmd中node --version ...

  7. ASPNetCore 发布到IIS

    ASPNetCore 发布到IIS 准备工作 1.1.  安装IIS.(具体操作不再说明) 安装成功后再浏览器输入localhost得到的页面如下 1.2.  安装dotnet-hosting-2.2 ...

  8. Android中四种补间动画的使用示例(附代码下载)

    场景 Android中四种补间动画. 透明度渐变动画 旋转动画 缩放动画 平移动画 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程 ...

  9. 【读书笔记】https://source.android.google.cn/devices/bootloader

    https://source.android.google.cn/devices/bootloader 本文主要记录aosp官网关于bootloader的相关资料 Bootloader A bootl ...

  10. jq--实现自定义下拉框

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...