布局很简单,只列举 关键部位的代码
_renderAddImageView(index){ if (this.state.avatarSource!=null&&index<this.state.avatarSource.length) { return( <Image source={require('../../img/service/虚线框.png')} style ={addImageViewStyles.image}> <Image source={this.state.avatarSource[index]} style={addImageViewStyles.imageL} /> <TouchableOpacity onPress ={this.deleteLoadedImage.bind(this,index)} style={addImageViewStyles.rightDelButton}> <Image source={require('../../img/service/删除.png')}/> </TouchableOpacity> </Image> ); } if ((this.state.avatarSource==null||this.state.avatarSource.length<1)&&index==1){ return null; } return ( <Image source={require('../../img/service/虚线框.png')} style ={styles.image}> <TouchableOpacity onPress = {this.addOnClicked.bind(this)}> <Image source={require('../../img/service/添加.png')}></Image> </TouchableOpacity> <Text style ={styles.normalTitle}>上传图片</Text> <Text style ={styles.normalText}>(最多能上传2张)</Text> </Image> ); }
根据不同端访问相册的不同可分别处理 ,由于涉及到原生和react native 的混合开发,相对复杂建议使用一个兼容iOS 和Android的第三方库来实现该功能。下面的示例使用的是react-native-image-picker 。
ImagePicker.launchImageLibrary(options, (response) => { if (response.didCancel) { console.log('用户点击了取消'); } else if (response.error) { console.log('ImagePicker 出错: ', response.error); } else { let source = {uri: 'data:image/jpeg;base64,' + response.data, isStatic: true}; if (Platform.OS === 'ios') { source = {uri: response.uri.replace('file://', ''), isStatic: true}; } else { source = {uri: response.uri, isStatic: true}; } let imageArray = this.state.avatarSource; imageArray.push(source); let imgFileNameArray = this.state.imgFileName; if (response.fileName!=null) { imgFileNameArray.push(response.fileName); } this.setState({ avatarSource:imageArray, imgFileName:imgFileNameArray }); } });
封装上传文件的接口
function fetchUploadAction(...props) {
this.url = props.shift(1);
this.options = props.shift(1);
return fetch(this.url, Object.assign({}, this.options))
.then((response) => {
const bodyBlob = response["_bodyBlob"];
if (bodyBlob != null && bodyBlob.size == 0) {
return null;
}
const headers = response["headers"]
if (headers != null) {
const mapHeader = headers["map"];
if (mapHeader != null) {
contentLength = mapHeader["content-length"];
if (contentLength != null && contentLength == 0) {
return null;
}
}
}
return response.json()
});
调用上面的接口,专门用来上传图片
//imagesObject是存储调用相册返回的选中的图片的多个对象,可获得图片uri
//fileName 这几个对象对应的文件名,也可不要这个参数 从上面的uri中截取
function postUpLoadImage_Attachment(imagesObject,fileName) {
var apiPort = "v1/cases/attachments/";
let retObject = null;
for(let i=0;imagesObject!=null&&i<imagesObject.length;i++){
let formData = new FormData();
let tmpUri =imagesObject[i];
//DateFormatTool.GetDateTimeStrValue() 是获取当前时间的时间戳字符串
let tmpfileName=DateFormatTool.GetDateTimeStrValue()+"_"+i+"_"+fileName[i];
let file = {uri:tmpUri.uri,type:'multipart/form-data',name:tmpfileName};
formData.append("attachment",file);
retObject=fetchUploadAction(`${kParCRMAPIBaseURL}/${apiPort}`, {
method: 'post',
headers: {
'Content-Type':'multipart/form-data',
},
body: formData,
});
}
return retObject;
},
try {
CRMServiceApiNet.postUpLoadImage_Attachment(this.state.avatarSource,this.state.imgFileName)
.then((response) => { this.updateLoadingState(false); if(response!=null&&response.code) { HandleErrorManager.handleObj(response); } else { console.log("上传成功"+response); this.sendTheQuestionSuccess(); } }) } catch(e) { this.updateLoadingState(false); StandardAlertCom.show('提示','网络错误',[ { text: '确定', onPress: () => console.log('确定 Pressed!') } ]); }
安装Apache ,配置服务器环境 , 设置最大的上传文件的大小和上传文件的并发个数 ,以及要上传到的目录的属性必须为可写。。。下面是以mac 电脑为例,配置服务器相关属性。
这一步跳过 ,因为mac 上自带 Apache 环境 。
使用命令行工具 cd 到 /etc目录 如图
运行命令 ls *php* ,找到php.init 文件,如果没有 则找到 php.ini.default copy 一份,
注意将原文件copy 一份 ,以防修改出错
file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开
upload_max_filesize = 8m ; 即允许上传文件大小的最大值。默认为2M
post_max_size = 8m ;指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值。默认为8M
一般地,设置好上述四个参数后,上传<=100M的文件是不成问题,在网络正常的情况下。
但如果要上传>8M的大体积文件,只设置上述四项还一定能行的通。还得设置以下参数:
max_execution_time = 600 ;每个PHP页面运行的最大时间值(秒),默认30秒
max_input_time = 600 ;每个PHP页面接收数据所需的最大时间,默认60秒
memory_limit = 8m ;每个PHP页面所吃掉的最大内存,默认8M
如果上面配置后还不成功,你可以把php.ini.default 再配置一下。
函数原型: pathinfo(path,options)
定义和用法
pathinfo() 函数以数组或字符串的形式返回关于文件路径的信息。
返回的数组元素如下:
[dirname]: 返回文件路径中的目录部分
[basename]: 返回文件路径中文件名的部分
[extension]: 返回文件路径中文件的类型的部分
定义和用法
file_exists() 函数检查文件或目录是否存在。
如果指定的文件或目录存在则返回 true,否则返回 false。
语法
file_exists(path)
参数 描述
path 必需。规定要检查的路径。
getimagesize() 函数用于获取图像尺寸,类型等信息。
本函数可用来取得 GIF、JPEG 及 PNG 格式的图片的高与宽,(不需要安装 GD library 就可以使用本函数)
返回的数据解析(成功返回一个数组,失败则返回 FALSE )
返回的数组有四个元素。
返回数组的第一个元素 (索引值 0) 是图片的高度,单位是像素 (pixel)。
第二个元素 (索引值 1) 是图片的宽度。
第三个元素 (索引值 2) 是图片的文件格式,其值 1 为 GIF 格式、 2 为 JPEG/JPG 格式、3 为 PNG 格式。
第四个元素 (索引值 3) 为图片的高与宽字符串,height=xxx width=yyy。可省略的参数 imageinfo 用来取得一些图片的相关信息.
函数原型 : move_uploaded_file(file ,newloc)
参数描述
file 必需。规定要移动的文件。
newloc 必需。规定文件的新位置。
说明
该函数检查并确保由 file 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST 上传机制所上传的)。如果文件合法,则将其移动为由 newloc 指定的文件。
如果 file 不是合法的上传文件,不会出现任何操作,move_uploaded_file() 将返回 false。
如果 file 是合法的上传文件,但出于某些原因无法移动,不会出现任何操作,move_uploaded_file() 将返回 false,此外还会发出一条警告。
这种检查显得格外重要,如果上传的文件有可能会造成对用户或本系统的其他用户显示其内容的话。
本代码设计一个文件上传管理类 ,定义一系列的操作。$this->retErrorDetail 为返回的错误信息,如果没有出错该值则为 null 。如果上传成功则返回一个json 数据,(哪些文件上传成功,文件的参数,哪些失败,失败的原因)。
下面是主要函数的示例代码:
function handleUploadAndSave($formkey){
$FilekeyValue_FormData =$formkey;
$theFile = $_FILES[$FilekeyValue_FormData]["tmp_name"];
//Post multipart
if ($_FILES[$FilekeyValue_FormData]["error"] > 0){
$this->retErrorDetail="Error: " . $_FILES[$FilekeyValue_FormData]["error"];
$this->formatDetailError($this->retErrorDetail);
return false;
}else{
//打印上传二进制文件信息
foreach($_FILES[$FilekeyValue_FormData] as $key=>$value){
$this->formatDetailSuccess($key."=>".$value. "\n");
}
//定义上传的文件 保存的路径
$target_dir = "/Users/XXXX/myWebServer/uploads/".$this->caseId."/";
$target_file = $target_dir.basename($_FILES[$FilekeyValue_FormData]["name"]);
$uploadOK = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// 检查 上传的文件是否为图片
$check = getimagesize($theFile);
if($check !== false) {
$this->formatDetailSuccess("文件是一个 图片- " . $check["mime"] . ".");
$uploadOk = 1;
} else {
$this->retErrorDetail="文件不是图片.";
$this->formatDetailError($this->retErrorDetail);
$uploadOk = 0;
}
// 检测要上传的文件是否 已经被上传(在该目录下是否已存在该文件)
if (file_exists($target_file)) {
$this->retErrorDetail="抱歉, 该文件已存在.";
$this->formatDetailError($this->retErrorDetail);
$uploadOk = 0;
}
//检测要上传文件的大小 >1mb
if ($_FILES[$FilekeyValue_FormData]["size"] > 1024*1024) {
$this->retErrorDetail="抱歉, 您上传的文件太大了";
$this->formatDetailError($this->retErrorDetail);
$uploadOk = 0;
}
//检测后缀名称
$imageFileType = strtolower($imageFileType);
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
$this->retErrorDetail= "抱歉, 仅支持 JPG, JPEG, PNG & GIF files";
$this->formatDetailError($this->retErrorDetail);
$uploadOk = 0;
}
//检测是否上传成功
if ($uploadOk == 0) {
$this->retErrorDetail="抱歉, 您的文件没有被上传成功.";
$this->formatDetailError($this->retErrorDetail);
} else {
if (!mkdir("uploads")){
$this->formatDetailSuccess("创建目录失败");
return false;
}
if (move_uploaded_file($theFile,$target_file))
{
$this->formatDetailSuccess("文件已经被上传成功.");
} else {
$this->retErrorDetail="抱歉, 保存文件时出现未知错误.";
$this->formatDetailError($this->retErrorDetail);
}
}
}
if($uploadOk==0){
return false;
}
return true;
}
在 uploads 目录下 ,找到创建的case 。(联系方式和具体的描述写在 文档里)