PHP Classes

File: FastCurlMulti.php

Recommend this page to a friend!
  Classes of Antonio López Vivar   Fast Curl   FastCurlMulti.php   Download  
File: FastCurlMulti.php
Role: Class source
Content type: text/plain
Description: FastCurlMulti
Class: Fast Curl
Send HTTP requests using Curl extension
Author: By
Last change: .
Date: 11 years ago
Size: 6,610 bytes
 

Contents

Class file image Download
<?php

/**
 * FastCurlMulti (PHP object-oriented wrapper for {@link http://curl.haxx.se/ cURL})
 *
 * Copyright (c) 2010 Antonio López Vivar
 *
 * LICENSE:
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see {@link http://www.gnu.org/licenses}.
 *
 *
 * @category Library
 * @package FastCurl
 * @author Antonio López Vivar <tonikelope@gmail.com>
 * @copyright 2010 Antonio López Vivar
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @version 1.6
 */

 
/**
 * @property mixed $_mh curl_multi handle.
 * @property array $_ch FastCurl objects locked to this container.
 * @property bool $_multiset If it's activated, you can set the same CURLOPT to all FastCurl objects making $fastmulti_handle->curlopt=value;
 * @property bool $_implicit_refresh If it's activated when a FastCurl object (locked to this container) property is set, FastCurl object will be refresh.
 */
class FastCurlMulti
{
    const
VERSION='1.6';
   
    private
$_mh=NULL;
   
    private
$_ch=NULL;
   
    private
$_multiset=NULL;
   
