PHP Classes

File: public/server/copy-file.php

Recommend this page to a friend!
  Classes of Joseluis Laso   Asynchronous Long Server Tasks   public/server/copy-file.php   Download  
File: public/server/copy-file.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Asynchronous Long Server Tasks
Start background tasks and query progress status
Author: By
Last change: changing external CURL to native fsckopen
Date: 8 years ago
Size: 2,377 bytes
 

Contents

Class file image Download
<?php

set_time_limit
(0);
ignore_user_abort(true);

// this file wants to simulate a real large process that have to be executed in background

require_once __DIR__.'/../../vendor/autoload.php';

use
JLaso\ToolsLib\Json;
use
JLaso\ToolsLib\Status;

$id = isset($_POST['id']) ? $_POST['id'] : null;
$fileName = isset($_POST['name']) ? $_POST['name'] : "";
$fileSize = isset($_POST['size']) ? $_POST['size'] : "";

if ((
null === $id) || !$fileName || !$fileSize) {

   
Json::error("you have to send 'id','name' and 'size' to start processing");
    exit();

}

$status = new Status($_POST["_task"]);

// if the status file exists means that another instance of this task is working
if ($status->existsStatusFile()) {
   
Json::ok(array('id'=>$id, 'status'=>Status::QUEUED));
    exit();
}

$status->touchStatusFile();

// the next lines terminates the output buffer and let believe the requester that the program had finished
ob_start();
Json::ok();
header("Content-Length: ".ob_get_length());
header('Connection: close');
ob_end_flush();
flush();
session_write_close();

// wait a little before the huge work
sleep(1);

// this is some kind of magic, in order to copy the status file if something wrong happens
function master_shutdown()
{
    global
$status;
   
$status->hangOn();
}
register_shutdown_function('master_shutdown');

$tasks = array();

do {
   
// get the first task in the queue
   
if (!$id){
        foreach(
$tasks as $key=>$task){
           
$id = $key;
            break;
        }
    }

    if (
$status->getInfo($id) != Status::DONE) {

       
$status->updateStatus($id, Status::PROCESSING);
       
process($status, $id, $fileName, $fileSize);
       
$status->updateStatus($id, Status::DONE);

    }

   
// continue while existing pending tasks
   
$id = null;
   
$tasks = $status->getNotDoneTasks();

} while(
count($tasks));

sleep(2); // give time to frontend to recover updated status

// frees status file indicating that this process has been terminated
$status->freeStatusFile();


function
process(Status $status, $id, $name, $size)
{
   
$factor = intval($size/100);
    for(
$i=0;$i<=$size;$i+=$factor){
       
usleep(100000); // simulate that is copying a piece of the file
       
$status->updateStatus($id, Status::PROCESSING.":".intval($i/$factor));
    }
   
sleep(1);
   
$status->updateStatus($id, Status::DONE);
   
sleep(2);
}