PHP Curl request encapsulation

curl request module encapsulation in php

<?php
namespace App\Utils;


/**
 * http tool class
 * @author Administrator
 *
 */
class HttpUtils
{
    
    private static $_instance;
    
    private function __construct()
    {
    }
    
    public static function getInstance()
    {
        if( null == self::$_instance )
        {
            self::$_instance = new HttpUtils();
        }
        return self::$_instance;
    }
    
    /**
     * http curl request
     * @param unknown $remote
     * @param unknown $method
     * @param array $data
     * @param array $headers
     * @return string
     */
    public function curl( $remote, $method = 'GET', $data = [], $headers = [], $format = 'STRING' )
    {
       
        if( !$remote )
        {
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'msg' ] = 'ERROR: undefined request url';
            return $arrMsg;
        }
        
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $remote );
        curl_setopt( $ch, CURLOPT_HEADER, false );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 60 );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        curl_setopt( $ch, CURLOPT_USERAGENT, $this->_getAgent() );
        if( isset( $headers ) & amp; & amp; !empty( $headers ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        }
        
        switch($method)
        {
            case 'GET':
                
            break;
            case 'PUT':
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT' );
                switch($format)
                {
                    case 'STRING':
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data, '', ' & amp;' ) ); //Set the request body and submit the data package
                    break;
                    case 'JSON':
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) ); //Set the request body and submit the data package
                    break;
                }
            break;
            case 'POST':
                curl_setopt( $ch, CURLOPT_POST, 1 );
                switch($format)
                {
                    case 'STRING':
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data, '', ' & amp;' ) );
                    break;
                    case 'JSON':
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) );
                    break;
                }
            break;
            case 'DELETE':
                curl_setopt ( $ch, CURLOPT_NOSIGNAL, true );
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'DELETE' );
            break;
        }
        
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        $result = curl_exec( $ch );
        $error = curl_error( $ch );
        $curl_info = curl_getinfo( $ch );
        curl_close( $ch );
        if( isset( $error ) & amp; & amp; strlen( $error ) > 0 )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remote;
            $arrMsg[ 'msg' ] = ' Curl ERROR: curl error code is ' . $error;
            
            return $arrMsg;
        }
        
        if( 400 <= $curl_info[ 'http_code' ] )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'http_code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remote;
            $arrMsg[ 'errmsg' ] = $result;
            $arrMsg[ 'msg' ] = ' CURL ERROR: http response error ';
            
            return $arrMsg;
        }
        
        $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
        $arrMsg[ 'request' ] = $remote;
        $arrMsg[ 'data' ] = $result;
        $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];
        
        return $arrMsg;
    }
    
    
    /**
     * Is it normal to obtain remote data?
     * @param unknown $remote
     * @return string
     */
    public function curlGet( $remote, $headers = [], $proxy = false )
    {
        if( !$remote )
        {
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'msg' ] = 'ERROR: undefined request url';
            return $arrMsg;
        }
        
        $curl = curl_init();
        curl_setopt( $curl, CURLOPT_URL, $remote );
        curl_setopt( $curl, CURLOPT_HEADER, false );
        curl_setopt( $curl, CURLOPT_TIMEOUT, 75 );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false );
        
        // Configurable to randomly select USERAGENT
        $strUserAgent = $this->_getAgent();
        curl_setopt( $curl, CURLOPT_USERAGENT, $strUserAgent );
        curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
        if( !empty( $headers ) )
        {
            curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
        }
        if($proxy)
        {
            // Configure multi-agent mode, you can switch randomly or specify mode switching to use agents
            $arrAgentINfo = $this->_getProxy();
            curl_setopt( $curl, CURLOPT_HTTPPROXYTUNNEL, false );
            curl_setopt( $curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
            curl_setopt( $curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC );
            
            //Set proxy server
            curl_setopt( $curl, CURLOPT_PROXY, $arrAgentINfo[ 'server' ] );
            //Set tunnel verification information
            curl_setopt( $curl, CURLOPT_PROXYUSERPWD, "{$arrAgentINfo['user']}:{$arrAgentINfo['passwd']}");
        }
        
        $iStart = microtime( true );
        try{
            $data = curl_exec( $curl );
            $error_code = curl_errno( $curl );
            $error_info = curl_error( $curl );
            $curl_info = curl_getinfo( $curl );
            curl_close( $curl );
            $iUserSec = sprintf( '%0.2f', microtime( true ) - $iStart );
            if( isset( $error_info ) & amp; & amp; strlen( $error_info ) > 0 )
            {
                $arrMsg[ 'code' ] = 0;
                $arrMsg[ 'curl_code' ]= $error_code;
                $arrMsg[ 'request' ]= $remote;
                $arrMsg[ 'msg' ] = 'CURL ERROR: '. $error_info;
                $arrMsg[ 'time' ] = $iUserSec;
                
                return $arrMsg;
            }
            $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remote;
            $arrMsg[ 'data' ] = $data;
            $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];
            $arrMsg[ 'time' ] = $iUserSec;
            
        }catch ( \Exception $e ){
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remote;
            $arrMsg[ 'msg' ] = 'CURL ERROR: '. $e->getMessage();
            $arrMsg[ 'time' ] = $iUserSec;
        }
        
        return $arrMsg;
    }
    
    
    /**
     * Simulate post submission
     * @param unknown $remoteUrl
     * @param unknown $data
     * @return boolean|string
     */
    public function curlPost( $remoteUrl, $data, $headers = [], $format = 'STRING' )
    {
        if( !$remoteUrl || !$data || empty( $data ) )
        {
            return false;
        }
        
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $remoteUrl );
        curl_setopt( $ch, CURLOPT_POST, true );
        switch($format)
        {
            case 'STRING':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data, '', ' & amp;' ) );
            break;
            case 'JSON':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, \GuzzleHttp\json_encode( $data ) );
            break;
        }
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 20 );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 180 );
        if( !empty( $headers ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        }
        curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        $result = curl_exec( $ch );
        $error = curl_error( $ch );
        $curl_info = curl_getinfo( $ch );
        curl_close( $ch );
        
        if( isset( $error ) & amp; & amp; strlen( $error ) > 0 )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'msg' ] = ' Curl ERROR: curl error code is ' . $error;
            
            return $arrMsg;
        }
        
        if( 200 != $curl_info[ 'http_code' ] )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'http_code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'data' ] = $result;
            $arrMsg[ 'msg' ] = ' CURL ERROR: http response error ';
            
            return $arrMsg;
        }
        
        $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
        $arrMsg[ 'request' ] = $remoteUrl;
        $arrMsg[ 'data' ] = $result;
        $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];
        
        return $arrMsg;
    }
    
    
    /**
     * Simulate post submission
     * @param unknown $remoteUrl
     * @param unknown $data
     * @return boolean|string
     */
    public function curlPut( $remoteUrl, $data, $headers = [], $format = 'STRING' )
    {
        if( !$remoteUrl || !$data || empty( $data ) )
        {
            return false;
        }
        
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $remoteUrl );
        curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT' );
        switch($format)
        {
            case 'STRING':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data, '', ' & amp;' ) );
                break;
            case 'JSON':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, \GuzzleHttp\json_encode( $data ) );
                break;
        }
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 0 );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 180 );
        curl_setopt( $ch, CURLOPT_USERAGENT, $this->_getAgent() );
        if( !empty( $headers ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        }
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        $result = curl_exec( $ch );
        $error = curl_error( $ch );
        $curl_info = curl_getinfo( $ch );
        curl_close( $ch );
        
        if( isset( $error ) & amp; & amp; strlen( $error ) > 0 )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'msg' ] = ' Curl ERROR: curl error code is ' . $error;
            
            return $arrMsg;
        }
        
        if( 200 != $curl_info[ 'http_code' ] )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'http_code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'data' ] = $result;
            $arrMsg[ 'msg' ] = ' CURL ERROR: http response error ';
            
            return $arrMsg;
        }
        
        $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
        $arrMsg[ 'request' ] = $remoteUrl;
        $arrMsg[ 'data' ] = $result;
        $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];
        
        return $arrMsg;
    }
    
    
    
    /**
     * Simulate post submission
     * @param unknown $remoteUrl
     * @param unknown $data
     * @return boolean|string
     */
    public function curlDelete( $remoteUrl, $headers = [] )
    {
        if( !$remoteUrl )
        {
            return false;
        }
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $remoteUrl );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 60 );
        curl_setopt( $ch, CURLOPT_USERAGENT, $this->_getAgent() );
        if( !empty( $headers ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        }
        curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'DELETE' );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        $result = curl_exec( $ch );
        $error = curl_error( $ch );
        $curl_info = curl_getinfo( $ch );
        curl_close( $ch );
        
        if( isset( $error ) & amp; & amp; strlen( $error ) > 0 )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'msg' ] = ' Curl ERROR: curl error code is ' . $error;
            
            return $arrMsg;
        }
        if( 200 <= $curl_info[ 'http_code' ] & amp; & amp; 400 > $curl_info[ 'http_code' ])
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'http_code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'msg' ] = ' CURL ERROR: http response error ';
            
            return $arrMsg;
        }
        
        $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
        $arrMsg[ 'request' ] = $remoteUrl;
        $arrMsg[ 'data' ] = $result;
        $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];
        
        return $arrMsg;
    }
    
    
    
    /**
    * Randomly obtain agent information
    * @return unknown[]
    */
    private function _getProxy()
    {
        $arrRet = array();
        
        $arrCacheProxy = config( 'agents.proxys' );
        $proxy = array_shift( $arrCacheProxy );
        
        $arrRet[ 'name' ] = $proxy[ 'name' ];
        $arrRet[ 'server' ] = $proxy[ 'proxy' ] . ':' . $proxy[ 'port' ];
        if( isset( $proxy[ 'user' ] ) & amp; & amp; $proxy[ 'user' ] )
        {
            $arrRet[ 'user' ] = $proxy[ 'user' ];
        }
        
        if( isset( $proxy[ 'passwd' ] ) & amp; & amp; $proxy[ 'passwd' ] )
        {
            $arrRet[ 'passwd' ] = $proxy[ 'passwd' ];
        }
        
        return $arrRet;
    }
    
    
    /**
     * Randomly obtain user-agent
     */
    private function _getAgent()
    {
        $agent = config( 'agents.agents' );
        $iGNum = count( $agent );
        $iCurrent = rand( 0, intval( $iGNum - 1 ) );
        
        return $agent[$iCurrent];
        
    }


    /**
     * Simulate post submission
     * @param unknown $remoteUrl
     * @param unknown $data
     * @return boolean|string
     */
    public function curlPostWithCookie( $remoteUrl, $data,$cookie, $headers = [], $format = 'STRING' )
    {
        if( !$remoteUrl || !$data || empty( $data ) )
        {
            return false;
        }

        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $remoteUrl );
        curl_setopt( $ch, CURLOPT_POST, true );
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //Set Cookie information to be saved in the specified file
        switch($format)
        {
            case 'STRING':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data, '', ' & amp;' ) );
                break;
            case 'JSON':
                curl_setopt( $ch, CURLOPT_POSTFIELDS, \GuzzleHttp\json_encode( $data ) );
                break;
        }
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 0 );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 240 );
        if( !empty( $headers ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        }
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        $result = curl_exec( $ch );
        $error = curl_error( $ch );
        $curl_info = curl_getinfo( $ch );
        curl_close( $ch );

        if( isset( $error ) & amp; & amp; strlen( $error ) > 0 )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'msg' ] = ' Curl ERROR: curl error code is ' . $error;

            return $arrMsg;
        }

        if( 200 != $curl_info[ 'http_code' ] )
        {
            //abnormal
            $arrMsg[ 'code' ] = 0;
            $arrMsg[ 'http_code' ] = $curl_info[ 'http_code' ];
            $arrMsg[ 'request' ] = $remoteUrl;
            $arrMsg[ 'data' ] = $result;
            $arrMsg[ 'msg' ] = ' CURL ERROR: http response error ';

            return $arrMsg;
        }

        $arrMsg[ 'code' ] = $curl_info[ 'http_code' ];
        $arrMsg[ 'request' ] = $remoteUrl;
        $arrMsg[ 'data' ] = $result;
        $arrMsg[ 'msg' ] = 'REMOTE: http code ' . $curl_info[ 'http_code' ];

        return $arrMsg;
    }
    
    
    
    /**
     * Get link details
     * @author Administrator
     * @datetime May 7, 2019 5:39:16 pm
     *@comment
     *
     * @param unknown $url
     * @return array|string[]|unknown[]|mixed[]
     */
    public function curlGetHeader( $url )
    {
        $arrRet = array();
        if( !$url || strlen( $url ) <= 0 )
        {
            return $arrRet;
        }
        if( !starts_with( $url , [ 'http', 'https', 'Http', 'Https', 'HTTP', 'HTTPS' ] ) )
        {
            return $arrRet;
        }
        try{
            $header = get_headers( $url, TRUE );
            if ( strpos( $header[0], 302 ) || strpos( $header[0], 301 ) )
            {
                if( isset( $header[ 'Location' ] ) & amp; & amp; is_array( $header[ 'Location' ] ) & amp; & amp; !empty( $header[ 'Location' ] ) )
                {
                    $url = $header[ 'Location' ][count( $header['Location'] )-1 ];
                }
                else if( isset( $header[ 'Location' ] ) )
                {
                    $url = $header[ 'Location' ];
                }
            }
            $urlInfo = parse_url( $url );
            if( isset( $urlInfo ) & amp; & amp; !empty( $urlInfo ) )
            {
                $scheme = strtolower( $urlInfo[ 'scheme' ] );
                $arrRet[ 'scheme' ] = $scheme;
                $arrRet[ 'host' ] = strtolower( $urlInfo[ 'host' ] );
                $arrRet[ 'url' ] = $scheme . '://' . $urlInfo[ 'host' ];
            }
        }catch( \Exception $e ){
            if( preg_match( "/ssl3_get_server_certificate/i" , $e->getMessage() ) )
            {
                return $this->curlGetHeader( str_replace( 'https://' , 'http://', $url ) );
            }
        }
        
        return $arrRet;
    }
}