Environment :

1、PHP 7.1

2、Lumen 5.5

 

Process :

1、Lumen 自动加载 bootstrap/app.php ,服务容器初始化,将服务提供器注册到服务容器。

$app->register(Ixudra\Curl\CurlServiceProvider::class);

 

2、将这个 Ixudra\Curl 添加到静态调用。

<?php namespace Ixudra\Curl\Facades;


use Illuminate\Support\Facades\Facade;


class Curl extends Facade {

/**

* @return string

*/

protected static function getFacadeAccessor()

{

return 'Curl';

}

}

 

3、在每次使用 Ixudra\Curl ,即实例化一个单例。这里采用单例模式,确保只返回同一个实例。

/**

* @return void

*/

public function register()

{

$this->app->singleton('Curl', function () {

return new CurlService();

}

);

}

 

4、通过链式构造器,在每一次链式方法调用中,返回同一个对象引用,这样传递对象实例,逐步实现整个业务的查询构造。

/**

* Set the URL to which the request is to be sent

*

* @param $url string The URL to which the request is to be sent

* @return Builder

*/

public function to($url)

{

return $this->withCurlOption( 'URL', $url );

}


/**

* Set any specific cURL option

*

* @param string $key The name of the cURL option

* @param string $value The value to which the option is to be set

* @return Builder

*/

protected function withCurlOption($key, $value)

{

$this->curlOptions[ $key ] = $value;


return $this;

}


/**

* Set any specific package option

*

* @param string $key The name of the cURL option

* @param string $value The value to which the option is to be set

* @return Builder

*/

protected function withPackageOption($key, $value)

{

$this->packageOptions[ $key ] = $value;


return $this;

}


/**

* Add a HTTP header to the request

*

* @param string $header The HTTP header that is to be added to the request

* @return Builder

*/

public function withHeader($header)

{

$this->curlOptions[ 'HTTPHEADER' ][] = $header;


return $this;

}

 

5、完成整个对象的查询构造后,结束对象的查询构造,调起整个对象的处理方法。获取到查询结果,就只返回查询结果,不再传递实例本身。

/**

* Send a DELETE request to a URL using the specified cURL options

*

* @return mixed

*/

public function delete()

{

$this->appendDataToURL();


return $this->withOption('CUSTOMREQUEST', 'DELETE')

->send();

}


/**

* Send the request

*

* @return mixed

*/

protected function send()

{

// Add JSON header if necessary

if( $this->packageOptions[ 'asJsonRequest' ] ) {

$this->withHeader( 'Content-Type: application/json' );

}


if( $this->packageOptions[ 'enableDebug' ] ) {

$debugFile = fopen( $this->packageOptions[ 'debugFile' ], 'w');

$this->withOption('STDERR', $debugFile);

}


// Create the request with all specified options

$this->curlObject = curl_init();

$options = $this->forgeOptions();

curl_setopt_array( $this->curlObject, $options );


// Send the request

$response = curl_exec( $this->curlObject );


$responseHeader = null;

if( $this->curlOptions[ 'HEADER' ] ) {

$headerSize = curl_getinfo( $this->curlObject, CURLINFO_HEADER_SIZE );

$responseHeader = substr( $response, 0, $headerSize );

$response = substr( $response, $headerSize );

}


// Capture additional request information if needed

$responseData = array();

if( $this->packageOptions[ 'responseObject' ] || $this->packageOptions[ 'responseArray' ] ) {

$responseData = curl_getinfo( $this->curlObject );


if( curl_errno($this->curlObject) ) {

$responseData[ 'errorMessage' ] = curl_error($this->curlObject);

}

}


curl_close( $this->curlObject );


if( $this->packageOptions[ 'saveFile' ] ) {

// Save to file if a filename was specified

$file = fopen($this->packageOptions[ 'saveFile' ], 'w');

fwrite($file, $response);

fclose($file);

} else if( $this->packageOptions[ 'asJsonResponse' ] ) {

// Decode the request if necessary

$response = json_decode($response, $this->packageOptions[ 'returnAsArray' ]);

}


if( $this->packageOptions[ 'enableDebug' ] ) {

fclose( $debugFile );

}


// Return the result

return $this->returnResponse( $response, $responseData, $responseHeader );

}


/**

* @param mixed $content Content of the request

* @param array $responseData Additional response information

* @param string $header Response header string

* @return mixed

*/

protected function returnResponse($content, array $responseData = array(), $header = null)

{

if( !$this->packageOptions[ 'responseObject' ] && !$this->packageOptions[ 'responseArray' ] ) {

return $content;

}


$object = new stdClass();

$object->content = $content;

$object->status = $responseData[ 'http_code' ];

$object->contentType = $responseData[ 'content_type' ];

if( array_key_exists('errorMessage', $responseData) ) {

$object->error = $responseData[ 'errorMessage' ];

}


if( $this->curlOptions[ 'HEADER' ] ) {

$object->headers = $this->parseHeaders( $header );

}


if( $this->packageOptions[ 'responseObject' ] ) {

return $object;

}


if( $this->packageOptions[ 'responseArray' ] ) {

return (array) $object;

}


return $content;

}

 

Conclusion:

根据OO编程思想,通过静态调用,初始化一个单例。调用其构造查询方法,逐步完成对象的构造。在这个构造过程中,每次都返回同一个对象的引用。最终呈现的效果,就是一种链式查询。而这种查询构造器的调用,在开发上,大大提高开发效率,代码也更加精简,优雅。

$response = Curl::to('http://www.foo.com/bar')
        ->withData( array( 'foz' => 'baz' ) )
        ->asJson( true )
        ->post();

 

转载本文,请注明出处、作者。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