    private
$_implicit_refresh=NULL;
   
   
   
/**
     * @param FastCurl $chandle (It can be a single FastCurl object or an array of FastCurl objects)
     * @param bool $multiset If it's activated, you can set the same CURLOPT to all FastCurl objects making $fastmulti_handle->curlopt=value;
     * @param bool $_implicit_refresh If it's activated when a FastCurl object (locked to this container) property is set, FastCurl object will be refresh.
     * @return FastCurlMulti $this
     */
   
public function __construct($chandle=NULL, $multiset=FALSE, $implicit_refresh=TRUE)
    {
       
$this->_mh=curl_multi_init();
       
$this->_ch=array();
       
        if(
$chandle)
        {
            if(
is_array($chandle))
            {
                foreach(
$chandle as $ch)
                   
$this->add($ch);
            }
            else
               
$this->add($chandle);
        }
       
       
$this->_multiset=is_bool($multiset)?$multiset:FALSE;
       
$this->_implicit_refresh=is_bool($implicit_refresh)?$implicit_refresh:TRUE;
       
        return
$this;
    }
   
   
   
/**
     * @return bool Set ok
     */
   
public function set_multiset($value)
    {
        if((
$ret=is_bool($value)))
           
$this->_multiset=$value;
           
        return
$ret;
    }
   
   
   
/**
     * @return bool Set ok
     */
   
public function set_implicit_refresh($value)
    {
        if((
$ret=is_bool($value)))
           
$this->_implicit_refresh=$value;
           
        return
$ret;
    }
   
   
   
/**
     * @return bool
     */
   
public function is_multiset()
    {
        return
$this->_multiset;
    }
   
   
   
/**
     * @return bool
     */
   
public function is_implicit_refresh()
    {
        return
$this->_implicit_refresh;
    }
   
   
   
/**
     * Before closing curl_multi_handle, we remove any FastCurl locked object.
     */
   
public function __destruct()
    {
        foreach(
$this->_ch as $ch)
           
$this->remove($ch);
       
       
curl_multi_close($this->_mh);
    }
   
   
   
/**
     * @param FastCurl $ch
     */
   
public function add(FastCurl $ch)
    {
       
$ch->lockMulti($this);
    }

   
   
/**
     * @param FastCurl $ch
     */
   
public function remove(FastCurl $ch)
    {
       
$ch->unlockMulti($this);
    }
   
   
   
/**
     * @param FastCurl $ch
     */
   
public function refresh(FastCurl $ch)
    {
        if(
$ch->unlockMulti($this))
           
$ch->lockMulti($this);
    }
   
   
   
/**
     * Executes all curl handles parallelly (fastcookies support).
     *
     * @param bool $verbose Prints '+' while looping for all requests (useful to avoid browser's timeout (PHP output buffer must be off)).
     */
   
public function exec($verbose=FALSE)
    {
       
$ir_orig=$this->is_implicit_refresh();
       
$this->set_implicit_refresh(FALSE);
       
       
$fc_redir=array();
       
        foreach(
$this->_ch as $fc)
            if(
$fc->followlocation && (is_array($fc->get_fc_cookies()) || $fc->is_fast_followlocation()))
            {
               
$fc_redir[]=array($fc, $fc->url, $fc->referer);
               
$fc->followlocation=FALSE;
            }
       
        do
        {
           
$active=NULL;
           
$mrc=FALSE;
           
$redir=FALSE;
           
            foreach(
$fc_redir as $fc)
                if(
is_array($fc[0]->get_fc_cookies()))
                   
$fc[0]->send_fc_cookies_from_multi($this);
            do
            {
                if(
$mrc===FALSE || curl_multi_select($this->_mh)!=-1)
                {
                    while((
$mrc=curl_multi_exec($this->_mh, $active))==CURLM_CALL_MULTI_PERFORM);
                   
                    if(
$verbose)
                        echo
'+ ';
                }
               
            }while(
$active && $mrc==CURLM_OK);
           
            foreach(
$fc_redir as $fc)
            {
                if((
$res=curl_multi_getcontent($fc[0]->get_ch_from_multi($this))))
                {
                    if(
is_array($fc[0]->get_fc_cookies()))
                       
$fc[0]->receive_fc_cookies_from_multi($this, $res);

                    if(
strpos(trim($fc[0]->info('HTTP_CODE')), '3')===0)
                    {
                        if(
$verbose)
                            echo
'> ';
                       
                        if(
$fc[0]->post && $fc[0]->info('HTTP_CODE')!=307)
                           
$fc[0]->enable_post(FALSE);
                       
                       
preg_match('/(?:(?:Location)|(Refresh))\: *?(?(1)\d+; *?url\=)(?P<redir>[^\r\n]+)/i', $res, $url);
                       
                        if(
preg_match('/^(?!.*?\:\/\/)/', ($url['redir']=trim($url['redir']))))
                           
$url['redir']=preg_replace('/(?<!\:\/)\/[^\/]+$/','',$fc[0]->url).'/'.ltrim($url['redir'], '/');
                           
                        if(
$fc[0]->autoreferer)
                           
$fc[0]->referer=$fc[0]->url;
                       
                       
$fc[0]->url=$url['redir'];
                       
                       
$this->refresh($fc[0]);
                       
                       
$redir=TRUE;
                    }
                }
            }
           
        }while(
$redir);
       
        foreach(
$fc_redir as $fc)
        {
           
$fc[0]->set_last_url_from_multi($this, $fc[0]->url);
           
$fc[0]->url=$fc[1];
           
$fc[0]->referer=$fc[2];
           
$fc[0]->followlocation=TRUE;
        }
       
       
$this->set_implicit_refresh($ir_orig);
    }
   
   
   
/**
     * @param FastCurl $ch
     */
   
public function accept(FastCurl $ch)
    {
       
$this->_ch[] = $ch;
       
curl_multi_add_handle($this->_mh, $ch->get_ch_from_multi($this));
    }
   
   
   
/**
     * @param FastCurl $ch
     */
   
public function release(FastCurl $ch)
    {
        if((
$key=array_search($ch, $this->_ch, TRUE))!==FALSE)
        {
           
curl_multi_remove_handle($this->_mh, $ch->get_ch_from_multi($this));
            unset(
$this->_ch[$key]);
        }
    }
   
   
   
/**
     * Sets a CURLOPT for every FastCurl object in the container (if _multiset is ON)
     *
     * @param string $opt
     * @param mixed $value
     * @return bool CURLOPT set ok
     */
   
public function __set($opt, $value)
    {
        if((
$ret=($this->is_multiset() && defined('CURLOPT_'.strtoupper($opt)))))
        {
            foreach(
$this->_ch as $ch)
               
$ch->$opt=$value;
        }
       
        return
$ret;
    }
}

/* ?> */