آپلود عکس در سرور با استفاده از PHP در React Native


آپلود عکس یکی از عملیات های پرکاربرد و مهم در توسعه اپلیکیشن های React Native است زیرا در حال حاضر همه برنامه های Android و IOS کاملا پویا هستند و کاربر میتواند به سیستم وارد شود و اطلاعات پروفایل خودش رو ویرایش کنه که عکس نمایه یکی از مهم ترین اون هاست.یا در اپلیکیشن هایی مثل دیوار ، شیپور ، اپلیکیشن های گردشگری یا شبکه های اجتماعی معمولا عکس های مورد نظرتون رو به اشتراک میزارید.بنابراین در این آموزش متنی ما قصد داریم یک اپلیکیشن با React Native با قابلیت گرفتن عکس یا انتخاب از گالری و آپلود در سرور توسعه بدیم.
لیست کتابخانه هایی که در این پروژه استفاده میکنیم:
- react-native-image-picker : To pick image form gallery or camera.
- rn-fetch-blob : Send selected image to server.
1.نصب کتابخانه react-native-image-picker
قبل از شروع به کدنویسی ما نیاز داریم که کتابخانه react-native-image-picker رو نصب کنیم.برای نصب این کتابخانه نیازه که دایرکتوری پروژه رو در Command Prompt یا Terminal باز کنیم و دستور زیر رو اجرا کنیم.
1 |
npm install react-native-image-picker@latest --save |
2.بعد از نصب موفقیت آمیز کتابخانه react-native-image-picker باید دستور react–native link رو اجرا کنیم.این دستور باعث میشه تا پروژه به صورت کامل re-index بشه و کتابخانه react-native-image-picker در index پروژه قرار بگیره.
3.پیکربندی پروژه برای پلتفرم Android
1.فایل build.gradle رو در در پوشه YourReactNativeProject/android.
2.جایگزین کردن classpath ‘com.android.tools.build:gradle:2.2.+’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.+' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { mavenLocal() jcenter() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url "$rootDir/../node_modules/react-native/android" } } } |
3.فایل YourReactNativeProjectFolder/android/gradle/wrapper/gradle-wrapper.properties و distributionUrl رو با
1 |
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip |
جایگزین کنید.کد کامل فایل gradle-wrapper.properties بصورت زیر است.
1 2 3 4 5 |
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip |
4.سرانجام فایل AndroidManifest.xml رو از مسیر YourReactNativeProjectFolder\android\app\src\main باز کنید . CAMERA permission و WRITE_EXTERNAL_STORAGE permission رو اضافه میکنیم.کد کامل فایل AndroidManifest.xml بصورت زیر است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.imagepickerproject" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" /> <application android:name=".MainApplication" android:allowBackup="true" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> </application> </manifest> |
4.پیکربندی پروژه برای پلتفرم IOS
1.فایل YourReactNativeProject -> ios – > YourProjectName.xcodeproj رو باز کنید.
2.فایل info.plist رو از side panel باز کنید.این فایل شامل اطلاعات مفیدی در مورد پروژه است.
3.بر روی آیکون + در بالای صفحه کلیک کنید.
4. Privacy – Camera Usages Description رو شبیه اسکرین شات زیر انتخاب کنید.
5.Privacy – Photo Library Usages رو انتخاب کنید.
6.حالا باید برای premission هایی که اضافه کردیم یک سری اطلاعات و توضیحات قرار شبیه اسکرین شات زیر قرار بدیم.
5.نصب کتابخانه rn-fetch-blob library :
1.دایرکتوری پروژه رو در CMD باز کنید و دستور زیر رو اجرا کنید.
1 |
npm install --save rn-fetch-blob |
2.بعد از نصب موفقیت آمیز کتابخانه باید دستور react–native link رو اجرا کنیم.این دستور باعث میشه تا پروژه به صورت کامل re-index بشه و کتابخانه در index پروژه قرار بگیره.
6.ایجاد دیتابیس MySQL و جدول در PhpMyAdmin:
1. ایجاد یک دیتابیس جدید به نام mydatabase .
2.درون این دیتابیس باید یک جدول به نام image_upload_table با 3 ستون id, image_tag و image_path ایجاد کنیم.از این جدول برای ذخیره سازی URL عکس و تگ های عکس استفاده میشود.
6.برنامه نویسی سمت سرور
من یک پوشه به اسم Project و داخلش یک پوشه به اسم Uploads ایجاد کردم.تمامی عکس ها درون این پوشه ذخیره میشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php //Define your host here. $hostname = "localhost"; //Define your database User Name here. $username = "root"; //Define your database Password here. $password = ""; //Define your Database Name here. $dbname = "mydatabase"; $conn = mysql_connect($hostname, $username, $password); mysql_select_db($dbname, $conn); // Type your website name or domain name here. $domain_name = "http://192.168.2.102/Project/" ; // Image uploading folder. $target_dir = "uploads"; // Generating random image name each time so image name will not be same . $target_dir = $target_dir . "/" .rand() . "_" . time() . ".jpeg"; // Receiving image tag sent from application. $img_tag = $_POST["image_tag"]; // Receiving image sent from Application if(move_uploaded_file($_FILES['image']['tmp_name'], $target_dir)){ // Adding domain name with image random name. $target_dir = $domain_name . $target_dir ; // Inserting data into MySQL database. mysql_query("insert into image_upload_table ( image_tag, image_path) VALUES('$img_tag' , '$target_dir')"); $MESSAGE = "Image Uploaded Successfully." ; // Printing response message on screen after successfully inserting the image . echo json_encode($MESSAGE); } ?> |
7.فایل App.js رو باز کنید
8.ایمپورت کردن کامپوننت های StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput و Alert در پروژه.
1 2 3 |
import React, { Component } from 'react'; import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from 'react-native'; |
9.ایمپورت کردن ماژول های ImagePicker و RNFetchBlob از کتابخانه های react-native-image-picker و rn-fetch-blob .
1 2 3 |
import ImagePicker from 'react-native-image-picker'; import RNFetchBlob from 'rn-fetch-blob'; |
10.ایجاد یک کلاس به نام Project در فایل App.js
1 2 3 4 5 6 |
export default class Project extends Component { } |
11.ایجاد ()constructor و تعریف 3 state به نام های ImageSource, data و Image_TAG.
ImageSource : برای نگه داری path عکس انتخاب شده از گالری یا گرفته شده از دوربین استفاده میشود.
data : برای نگه داری عکس انتخاب شده به عنوان object برای ارسال به سرور استفاده میشود.
Image_TAG : برای نگه داری تگ های عکس که همراه با عکس سمت سرور فرستاده میشود،استفاده میشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
constructor() { super(); this.state = { ImageSource: null, data: null, Image_TAG: '' } } |
12.ایجاد دو تابع به نام های selectPhotoTapped و ImagePicker.showImagePicker.این توابع بصورت از پیش تعریف شده در کتابخانه react native image picker موجود هستند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
selectPhotoTapped() { const options = { quality: 1.0, maxWidth: 500, maxHeight: 500, storageOptions: { skipBackup: true } }; ImagePicker.showImagePicker(options, (response) => { console.log('Response = ', response); if (response.didCancel) { console.log('User cancelled photo picker'); } else if (response.error) { console.log('ImagePicker Error: ', response.error); } else if (response.customButton) { console.log('User tapped custom button: ', response.customButton); } else { let source = { uri: response.uri }; this.setState({ ImageSource: source, data: response.data }); } }); } |
13.تعریف یک تابع به اسم ()uploadImageToServer . درون این تابع ما از متد RNFetchBlob.fetch() برای آپلود عکس انتخاب شده بر روی سرور.چون اپلیکیشن رو بر روی localhost تست میکنیم بنابراین باید IP address رو قرار بدیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
uploadImageToServer = () => { RNFetchBlob.fetch('POST', 'http://192.168.2.102/Project/upload_image.php', { Authorization: "Bearer access-token", otherHeader: "foo", 'Content-Type': 'multipart/form-data', }, [ { name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data }, { name: 'image_tag', data: this.state.Image_TAG } ]).then((resp) => { var tempMSG = resp.data; tempMSG = tempMSG.replace(/^"|"$/g, ''); Alert.alert(tempMSG); }).catch((err) => { // ... }) } |
14.اضافه کردن دو تا کامپوننت Touchable opacity و یک Text Input در بلاک render’s return .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
render() { return ( <View style={styles.container}> <TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}> <View style={styles.ImageContainer}> {this.state.ImageSource === null ? <Text>Select a Photo</Text> : <Image style={styles.ImageContainer} source={this.state.ImageSource} /> } </View> </TouchableOpacity> <TextInput placeholder="Enter Image Name " onChangeText={data => this.setState({ Image_TAG: data })} underlineColorAndroid='transparent' style={styles.TextInputStyle} /> <TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} > <Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text> </TouchableOpacity> </View> ); } |
15.ایجاد استایل سفارشی.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', backgroundColor: '#FFF8E1', paddingTop: 20 }, ImageContainer: { borderRadius: 10, width: 250, height: 250, borderColor: '#9B9B9B', borderWidth: 1 / PixelRatio.get(), justifyContent: 'center', alignItems: 'center', backgroundColor: '#CDDC39', }, TextInputStyle: { textAlign: 'center', height: 40, width: '80%', borderRadius: 10, borderWidth: 1, borderColor: '#028b53', marginTop: 20 }, button: { width: '80%', backgroundColor: '#00BCD4', borderRadius: 7, marginTop: 20 }, TextStyle: { color: '#fff', textAlign: 'center', padding: 10 } }); |
16.کد کامل برنامه در فایل App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
import React, { Component } from 'react'; import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from 'react-native'; import ImagePicker from 'react-native-image-picker'; import RNFetchBlob from 'rn-fetch-blob'; export default class Project extends Component { constructor() { super(); this.state = { ImageSource: null, data: null, Image_TAG: '' } } selectPhotoTapped() { const options = { quality: 1.0, maxWidth: 500, maxHeight: 500, storageOptions: { skipBackup: true } }; ImagePicker.showImagePicker(options, (response) => { console.log('Response = ', response); if (response.didCancel) { console.log('User cancelled photo picker'); } else if (response.error) { console.log('ImagePicker Error: ', response.error); } else if (response.customButton) { console.log('User tapped custom button: ', response.customButton); } else { let source = { uri: response.uri }; this.setState({ ImageSource: source, data: response.data }); } }); } uploadImageToServer = () => { RNFetchBlob.fetch('POST', 'http://192.168.2.102/Project/upload_image.php', { Authorization: "Bearer access-token", otherHeader: "foo", 'Content-Type': 'multipart/form-data', }, [ { name: 'image', filename: 'image.png', type: 'image/png', data: this.state.data }, { name: 'image_tag', data: this.state.Image_TAG } ]).then((resp) => { var tempMSG = resp.data; tempMSG = tempMSG.replace(/^"|"$/g, ''); Alert.alert(tempMSG); }).catch((err) => { // ... }) } render() { return ( <View style={styles.container}> <TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}> <View style={styles.ImageContainer}> {this.state.ImageSource === null ? <Text>Select a Photo</Text> : <Image style={styles.ImageContainer} source={this.state.ImageSource} /> } </View> </TouchableOpacity> <TextInput placeholder="Enter Image Name " onChangeText={data => this.setState({ Image_TAG: data })} underlineColorAndroid='transparent' style={styles.TextInputStyle} /> <TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} > <Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text> </TouchableOpacity> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', backgroundColor: '#FFF8E1', paddingTop: 20 }, ImageContainer: { borderRadius: 10, width: 250, height: 250, borderColor: '#9B9B9B', borderWidth: 1 / PixelRatio.get(), justifyContent: 'center', alignItems: 'center', backgroundColor: '#CDDC39', }, TextInputStyle: { textAlign: 'center', height: 40, width: '80%', borderRadius: 10, borderWidth: 1, borderColor: '#028b53', marginTop: 20 }, button: { width: '80%', backgroundColor: '#00BCD4', borderRadius: 7, marginTop: 20 }, TextStyle: { color: '#fff', textAlign: 'center', padding: 10 } }); |
اسکرین شات :
یادگیری react native
اگر قصد یادگیری react native به صورت کامل و تخصصی را دارید ، پیشنهاد می کنم آموزش جامع و پروژه محور react native را مشاهده کنید.
دیدگاهتان را بنویسید