Just Simple Info

Pages

Upload File to Server With Extra String Data In Android




I developing android application that need to upload images in server using okhttp3 library.
This library work great with small amount of time writing code. Then suddenly my internet connection get worst. I thought my application not working because no server response for almost a minute. Luckily android studio has great tool for debugging. I notice that my application have network activity therefore the android application is working.

So I write simple code to show uploading progress to notify user what happening.


Android file structure :
  • CustomRequestBody.java
  • Data.java
  • ItemRecyclerViewAdapter.java
  • MainActivity.java
  • PopupOfProgress.java
  • UploaderAsyncTask.java
Android xml structure:
  • activity_main.xml
  • image_item.xml
  • upload_progress.xml
Php file structure:
  • index.php
  • upload_receiver.php
Below are the JAVA codes:

1. CustomRequestBody.java

package com.simpleinfo.uploadfileswithphp;

import android.util.Log;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

public class CustomRequestBody extends RequestBody {

    RequestBody mDelegateRequestBody;
    ProgressListener mProgressListener;
    CountingSink mCountingSink;
    Data mData;

    long mContentLength = 0;
    CustomRequestBody(RequestBody delegateRequestBody,ProgressListener progressListener,Data data){

        mDelegateRequestBody = delegateRequestBody;

        try {
            mContentLength = mDelegateRequestBody.contentLength();
            Log.e("size",mDelegateRequestBody.contentLength()+"");
        } catch (IOException e) {
            e.printStackTrace();
        }
        mProgressListener = progressListener;
        mData = data;
    }

    @Override
    public long contentLength() {


        return mContentLength;
    }

    @Override
    public MediaType contentType() {
        return mDelegateRequestBody.contentType();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {

        if(mCountingSink == null){

            mCountingSink = new CountingSink(sink);


        }


        //CountingSink countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(mCountingSink);
        mDelegateRequestBody.writeTo(bufferedSink);
        bufferedSink.flush();

    }

    protected final class CountingSink extends ForwardingSink {

        long mUploaded = 0;
        long mContentLenght = 0;
        public CountingSink(Sink delegate) {
            super(delegate);

            mContentLenght = contentLength();
        }
        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);

            mUploaded += byteCount;

            if(mProgressListener !=null){
                mProgressListener.progress(byteCount,mContentLenght,mData);

                if( mUploaded >= CustomRequestBody.this.mContentLength ){

                    mProgressListener.onFileUploadDone(mData);
                }
            }


        }
    }
    public interface ProgressListener {
        void progress(long uploaded, long size, Data data);
        void onFileUploadDone(Data data);
        void onError(String errorMessage , Data data);
    }
}

2. Data.java

package com.simpleinfo.uploadfileswithphp;

public class Data {
    private String imageName;
    private String imagePath;
    private boolean isUploaded = false;


    public String getImageName() {
        return imageName;
    }

    public void setImageName(String imageName) {
        this.imageName = imageName;
    }

    public String getImagePath() {
        return imagePath;
    }

    public boolean isUploaded() {
        return isUploaded;
    }

    public void setUploaded(boolean uploaded) {
        isUploaded = uploaded;
    }

    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }


}

3. ItemRecyclerViewAdapter.java


package com.simpleinfo.uploadfileswithphp;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.File;
import java.util.List;

public class ItemRecyclerViewAdapter extends RecyclerView.Adapter<ItemRecyclerViewAdapter.CustomViewHolder>  {

    List<Data> mDatas;
    Context mContext;

    public ItemRecyclerViewAdapter(List<Data> datas,Context context){

        mDatas = datas;
        mContext = context;

    }


    @NonNull
    @Override
    public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        LayoutInflater inflater = LayoutInflater.from(mContext);

        CardView cardView = (CardView) inflater.inflate(R.layout.image_item,viewGroup,false);
        CustomViewHolder customViewHolder = new CustomViewHolder(cardView);

