---
title: "Enabling Multi-threaded Upload via ActiveX/Java Uploader in PHP"
canonical: https://www.aurigma.com/docs/us8/enabling-multi-threaded-upload-php.htm
product: "Upload Suite 8"
---

# Enabling Multi-threaded Upload via ActiveX/Java Uploader in PHP
 
By the nature of HTTP, protocol web servers are designed to handle multiple simultaneous requests. While creating a file upload solution we can employ this feature to increase upload speed. The idea is quite simple: divide data into several pieces and upload them simultaneously, each data piece within a separate HTTP request. This trick can yield up to a 50% increase in upload speed if the channel between a client computer and a web server is fast enough. ActiveX/Java Uploader supports this approach, and this topic explains what changes are required to switch your application to multi-threaded upload.

Multi-threaded upload works only if the packages and/or chunks modes are turned on (to do this, the [FilesPerPackage](https://www.aurigma.com/docs/us8/JA_P_Aurigma_ImageUploader_UploadSettings_FilesPerPackage.htm.md) property and/or the [ChunkSize](https://www.aurigma.com/docs/us8/JA_P_Aurigma_ImageUploader_UploadSettings_ChunkSize.htm.md) property must have a positive value). In this case, the uploading files are processed in multiple pieces (by packages or chunks) rather than all at once. While uploading each file in a separate request (**FilesPerPackage** ` = 1`) is the simplest way to start with multi-threaded upload, we recommend you to read the [Sending All Files at Once or in Several Parts in ActiveX/Java Uploader](https://www.aurigma.com/docs/us8/sending-all-files-at-once-or-in-several-parts.htm.md) topic. Also the [Upload Modes Best Practices](https://www.aurigma.com/docs/us8/upload-modes-best-practices.htm.md) topic can help you to find the most appropriate configuration.

Even though ActiveX/Java Uploader supports up to 10 simultaneous threads, in real world use we have found that the optimal number of connections to use is 3-4. Uploading files in a larger number of simultaneous requests can stress your server too much which will result in the elimination of the desired positive effect.

The [Saving Uploaded Files in ActiveX/Java Uploader PHP](https://www.aurigma.com/docs/us8/saving-uploaded-files-in-php-iu.htm.md) topic explains how to process uploaded files and outlines three approaches for handling files on the server side. Here we will examine each approach and suggest changes required to work in the multi-threaded mode:

- processing uploaded data automatically
- processing uploaded data using UploadHandler class
- processing uploaded data using POST fields data

## Processing Uploaded Data Automatically
 
ActiveX/Java Uploader provides the [UploadHandler](https://www.aurigma.com/docs/us8/JA_T_P_UploadHandler.htm.md) class to process the uploaded data. This class allows the saving of uploaded data automatically to the specified folder. To enable the multi-threaded upload along with the autosave mode, you do not need to change your server code. Just set the [MaxConnectionCount](https://www.aurigma.com/docs/us8/JA_P_P_UploadSettings_MaxConnectionCount.htm.md) property to a positive value (specifying a number of simultaneous connections). Make sure that you enable multiple packages and/or chunk upload as we discussed above.
 
The snippet below configures an [Uploader](https://www.aurigma.com/docs/us8/JA_T_P_Uploader.htm.md) object to send files in up to 4 simultaneous threads and to place each file in a separate package:
 ```
<?php
    require_once "ImageUploaderPHP/Uploader.class.php";
    
    $uploader->getUploadSettings()->setActionUrl("upload.php");
    $uploader->getUploadSettings()->setMaxConnectionCount(4);
    $uploader->getUploadSettings()->setFilesPerPackage(1);
?>
``` 
In the previous snippet [ActionUrl](https://www.aurigma.com/docs/us8/JA_P_P_UploadSettings_ActionUrl.htm.md) specifies the upload script (`upload.php`). Here is the code for `upload.php`, which saves received data to the `/Catalog` folder:
 ```
<?php
    require_once "ImageUploaderPHP/UploadHandler.class.php";

    $uploadHandler = new UploadHandler();
    $uploadHandler->saveFiles("Catalog/");
?>
```

## Processing Uploaded Data Using UploadHandler Class
 
The **UploadHandler** class is a server-side component which gives you flexible access to all data uploaded from client computers (for more information see the [Saving Uploaded Files in ActiveX/Java Uploader PHP](https://www.aurigma.com/docs/us8/saving-uploaded-files-in-php-iu.htm.md) topic). This component exposes the [FileUploadedCallback](https://www.aurigma.com/docs/us8/JA_P_P_UploadHandler_FileUploadedCallback.htm.md) and [AllFilesUploadedCallback](https://www.aurigma.com/docs/us8/JA_P_P_UploadHandler_AllFilesUploadedCallback.htm.md) properties allowing you to set callback functions for handling uploaded data.
 
The **AllFilesUploadedCallback** function is called when the whole upload session is completed, i.e. while the upload process is in progress the server collects all data sent in single or multiple threads and then returns a collection of uploaded files and metadata to the function. Thus, if you use the **AllFilesUploadedCallback** property, you can enable multi-threaded upload by setting the **MaxConnectionCount** property to a positive value. Also, do not forget to enable multiple packages and/or chunk upload as we discussed at the beginning of this topic.
 
The **FileUploadedCallback** function is called each time a file is successfully uploaded. If you set up ActiveX/Java Uploader to transfer files in the multi-threaded mode, it can turn out that multiple requests arrive to the server and call the function at the same moment. So, if you use the **FileUploadedCallback** property and want to enable multi-threaded upload in your application, it is not enough just to change the value of the **MaxConnectionCount** property. You must review the code of the **FileUploadedCallback** function and rewrite thread-unsafe segments.
 
Here you can see several examples of thread-unsafe code:
 
- changing a resource that is not supposed to be changed concurrently (e.g. if you write to a file)
- using thread-unsafe collections
- using thread-unsafe libraries

For example, if the **FileUploadedCallback** function writes data to a file, there can be multiple concurrent calls causing simultaneous file writing. To resolve this issue add synchronization to the file accessing code. The following snippet demonstrates how to do this:
 ```
<?php
function saveUploadedFile($uploadedFile) 
{
    $lock = fopen("lock.txt","a");

    //Lock resource.
    if(flock($lock, LOCK_EX)) 
    {
        $absGalleryPath = realpath("Gallery/");

        //Create or load XML file which will keep information about files.
        $descriptions = new DOMDocument('1.0');
        if (file_exists($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml"))
            $descriptions->load($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml");
        else
            $descriptions->appendChild($descriptions->createElement("files"));
    
        //Save file info.
        $xmlFile = $descriptions->createElement("file");
        $xmlFile->setAttribute("name", rawurlencode($uploadedFile->getSourceName()));
        $xmlFile->setAttribute("width", $uploadedFile->getSourceWidth());
        $xmlFile->setAttribute("height", $uploadedFile->getSourceHeight());
        $xmlFile->setAttribute("description", $uploadedFile->getDescription());
        $descriptions->documentElement->appendChild($xmlFile);
        $descriptions->save($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml");

        flock($lock, LOCK_UN);
        fclose($lock);
    }
}
?>
```

## Processing Uploaded Data Using POST Fields Data
 
This approach requires you to write code for parsing HTTP POST fields. All data sent by ActiveX/Java Uploader is stored in the **$\_POST** predefined variable. To simplify accessing the POST request fields ActiveX/Java Uploader PHP classes provide [PostFields](https://www.aurigma.com/docs/us8/JA_T_P_PostFields.htm.md) (for more information see the [Saving Uploaded Files in ActiveX/Java Uploader PHP](https://www.aurigma.com/docs/us8/saving-uploaded-files-in-php-iu.htm.md) and [POST Field Reference](https://www.aurigma.com/docs/us8/post-field-reference-iu.htm.md) topics).
 
Like in the previous approach, we should take steps to avoid simultaneous requests which can cause problems in case of thread-unsafe code. So, to enable multi-threaded upload for this approach, you should perform the following steps:
 
- Specify the **MaxConnectionCount** property to define the number of simultaneous connections.
- Make sure that you enable package upload as we discussed before. As this approach does not restore files from chunks automatically, we do not recommend using the chunk upload mode, as you would be required to write code for handling chunks.
- Review the code for parsing HTTP POST fields and rewrite thread-unsafe segments. You can see examples of thread-unsafe code in the previous example.

The following snippet contains thread-safe code that saves information about uploaded files to an XML file:
 ```
<?php
    require_once "ImageUploaderPHP/PostFields.class.php";

    // Check if it is POST request;
    // we should not try to save files in HEAD requests.
    if ($_SERVER['REQUEST_METHOD'] != 'POST') 
        exit();
    
    $lock = fopen("lock.txt","a");

    //Lock resource.
    if(flock($lock, LOCK_EX)) 
    {
        $absGalleryPath = realpath("Gallery");

        //Create or load XML file which will keep information about files (image dimensions, description, etc).
        $descriptions = new DOMDocument('1.0');
        if (file_exists($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml"))
            $descriptions->load($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml");
        else
            $descriptions->appendChild($descriptions->createElement("files"));

        //Iterate through uploaded data and save the original file, thumbnail, and description.
        for ($i = 0; $i < $_POST[PostFields::packageFileCount]; $i++) 
        {
            //Save file info.
            $xmlFile = $descriptions->createElement("file");
            $xmlFile->setAttribute("name", rawurlencode($_POST[sprintf(PostFields::sourceName,$i)]));
            $xmlFile->setAttribute("width", $_POST[sprintf(PostFields::sourceWidth, $i)]);
            $xmlFile->setAttribute("height", $_POST[sprintf(PostFields::sourceHeight, $i)]);
            $xmlFile->setAttribute("description", $_POST[sprintf(PostFields::description, $i)]);
            $descriptions->documentElement->appendChild($xmlFile);
        }
        $descriptions->save($absGalleryPath . DIRECTORY_SEPARATOR . "Descriptions.xml");
    
        flock($lock, LOCK_UN);
        fclose($lock);
    }
?>
```

## See Also
 
### Reference
 
- [MaxConnectionCount Property](https://www.aurigma.com/docs/us8/JA_P_P_UploadSettings_MaxConnectionCount.htm.md)
- [FilesPerPackage Property](https://www.aurigma.com/docs/us8/JA_P_P_UploadSettings_FilesPerPackage.htm.md)
- [ChunkSize Property](https://www.aurigma.com/docs/us8/JA_P_P_UploadSettings_ChunkSize.htm.md)
- [UploadHandler.FileUploadedCallback Property](https://www.aurigma.com/docs/us8/JA_P_P_UploadHandler_FileUploadedCallback.htm.md)
- [UploadHandler.AllFilesUploadedCallback Property](https://www.aurigma.com/docs/us8/JA_P_P_UploadHandler_AllFilesUploadedCallback.htm.md)
- [PostFields Class](https://www.aurigma.com/docs/us8/JA_T_P_PostFields.htm.md)

### Manual
 
- [Quick Start with ActiveX/Java Uploader PHP](https://www.aurigma.com/docs/us8/quick-start-with-image-uploader-php.htm.md)
- [Saving Uploaded Files in ActiveX/Java Uploader PHP](https://www.aurigma.com/docs/us8/saving-uploaded-files-in-php-iu.htm.md)
- [Sending All Files at Once or in Several Parts in ActiveX/Java Uploader](https://www.aurigma.com/docs/us8/sending-all-files-at-once-or-in-several-parts.htm.md)
- [POST Field Reference](https://www.aurigma.com/docs/us8/post-field-reference-iu.htm.md)
