You are here

Multitasking PHP with curl

As you may already experienced, PHP is not very powerful if We are talking in terms of multitasking. I reckon being a PHP programmer you would have spent hours or maybe even a days to optimize your application's/websites's performance, trying to ajaxise output or somehow find a way's to split functionality into several tasks. It can be pretty tricky in PHP, since this language by default works top to bottom - executes the code in order it is written. Well, yes, using complex objects you might be able to achieve sort of something close to multi threading.

But what about something simple, lets say you need to test your project performance, easily and quickly?

This small PHP class project assumes that you've got a paged view on your website, let's say search results - 1000 items structured in 100 pages having 10 items per page. Your project is just to be launched and you boss asks you quite a rhetoric question - "Are you sure that your project is optimized to handle our enormous traffic?". Here is the deal, the easiest way would be create a http query and query all paged view multiple pages in one go!!!

My code below is inspired from this curl_multi_exec post.

<?php

/**
 * Description of multi_query_site
 *
 * @author janisjanovskis - <a href="mailto:janis.janovskis@passivemanagement.net">janis.janovskis@passivemanagement.net</a>
 *
 *  inspired from @link <a href="http://www.rustyrazorblade.com/2008/02/curl_multi_exec/
">http://www.rustyrazorblade.com/2008/02/curl_multi_exec/
</a> *  very simple class just uses curl
 */
class multi_query_site {
   
//some setup and runtime variables
   
private $baseHurl = '<a href="http://yoursite.com/path-to-view-query/output?page=';
">http://yoursite.com/path-to-view-query/output?page=';
</a>    private
$pages = 200;
    /** @var
$curl_array */
    private
$curl_array = array();
    /** @var
$master */
    private
$master;

    public function __costruct(

$baseHurl, $pages) {
      //First lets check if it actually works - do We have curl installed 
      if(!function_exists('curl_init')){
            print "
No Curl available\n";
            unset(
$this);
            die();
        }
       
$this->baseHurl = $baseHurl;
       
$this->pages = $pages;
    }
   
    /**
     * @function initilze_threads()
     */
   
    public function initilze_threads() {
       
$this->master = curl_multi_init();
        /**
         * building up a conection array
         */
        for(
$i = 1; $i <= $this->pages; $i++){
           
$url = $this->baseHurl.$i;
           
$this->curl_array[$i] = curl_init($url);
            curl_setopt(
$this->curl_array[$i], CURLOPT_RETURNTRANSFER, true);
            // Here comes in curl_multi
            curl_multi_add_handle(
$this->master, $this->curl_array[$i]);
        }
       
$runnig = null;
        do{
            curl_multi_exec(
$this->master, $runnig);
        }while (
$runnig > 0);
    }
    // and some output functionality
    public function output_results() {
        print "
Sort of results\t\n";
        for(
$i = 1; $i <= $this->pages; $i++){
           
$result = substr(curl_multi_getcontent($this->curl_array[$i]), 0, 10);
            print "
[\t$i]\tResult\t$result\n[End\t$i\t]\n";
        }
        print "
Done\n";
        //This is just for curiosity
        print round((memory_get_peak_usage(TRUE))/1024/1024, 2)."
MB\n";
       
    }

    /**
     * @method _destruct() kills everything regarding curl;
     */
    public function __destruct() {
       // The power of _destruct interceptor, killing all multi handles
        for(

$i = 1; $i <= $this->pages; $i++){
            curl_multi_remove_handle(
$this->master, $this->curl_array[$i]);
        };
       //and closing all connections
        curl_multi_close(
$this->master);
    }
}

?>

As you can see, I left a lots of open space for your own inspirations, like creating a sub loops for each page load and multitask them separately.
I'll leave this multitasking PHP challenge on your shoulders.

Hopefully this makes sense to you, otherwise, do not hesitate to leave your comments.