Skip to end of metadata
Go to start of metadata

Redis is a useful solution when design systems on server and required the minimum latency between the client and server for handling message. We can easily build a thread application if we use shell_exec based on & and wait. PHP also provides a solution named as pthreads. but unfortunately the pthreads extension cannot be used in a web server environment. Threading in PHP should therefore remain to CLI-based applications only. 

To know more about thread application based on the shell script, please refer http://qsok.com/display/KB/Thread+implementation+in+shell+script for more information.

To implement, thread-based redis operation, we need below two functions:

function redis_set($host,$port,$key,$value,$thread=false)
{
        $obj = [ "v" => $value ];
        $value = str_replace( "\"", "\\\"", json_encode( $obj, JSON_UNESCAPED_UNICODE));
        $cmd="redis-cli -h {$host} -p {$port} set \"{$key}\" \"{$value}\"";
        if ($thread==true) $cmd .= " &";

        $resp=trim( shell_exec( $cmd));

        if ($resp=="OK") return NULL;
        else
        {
                echo "{$resp}\n";
                return $resp;
        }
}

function redis_get($host,$port,$key)
{
        $cmd = "redis-cli -h {$host} -p {$port} get \"{$key}\"";
        $resp=trim(shell_exec( $cmd));
        $obj=json_decode($resp,JSON_UNESCAPED_UNICODE);
        return $obj['v'];
}

Once you call redis_set() in thread mode, you can wait until your process' done as following:

shell_exec( "wait");

Below is a practical example to implement Redis application comparing the normal and thread processing :

<?php

$prev_time = 0;
function tick()
{
        global $prev_time;

        $cur_time = microtime(true);

        if ($prev_time) $diff = $cur_time - $prev_time;
        else $diff = "";

        echo $cur_time . " (" . $diff . ")\n";

        $prev_time = $cur_time;
}

function redis_set($host,$port,$key,$value,$run_in_thread=false)
{
        $obj = [ "v" => $value ];
        $value = str_replace( "\"", "\\\"", json_encode( $obj, JSON_UNESCAPED_UNICODE));
        $cmd="redis-cli -h {$host} -p {$port} set \"{$key}\" \"{$value}\"";
        if ($run_in_thread==true) $cmd .= " &";

        $resp=trim( shell_exec( $cmd));

        if ($resp=="OK") return NULL;
        else
        {
                echo "{$resp}\n";
                return $resp;
        }
}

function redis_get($host,$port,$key)
{
        $cmd = "redis-cli -h {$host} -p {$port} get \"{$key}\"";
        $resp=trim(shell_exec( $cmd));
        $obj=json_decode($resp,JSON_UNESCAPED_UNICODE);
        return $obj['v'];
}

echo "Error testing\n";
echo redis_set( "10.0.1.10", 6379, "chun", "kang1");
echo redis_get( "10.0.1.10", 6379, "chun"). "\n";

echo "Test Redis call in Normal mode!!\n";
$prev_time = 0;
tick();
redis_set( "10.0.1.11", 6379, "chun", "kang1");
redis_set( "10.0.1.12", 6379, "chun", "kang2");
redis_set( "10.0.1.13", 6379, "chun", "kang3");
tick();
echo redis_get( "10.0.1.11", 6379, "chun"). "\n";
echo redis_get( "10.0.1.12", 6379, "chun"). "\n";
echo redis_get( "10.0.1.13", 6379, "chun"). "\n";
tick();

echo "\n";
echo "Test same things in Thread mode\n";

$prev_time = 0;
tick();
redis_set( "10.0.1.11", 6379, "chun", "thread-kang1", true);
redis_set( "10.0.1.12", 6379, "chun", "thread-kang2", true);
redis_set( "10.0.1.13", 6379, "chun", "thread-kang3", true);
tick();

shell_exec("wait"); // wait until all workers to complete the job

echo redis_get( "10.0.1.11", 6379, "chun"). "\n";
echo redis_get( "10.0.1.12", 6379, "chun"). "\n";
echo redis_get( "10.0.1.13", 6379, "chun"). "\n";
tick();

?>

And below is the result of above code:

Error testing
Could not connect to Redis at 10.0.1.10:6379: No route to host

Could not connect to Redis at 10.0.1.10:6379: No route to host

Test Redis call in Normal mode!!
1622086912.1606 ()
1622086912.1754 (0.014813184738159)
kang1
kang2
kang3
1622086912.1895 (0.014098882675171)

Test same things in Thread mode
1622086912.1895 ()
1622086912.2041 (0.014595985412598)
thread-kang1
thread-kang2
thread-kang3
1622086912.2201 (0.015931129455566)

The benefit of above example is to enhance its processing performance, so you can do more for your purpose.