代码初始化
This commit is contained in:
142
addons/epay/library/v2/Yansongda/Supports/Traits/Accessable.php
Normal file
142
addons/epay/library/v2/Yansongda/Supports/Traits/Accessable.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Supports\Traits;
|
||||
|
||||
trait Accessable
|
||||
{
|
||||
/**
|
||||
* __get.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* __set.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set(string $key, $value)
|
||||
{
|
||||
return $this->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* get.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(?string $key = null, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return method_exists($this, 'toArray') ? $this->toArray() : $default;
|
||||
}
|
||||
|
||||
$method = 'get';
|
||||
foreach (explode('_', $key) as $item) {
|
||||
$method .= ucfirst($item);
|
||||
}
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}();
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* set.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set(string $key, $value)
|
||||
{
|
||||
$method = 'set';
|
||||
foreach (explode('_', $key) as $item) {
|
||||
$method .= ucfirst($item);
|
||||
}
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a offset exists.
|
||||
*
|
||||
* @see https://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
*
|
||||
* @param mixed $offset an offset to check for
|
||||
*
|
||||
* @return bool true on success or false on failure.
|
||||
*
|
||||
* The return value will be casted to boolean if non-boolean was returned.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return !is_null($this->get($offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to retrieve.
|
||||
*
|
||||
* @see https://php.net/manual/en/arrayaccess.offsetget.php
|
||||
*
|
||||
* @param mixed $offset the offset to retrieve
|
||||
*
|
||||
* @return mixed can return all value types
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set.
|
||||
*
|
||||
* @see https://php.net/manual/en/arrayaccess.offsetset.php
|
||||
*
|
||||
* @param mixed $offset the offset to assign the value to
|
||||
* @param mixed $value the value to set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset.
|
||||
*
|
||||
* @see https://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
*
|
||||
* @param mixed $offset the offset to unset
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Supports\Traits;
|
||||
|
||||
use ReflectionClass;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
trait Arrayable
|
||||
{
|
||||
/**
|
||||
* toArray.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ((new ReflectionClass($this))->getProperties() as $item) {
|
||||
$k = $item->getName();
|
||||
$method = 'get'.Str::studly($k);
|
||||
|
||||
$result[Str::snake($k)] = method_exists($this, $method) ? $this->{$method}() : $this->{$k};
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace Yansongda\Supports\Traits;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Trait HasHttpRequest.
|
||||
*
|
||||
* @property string $baseUri
|
||||
* @property float $timeout
|
||||
* @property float $connectTimeout
|
||||
*/
|
||||
trait HasHttpRequest
|
||||
{
|
||||
/**
|
||||
* Http client.
|
||||
*
|
||||
* @var Client|null
|
||||
*/
|
||||
protected $httpClient = null;
|
||||
|
||||
/**
|
||||
* Http client options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $httpOptions = [];
|
||||
|
||||
/**
|
||||
* Send a GET request.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function get(string $endpoint, array $query = [], array $headers = [])
|
||||
{
|
||||
return $this->request('get', $endpoint, [
|
||||
'headers' => $headers,
|
||||
'query' => $query,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a POST request.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param string|array $data
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function post(string $endpoint, $data, array $options = [])
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
$options['body'] = $data;
|
||||
} else {
|
||||
$options['form_params'] = $data;
|
||||
}
|
||||
|
||||
return $this->request('post', $endpoint, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function request(string $method, string $endpoint, array $options = [])
|
||||
{
|
||||
return $this->unwrapResponse($this->getHttpClient()->{$method}($endpoint, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set http client.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHttpClient(Client $client): self
|
||||
{
|
||||
$this->httpClient = $client;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return http client.
|
||||
*/
|
||||
public function getHttpClient(): Client
|
||||
{
|
||||
if (is_null($this->httpClient)) {
|
||||
$this->httpClient = $this->getDefaultHttpClient();
|
||||
}
|
||||
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default http client.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*/
|
||||
public function getDefaultHttpClient(): Client
|
||||
{
|
||||
return new Client($this->getOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* setBaseUri.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseUri(string $url): self
|
||||
{
|
||||
if (property_exists($this, 'baseUri')) {
|
||||
$parsedUrl = parse_url($url);
|
||||
|
||||
$this->baseUri = ($parsedUrl['scheme'] ?? 'http').'://'.
|
||||
$parsedUrl['host'].(isset($parsedUrl['port']) ? (':'.$parsedUrl['port']) : '');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* getBaseUri.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*/
|
||||
public function getBaseUri(): string
|
||||
{
|
||||
return property_exists($this, 'baseUri') ? $this->baseUri : '';
|
||||
}
|
||||
|
||||
public function getTimeout(): float
|
||||
{
|
||||
return property_exists($this, 'timeout') ? $this->timeout : 5.0;
|
||||
}
|
||||
|
||||
public function setTimeout(float $timeout): self
|
||||
{
|
||||
if (property_exists($this, 'timeout')) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getConnectTimeout(): float
|
||||
{
|
||||
return property_exists($this, 'connectTimeout') ? $this->connectTimeout : 3.0;
|
||||
}
|
||||
|
||||
public function setConnectTimeout(float $connectTimeout): self
|
||||
{
|
||||
if (property_exists($this, 'connectTimeout')) {
|
||||
$this->connectTimeout = $connectTimeout;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return array_merge([
|
||||
'base_uri' => $this->getBaseUri(),
|
||||
'timeout' => $this->getTimeout(),
|
||||
'connect_timeout' => $this->getConnectTimeout(),
|
||||
], $this->getHttpOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* setOptions.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOptions(array $options): self
|
||||
{
|
||||
return $this->setHttpOptions($options);
|
||||
}
|
||||
|
||||
public function getHttpOptions(): array
|
||||
{
|
||||
return $this->httpOptions;
|
||||
}
|
||||
|
||||
public function setHttpOptions(array $httpOptions): self
|
||||
{
|
||||
$this->httpOptions = $httpOptions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert response.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function unwrapResponse(ResponseInterface $response)
|
||||
{
|
||||
$contentType = $response->getHeaderLine('Content-Type');
|
||||
$contents = $response->getBody()->getContents();
|
||||
|
||||
if (false !== stripos($contentType, 'json') || stripos($contentType, 'javascript')) {
|
||||
return json_decode($contents, true);
|
||||
} elseif (false !== stripos($contentType, 'xml')) {
|
||||
return json_decode(json_encode(simplexml_load_string($contents, 'SimpleXMLElement', LIBXML_NOCDATA), JSON_UNESCAPED_UNICODE), true);
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Supports\Traits;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
trait Serializable
|
||||
{
|
||||
/**
|
||||
* toJson.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson()
|
||||
{
|
||||
return $this->serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON.
|
||||
*
|
||||
* @see https://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
*
|
||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||
* which is a value of any type other than a resource
|
||||
*
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
if (method_exists($this, 'toArray')) {
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation of object.
|
||||
*
|
||||
* @see https://php.net/manual/en/serializable.serialize.php
|
||||
*
|
||||
* @return string the string representation of the object or null
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
if (method_exists($this, 'toArray')) {
|
||||
return json_encode($this->toArray());
|
||||
}
|
||||
|
||||
return json_encode([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the object.
|
||||
*
|
||||
* @see https://php.net/manual/en/serializable.unserialize.php
|
||||
*
|
||||
* @param string $serialized <p>
|
||||
* The string representation of the object.
|
||||
* </p>
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = json_decode($serialized, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new RuntimeException('Invalid Json Format');
|
||||
}
|
||||
|
||||
foreach ($data as $key => $item) {
|
||||
if (method_exists($this, 'set')) {
|
||||
$this->set($key, $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace Yansongda\Supports\Traits;
|
||||
|
||||
use Predis\Client;
|
||||
|
||||
/**
|
||||
* Trait ShouldThrottle.
|
||||
*
|
||||
* @property Client $redis
|
||||
*/
|
||||
trait ShouldThrottle
|
||||
{
|
||||
/**
|
||||
* _throttle.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_throttle = [
|
||||
'limit' => 60,
|
||||
'period' => 60,
|
||||
'count' => 0,
|
||||
'reset_time' => 0,
|
||||
];
|
||||
|
||||
/**
|
||||
* isThrottled.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $limit
|
||||
* @param int $period
|
||||
* @param bool $auto_add
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isThrottled($key, $limit = 60, $period = 60, $auto_add = false)
|
||||
{
|
||||
if (-1 === $limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$now = microtime(true) * 1000;
|
||||
|
||||
$this->redis->zremrangebyscore($key, 0, $now - $period * 1000);
|
||||
|
||||
$this->_throttle = [
|
||||
'limit' => $limit,
|
||||
'period' => $period,
|
||||
'count' => $this->getThrottleCounts($key, $period),
|
||||
'reset_time' => $this->getThrottleResetTime($key, $now),
|
||||
];
|
||||
|
||||
if ($this->_throttle['count'] < $limit) {
|
||||
if ($auto_add) {
|
||||
$this->throttleAdd($key, $period);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 限流 + 1.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $period
|
||||
*/
|
||||
public function throttleAdd($key, $period = 60)
|
||||
{
|
||||
$now = microtime(true) * 1000;
|
||||
|
||||
$this->redis->zadd($key, [$now => $now]);
|
||||
$this->redis->expire($key, $period * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* getResetTime.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param $key
|
||||
* @param $now
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getThrottleResetTime($key, $now)
|
||||
{
|
||||
$data = $this->redis->zrangebyscore(
|
||||
$key,
|
||||
$now - $this->_throttle['period'] * 1000,
|
||||
$now,
|
||||
['limit' => [0, 1]]
|
||||
);
|
||||
|
||||
if (0 === count($data)) {
|
||||
return $this->_throttle['reset_time'] = time() + $this->_throttle['period'];
|
||||
}
|
||||
|
||||
return intval($data[0] / 1000) + $this->_throttle['period'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限流相关信息.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param string|null $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getThrottleInfo($key = null, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->_throttle;
|
||||
}
|
||||
|
||||
if (isset($this->_throttle[$key])) {
|
||||
return $this->_throttle[$key];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已使用次数.
|
||||
*
|
||||
* @author yansongda <me@yansongda.cn>
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $period
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getThrottleCounts($key, $period = 60)
|
||||
{
|
||||
$now = microtime(true) * 1000;
|
||||
|
||||
return $this->redis->zcount($key, $now - $period * 1000, $now);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user