        return customViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder customViewHolder, int i) {
        Data data = mDatas.get(i);

        File file = new File(data.getImagePath());
        Bitmap bmp = BitmapFactory.decodeFile(file.getAbsolutePath());
        customViewHolder.mImageView.setImageBitmap(bmp);


        customViewHolder.mCardView.setTag(data);
        customViewHolder.mImageNameTextView.setText(data.getImageName());



        if(data.isUploaded()){
            customViewHolder.mStatusTextView.setText("Status : Uploaded");


        }else{

            customViewHolder.mStatusTextView.setText("");

        }

    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    class CustomViewHolder extends RecyclerView.ViewHolder{

        CardView mCardView;
        ImageView mImageView;
        TextView mImageNameTextView;
        TextView mStatusTextView;


        CustomViewHolder(@NonNull CardView cardView) {
            super(cardView);
            mCardView = cardView;
            mImageView = mCardView.findViewById(R.id.image_view);
            mImageNameTextView = mCardView.findViewById(R.id.image_name_textview);
            mStatusTextView = mCardView.findViewById(R.id.status_textview);

        }
    }
}

4. MainActivity.java


package com.simpleinfo.uploadfileswithphp;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    int GET_IMAGE_REQUEST_CODE = 1;

    RecyclerView mRecyclerView;
    RecyclerView.LayoutManager mLayoutManager;
    ItemRecyclerViewAdapter mAdapter;

    List<Data> mDatas = new ArrayList<>();
    PopupOfProgress mPopupOfProgress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView  = this.findViewById(R.id.recyclerview);
        mRecyclerView.setHasFixedSize(true);

        mLayoutManager = new GridLayoutManager(this,1);
        mRecyclerView.setLayoutManager(mLayoutManager);




    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();


        if (id == R.id.upload_file) {

            if(mDatas.size() == 0){

                AlertDialog alertDialog = new AlertDialog.Builder(this).create();
                alertDialog.setTitle("Message");
                alertDialog.setMessage("Please select file.");
                alertDialog.show();
                return false;
            }

            mPopupOfProgress = new PopupOfProgress(this);
            mPopupOfProgress.show();

            new UploaderAsyncTask(mDatas, new CustomProgressListener()).execute();

            return true;

        }else if(id == R.id.select_file){

            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), GET_IMAGE_REQUEST_CODE);

        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == GET_IMAGE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            //TODO: action


            ClipData clipData = null;

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {

                clipData = data.getClipData();
            }

            if(clipData == null){

                    String path = "";

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        path = this.getPathForKitKatAbove(this,data.getData());

                    }else{

                        path = this.getRealPathFromURI(data.getData());
                    }


                    Data imageData = new Data();
                    imageData.setImagePath(path);
                    imageData.setImageName(this.getImageName(path));

                    mDatas.add(imageData);

                    mAdapter =  new ItemRecyclerViewAdapter(mDatas,this);

                    mRecyclerView.setAdapter(mAdapter);
                    mRecyclerView.setItemViewCacheSize(1);

                    return;
                }




                int itemCount = clipData.getItemCount();

                for(int x = 0 ; x < itemCount ; x++){

                    ClipData.Item item = clipData.getItemAt(x);
                    Uri uri = item.getUri();
                    String path = "";

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

                        path = this.getPathForKitKatAbove(this,uri);

                    }else{

                        path= this.getRealPathFromURI(uri);


                    }


                    Data imageData = new Data();
                    imageData.setImagePath(path);
                    imageData.setImageName(this.getImageName(path));
                    mDatas.add(imageData);

                }




            mAdapter =  new ItemRecyclerViewAdapter(mDatas,this);

            mRecyclerView.setAdapter(mAdapter);
            mRecyclerView.setItemViewCacheSize(1);



        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    protected String getPathForKitKatAbove(Context context, Uri uri){

        String filePath = "";

        if(DocumentsContract.isDocumentUri(context, uri)) {

            String id = DocumentsContract.getDocumentId(uri);
            String splitedId = id.split(":")[1];

            String[] column = {MediaStore.Images.Media.DATA};


            Cursor cursor = getContentResolver().
                    query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            column,  MediaStore.Images.Media._ID + "=?", new String[]{splitedId}, null);


            int columnIndex = cursor.getColumnIndex(column[0]);

            if (cursor.moveToFirst()) {
                filePath = cursor.getString(columnIndex);
            }
            cursor.close();
        }

        return filePath;

    }
    protected String getRealPathFromURI(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    private String getImageName(String path){
        String splitedString[] = path.split("/");


        return splitedString[splitedString.length -1];
    }

    private void updateStatusInView(){

        /**
         * dismiss upload dialog
         */
        mPopupOfProgress.mAlertDialog.dismiss();

        int count = mLayoutManager.getChildCount();

        for(int x = 0 ; x < count ; x++){

            CardView cardView = (CardView) mLayoutManager.getChildAt(x);

            Data data = (Data) cardView.getTag();
            TextView statusTextView = cardView.findViewById(R.id.status_textview);

            if(data.isUploaded()){

                statusTextView.setText("Status : Uploaded");

            }else{

                statusTextView.setText("Status : Not uploaded");
            }

        }


    }

    class CustomProgressListener implements CustomRequestBody.ProgressListener{

        int totalFileToUpload = 0 ;
        int totalFileAttempToUploaded = 0;

        float overAllDataUploaded = 0;


        public void setTotalFileToUpload(int totalFileToUpload) {
            this.totalFileToUpload = totalFileToUpload;


        }



        public void resetOverallUpload(){
            overAllDataUploaded = 0;
        }


        @Override
        public void progress(long uploaded, final long size, final Data data) {



            float sizeFloat = size;

            overAllDataUploaded += uploaded;



            final float percentageUpload = (overAllDataUploaded /  sizeFloat) * 100;

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    mPopupOfProgress.mPerFileProgress.setProgress((int) overAllDataUploaded);
                    mPopupOfProgress.mPerFileProgress.setMax((int) size);

                    mPopupOfProgress.mOverallProgress.setProgress(totalFileAttempToUploaded);
                    mPopupOfProgress.mOverallProgress.setMax(totalFileToUpload);
                    mPopupOfProgress.mFileNameTextView.setText(data.getImageName());
                    mPopupOfProgress.mPerFileProgressTextview.setText(String.format("%.2f",percentageUpload)+" %");
                    mPopupOfProgress.mOverallProgressTextView.setText(totalFileAttempToUploaded +"/"+totalFileToUpload);
                }
            });
        }

        @Override
        public void onFileUploadDone(Data data) {

            totalFileAttempToUploaded++;
            data.setUploaded(true);

            if(totalFileToUpload <= totalFileAttempToUploaded){

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        updateStatusInView();
                    }
                });

            }

        }

        @Override
        public void onError(String errorMessage, final Data data) {

            data.setUploaded(false);

            totalFileAttempToUploaded++;

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        mPopupOfProgress.mFileNameTextView.setText("Failed :"+data.getImageName());
                        mPopupOfProgress.mOverallProgressTextView.setText(totalFileAttempToUploaded +"/"+totalFileToUpload);

                        if(totalFileToUpload <= totalFileAttempToUploaded){
                        updateStatusInView();
                        }
                    }
                });


        }


    }

}

5. PopupOfProgress.java

package com.simpleinfo.uploadfileswithphp;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PopupOfProgress extends AlertDialog.Builder {

    Context mContext;
    ProgressBar mPerFileProgress;
    ProgressBar mOverallProgress;
    TextView mFileNameTextView;
    TextView mPerFileProgressTextview;
    TextView mOverallProgressTextView;
    AlertDialog mAlertDialog;

    public PopupOfProgress(Context context) {
        super(context);
        mContext = context;
        this.init();
    }

    @Override
    public AlertDialog show() {
        mAlertDialog =  super.show();

        return mAlertDialog;
    }

    private void init(){


        LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.upload_progress,null,false);
        mPerFileProgress = linearLayout.findViewById(R.id.per_file_progress);
        mFileNameTextView= linearLayout.findViewById(R.id.file_name_textview);
        mPerFileProgressTextview= linearLayout.findViewById(R.id.per_file_progress_textview);
        mOverallProgress = linearLayout.findViewById(R.id.overall_progress);
        mOverallProgressTextView = linearLayout.findViewById(R.id.overall_progress_textview);
        this.setView(linearLayout);

    }


}

5. UploaderAsyncTask.java


package com.simpleinfo.uploadfileswithphp;

import android.os.AsyncTask;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.util.List;

import okhttp3.CacheControl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;


public class UploaderAsyncTask extends AsyncTask<String,String,String> {

    private final static String TAG = "UploaderAsyncTask";
    private final static String URL = "http://192.168.43.202/upload_receiver.php";

    OkHttpClient mClient;
    List<Data> mDatas;
    MainActivity.CustomProgressListener mCustomProgressListener;


    public  UploaderAsyncTask(List<Data> mData,MainActivity.CustomProgressListener customProgressListener){

        mClient = new OkHttpClient();
        mDatas = mData;
        mCustomProgressListener = customProgressListener;

    }

    @Override
    protected String doInBackground(String... strings) {

        /**
         * for overall progress
         */
        mCustomProgressListener.setTotalFileToUpload(mDatas.size());


        for(Data  data : mDatas){

            MultipartBody.Builder mBuilder = new MultipartBody.Builder();
            mBuilder.setType(MultipartBody.FORM);
            File file = new File(data.getImagePath());


            mBuilder.addFormDataPart("image", data.getImageName(), RequestBody.create(MediaType.parse("image/jpeg"),file));
            mBuilder.addFormDataPart("image_description", "This is the description");

            MultipartBody requestBody = mBuilder.build();

            CustomRequestBody customRequestBody = new CustomRequestBody(requestBody,mCustomProgressListener,data);

            Request request = new Request.Builder()
                    .url(URL)
                    .post(customRequestBody)
                    .cacheControl(new CacheControl.Builder().noCache().build())
                    .build();


            try {


                Response response = mClient.newCall(request).execute();

                if(!response.isSuccessful()){

                    mCustomProgressListener.onError("Failed to upload with error code "+response.code(),data);
                }


                ResponseBody responseBodyCopy = response.peekBody(Long.MAX_VALUE);

                /**
                 * server response
                 */
                Log.e(TAG,responseBodyCopy.string());


            } catch (IOException e) {

                e.printStackTrace();



                mCustomProgressListener.onError(e.getMessage(),data);

            }finally {
                /**
                 *
                 */
                mCustomProgressListener.resetOverallUpload();
            }


        }



        return null;
    }







}

Below are the XML layout files:

1. activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="8dp">

    <ProgressBar
        android:id="@+id/per_file_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/file_name_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="File:" />

        <TextView
            android:id="@+id/per_file_progress_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:gravity="right"
            android:text="0/0" />

    </LinearLayout>

    <ProgressBar
        android:id="@+id/overall_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/overall_progress_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right"
            android:text="0/0" />
    </LinearLayout>

</LinearLayout>

2. image_item.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="10dp"
    android:layout_margin="4dp"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true">



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/image_view"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:srcCompat="@mipmap/ic_launcher" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="10dp">

            <TextView
                android:id="@+id/image_name_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Image Name" />

            <TextView
                android:id="@+id/status_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Status" />
        </LinearLayout>

    </LinearLayout>


</android.support.v7.widget.CardView>

2. upload_progress.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="8dp">

    <ProgressBar
        android:id="@+id/per_file_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/file_name_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="File:" />

        <TextView
            android:id="@+id/per_file_progress_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:gravity="right"
            android:text="0/0" />

    </LinearLayout>

    <ProgressBar
        android:id="@+id/overall_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/overall_progress_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right"
            android:text="0/0" />
    </LinearLayout>

</LinearLayout>


AndroidManifest.xml



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.simpleinfo.uploadfileswithphp">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Make sure to add the code below in build.gradle

implementation 'com.squareup.okhttp3:okhttp:3.9.1'


Below are PHP codes:

1. index.php


<!DOCTYPE html>
<html>
<head>
<title>Android Upload File</title>
</head>
<body>


<h1>Uploaded Images</h1>

<?php

$directory = "images_uploaded/";
$images = glob($directory . "/*.jpg");

foreach($images as $image){
    ?>
    
    <img src="<?php echo $image?>" width="200px" height="200px" alt="<?php echo $image?>">

<?php } ?>

</body>
</html>

2. upload_receiver.php


<?php

$target_dir = "images_uploaded";

if (!file_exists($target_dir)) {
    mkdir($target_dir, 0777, true);
}

$target_file = $target_dir .'/'. basename($_FILES["image"]["name"]);

if(isset($_FILES["image"])) {
    $check = getimagesize($_FILES["image"]["tmp_name"]);
    
    if($check !== false) {
       
        if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
            echo "The file ". basename( $_FILES["image"]["name"]). " has been uploaded.";
        } else {
            echo "Sorry, there was an error uploading your file.";
        }
        
        
    } else {
        
        echo "File is not an image.";
    }
}else{
    
    echo '*** Failed ***';
    
}

?>

1 comment: