Commit e8fcd7a3 by 王召彬

增加v2版本

parent f190e8c9
<?php
/**
* Auto generated from CLS.proto at 2018-09-07 06:03:23
*
* cls package
*/
namespace Hdll\Services\V2\Common\ClsLogger\Cls;
/**
* Log message
*/
class Log extends \ProtobufMessage
{
/* Field index constants */
const TIME = 1;
const CONTENTS = 2;
/* @var array Field descriptors */
protected static $fields = array(
self::TIME => array(
'name' => 'time',
'required' => true,
'type' => \ProtobufMessage::PB_TYPE_INT,
),
self::CONTENTS => array(
'name' => 'contents',
'repeated' => true,
'type' => 'Log_Content'
),
);
/**
* Constructs new message container and clears its internal state
*/
public function __construct()
{
$this->reset();
}
/**
* Clears message values and sets default ones
*
* @return null
*/
public function reset()
{
$this->values[self::TIME] = null;
$this->values[self::CONTENTS] = array();
}
/**
* Returns field descriptors
*
* @return array
*/
public function fields()
{
return self::$fields;
}
/**
* Sets value of 'time' property
*
* @param integer $value Property value
*
* @return null
*/
public function setTime($value)
{
return $this->set(self::TIME, $value);
}
/**
* Returns value of 'time' property
*
* @return integer
*/
public function getTime()
{
$value = $this->get(self::TIME);
return $value === null ? (integer)$value : $value;
}
/**
* Appends value to 'contents' list
*
* @param Log_Content $value Value to append
*
* @return null
*/
public function appendContents(Log_Content $value)
{
return $this->append(self::CONTENTS, $value);
}
/**
* Clears 'contents' list
*
* @return null
*/
public function clearContents()
{
return $this->clear(self::CONTENTS);
}
/**
* Returns 'contents' list
*
* @return Log_Content[]
*/
public function getContents()
{
return $this->get(self::CONTENTS);
}
/**
* Returns 'contents' iterator
*
* @return \ArrayIterator
*/
public function getContentsIterator()
{
return new \ArrayIterator($this->get(self::CONTENTS));
}
/**
* Returns element from 'contents' list at given offset
*
* @param int $offset Position in list
*
* @return Log_Content
*/
public function getContentsAt($offset)
{
return $this->get(self::CONTENTS, $offset);
}
/**
* Returns count of 'contents' list
*
* @return int
*/
public function getContentsCount()
{
return $this->count(self::CONTENTS);
}
}
}
\ No newline at end of file
<?php
/**
* Auto generated from CLS.proto at 2018-09-07 06:03:23
*
* cls package
*/
namespace Hdll\Services\V2\Common\ClsLogger\Cls;
/**
* LogGroup message
*/
class LogGroup extends \ProtobufMessage
{
/* Field index constants */
const LOGS = 1;
const CONTEXTFLOW = 2;
const FILENAME = 3;
const SOURCE = 4;
/* @var array Field descriptors */
protected static $fields = array(
self::LOGS => array(
'name' => 'logs',
'repeated' => true,
'type' => 'Log'
),
self::CONTEXTFLOW => array(
'name' => 'contextFlow',
'required' => false,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
self::FILENAME => array(
'name' => 'filename',
'required' => false,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
self::SOURCE => array(
'name' => 'source',
'required' => false,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
);
/**
* Constructs new message container and clears its internal state
*/
public function __construct()
{
$this->reset();
}
/**
* Clears message values and sets default ones
*
* @return null
*/
public function reset()
{
$this->values[self::LOGS] = array();
$this->values[self::CONTEXTFLOW] = null;
$this->values[self::FILENAME] = null;
$this->values[self::SOURCE] = null;
}
/**
* Returns field descriptors
*
* @return array
*/
public function fields()
{
return self::$fields;
}
/**
* Appends value to 'logs' list
*
* @param Log $value Value to append
*
* @return null
*/
public function appendLogs(Log $value)
{
return $this->append(self::LOGS, $value);
}
/**
* Clears 'logs' list
*
* @return null
*/
public function clearLogs()
{
return $this->clear(self::LOGS);
}
/**
* Returns 'logs' list
*
* @return Log[]
*/
public function getLogs()
{
return $this->get(self::LOGS);
}
/**
* Returns 'logs' iterator
*
* @return \ArrayIterator
*/
public function getLogsIterator()
{
return new \ArrayIterator($this->get(self::LOGS));
}
/**
* Returns element from 'logs' list at given offset
*
* @param int $offset Position in list
*
* @return Log
*/
public function getLogsAt($offset)
{
return $this->get(self::LOGS, $offset);
}
/**
* Returns count of 'logs' list
*
* @return int
*/
public function getLogsCount()
{
return $this->count(self::LOGS);
}
/**
* Sets value of 'contextFlow' property
*
* @param string $value Property value
*
* @return null
*/
public function setContextFlow($value)
{
return $this->set(self::CONTEXTFLOW, $value);
}
/**
* Returns value of 'contextFlow' property
*
* @return string
*/
public function getContextFlow()
{
$value = $this->get(self::CONTEXTFLOW);
return $value === null ? (string)$value : $value;
}
/**
* Sets value of 'filename' property
*
* @param string $value Property value
*
* @return null
*/
public function setFilename($value)
{
return $this->set(self::FILENAME, $value);
}
/**
* Returns value of 'filename' property
*
* @return string
*/
public function getFilename()
{
$value = $this->get(self::FILENAME);
return $value === null ? (string)$value : $value;
}
/**
* Sets value of 'source' property
*
* @param string $value Property value
*
* @return null
*/
public function setSource($value)
{
return $this->set(self::SOURCE, $value);
}
/**
* Returns value of 'source' property
*
* @return string
*/
public function getSource()
{
$value = $this->get(self::SOURCE);
return $value === null ? (string)$value : $value;
}
}
}
\ No newline at end of file
<?php
/**
* Auto generated from CLS.proto at 2018-09-07 06:03:23
*
* cls package
*/
namespace Hdll\Services\V2\Common\ClsLogger\Cls;
/**
* LogGroupList message
*/
class LogGroupList extends \ProtobufMessage
{
/* Field index constants */
const LOGGROUPLIST = 1;
/* @var array Field descriptors */
protected static $fields = array(
self::LOGGROUPLIST => array(
'name' => 'logGroupList',
'repeated' => true,
'type' => 'LogGroup'
),
);
/**
* Constructs new message container and clears its internal state
*/
public function __construct()
{
$this->reset();
}
/**
* Clears message values and sets default ones
*
* @return null
*/
public function reset()
{
$this->values[self::LOGGROUPLIST] = array();
}
/**
* Returns field descriptors
*
* @return array
*/
public function fields()
{
return self::$fields;
}
/**
* Appends value to 'logGroupList' list
*
* @param LogGroup $value Value to append
*
* @return null
*/
public function appendLogGroupList(LogGroup $value)
{
return $this->append(self::LOGGROUPLIST, $value);
}
/**
* Clears 'logGroupList' list
*
* @return null
*/
public function clearLogGroupList()
{
return $this->clear(self::LOGGROUPLIST);
}
/**
* Returns 'logGroupList' list
*
* @return LogGroup[]
*/
public function getLogGroupList()
{
return $this->get(self::LOGGROUPLIST);
}
/**
* Returns 'logGroupList' iterator
*
* @return \ArrayIterator
*/
public function getLogGroupListIterator()
{
return new \ArrayIterator($this->get(self::LOGGROUPLIST));
}
/**
* Returns element from 'logGroupList' list at given offset
*
* @param int $offset Position in list
*
* @return LogGroup
*/
public function getLogGroupListAt($offset)
{
return $this->get(self::LOGGROUPLIST, $offset);
}
/**
* Returns count of 'logGroupList' list
*
* @return int
*/
public function getLogGroupListCount()
{
return $this->count(self::LOGGROUPLIST);
}
}
}
\ No newline at end of file
<?php
/**
* Auto generated from CLS.proto at 2018-09-07 06:03:23
*
* cls package
*/
namespace Hdll\Services\V2\Common\ClsLogger\Cls;
/**
* Content message embedded in Log message
*/
class Log_Content extends \ProtobufMessage
{
/* Field index constants */
const KEY = 1;
const VALUE = 2;
/* @var array Field descriptors */
protected static $fields = array(
self::KEY => array(
'name' => 'key',
'required' => true,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
self::VALUE => array(
'name' => 'value',
'required' => true,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
);
/**
* Constructs new message container and clears its internal state
*/
public function __construct()
{
$this->reset();
}
/**
* Clears message values and sets default ones
*
* @return null
*/
public function reset()
{
$this->values[self::KEY] = null;
$this->values[self::VALUE] = null;
}
/**
* Returns field descriptors
*
* @return array
*/
public function fields()
{
return self::$fields;
}
/**
* Sets value of 'key' property
*
* @param string $value Property value
*
* @return null
*/
public function setKey($value)
{
return $this->set(self::KEY, $value);
}
/**
* Returns value of 'key' property
*
* @return string
*/
public function getKey()
{
$value = $this->get(self::KEY);
return $value === null ? (string)$value : $value;
}
/**
* Sets value of 'value' property
*
* @param string $value Property value
*
* @return null
*/
public function setValue($value)
{
return $this->set(self::VALUE, $value);
}
/**
* Returns value of 'value' property
*
* @return string
*/
public function getValue()
{
$value = $this->get(self::VALUE);
return $value === null ? (string)$value : $value;
}
}
}
\ No newline at end of file
<?php
namespace Hdll\Services\V2\Common\ClsLogger;
use Swoft\Co;
use Swoole\Coroutine;
use GuzzleHttp\Client;
use Hdll\Services\V2\Common\ClsLogger\ClsSignature;
use Hdll\Services\V2\Common\ClsLogger\Cls\Log;
use Hdll\Services\V2\Common\ClsLogger\Cls\Log_Content;
use Hdll\Services\V2\Common\ClsLogger\Cls\LogGroup;
use Hdll\Services\V2\Common\ClsLogger\Cls\LogGroupList;
class ClsLog
{
const TOPICID_ERROR = '11b19b11-c6b3-45fc-ab1a-7a531558fb57';
const TOPICID_NOTICE = 'b84f9396-d17a-4e61-88a8-11e032755732';
public static function error($msgText, $key = ''){
$key = empty($key) ? \env('APP_NAME') : \env('APP_NAME').':'.$key;
$pbData = self::createPbData($key, $msgText);
return self::uploadToCls(self::TOPICID_ERROR, $pbData);
}
public static function notice($msgText, $key = '') {
$key = empty($key) ? \env('APP_NAME') : \env('APP_NAME').':'.$key;
$pbData = self::createPbData($key, $msgText);
return self::uploadToCls(self::TOPICID_NOTICE, $pbData);
}
private static function createPbData($key, $value)
{
$logGroupList = new LogGroupList;
$logGroup = new LogGroup;
$log = new Log;
$logContent = new Log_Content;
$logContent->setKey($key);
$logContent->setValue($value);
$log->appendContents($logContent);
$log->setTime(time());
$logGroup->appendLogs($log);
$logGroup->setSource(\env('APP_NAME'));
$logGroupList->appendLogGroupList($logGroup);
return $logGroupList->serializeToString();
}
private static function uploadToCls($topicId, $pbData) {
$authorization = ClsSignature::create();
$uri = 'http://ap-beijing.cls.myqcloud.com/structuredlog?topic_id='.$topicId;
for($n = 0;$n < 3;$n++){
$res = (new Client)->post($uri, [
'headers' => [
'Host' => 'ap-beijing.cls.myqcloud.com',
'Authorization' => $authorization,
'Content-Type' => 'application/x-protobuf',
],
'body'=>$pbData,
'timeout' => 30,
]);
if($res->getStatusCode() == 200) {
return true;
}
if (Co::id() > 0) {
Coroutine::sleep(2);
} else {
sleep(2);
}
}
$msg = '上传腾讯云日志服务失败:'.$res->getBody()->getContents();
self::writeClsErrors($msg);
return false;
}
/**
* 腾讯日志服务上传时产生错误,这种错误需要记录在本地文件
*
* @return void
*/
private static function writeClsErrors($messageText) {
$filename = 'cls_error.log';
$logFile = \alias('@runtime').'/logs/'.$filename;
if (Co::id() > 0) {
// 协程写
go(function () use ($logFile, $messageText) {
$res = Coroutine::writeFile($logFile, $messageText, FILE_APPEND);
if ($res === false) {
throw new \InvalidArgumentException("Unable to append to log file: {$logFile}");
}
});
} else {
$fp = fopen($logFile, 'a');
if ($fp === false) {
throw new \InvalidArgumentException("Unable to append to log file: {$filename}");
}
flock($fp, LOCK_EX);
fwrite($fp, $messageText);
flock($fp, LOCK_UN);
fclose($fp);
}
}
}
<?php
namespace Hdll\Services\V2\Common\ClsLogger;
class ClsSignature
{
public static function create(){
$signTime = (time()-10).';'.(time()+300);
$secretKey = 'IPL5g5PaaSAzd6NSO8gEmLxcN4pTzJSQ';
$secretId = 'AKIDseHj18kua0KTSJ4g9SadbVEnEUZVjvPj';
$sha1edHttpString = sha1("post\n/structuredlog\n\n\n");
$stringToSign = "sha1\n{$signTime}\n{$sha1edHttpString}\n";
$signKey = hash_hmac('sha1', $signTime, $secretKey);
$signature = hash_hmac('sha1', $stringToSign, $signKey);
$authorization = 'q-sign-algorithm=sha1&q-ak='.$secretId
."&q-sign-time={$signTime}&q-key-time={$signTime}&q-header-list=&q-url-param-list=&q-signature={$signature}";
return $authorization;
}
}
<?php declare(strict_types=1);
namespace Hdll\Services\V2\Common\ClsLogger;
use DateTime;
use Monolog\Handler\AbstractProcessingHandler;
use Swoft\Co;
use Swoft\Log\Helper\Log;
use Swoft\Log\Logger;
use Swoft\Log\Logger as SwoftLogger;
use Swoft\Stdlib\Helper\JsonHelper;
use function array_column;
use function implode;
use function in_array;
/**
* Class FileHandler
*
* @since 2.0
*/
class LogHandler extends AbstractProcessingHandler
{
//腾讯云日志主题
protected $topicId;
/**
* Write log levels
*
* @var string
*/
protected $levels = '';
/**
* @var array
*/
protected $levelValues = [];
/**
* Will exec on construct
*/
public function init(): void
{
if (is_array($this->levels)) {
$this->levelValues = $this->levels;
return;
}
// Levels like 'notice,error'
if (is_string($this->levels)) {
$levelNames = explode(',', $this->levels);
$this->levelValues = SwoftLogger::getLevelByNames($levelNames);
}
}
/**
* Write log by batch
*
* @param array $records
*
* @return void
*/
public function handleBatch(array $records): void
{
$records = $this->recordFilter($records);
if (!$records) {
return;
}
$this->write($records);
}
/**
* Write file
*
* @param array $records
*/
protected function write(array $records): void
{
if (Log::getLogger()->isJson()) {
$records = array_map([$this, 'formatJson'], $records);
} else {
$records = array_column($records, 'formatted');
}
$messageText = implode(" __||__ ", $records);
if($this->topicId == ClsLog::TOPICID_ERROR) {
if (Co::id() > 0) {
go(function () use ($messageText) {
ClsLog::error($messageText);
});
} else {
ClsLog::error($messageText);
}
} else if($this->topicId == ClsLog::TOPICID_NOTICE) {
if (Co::id() > 0) {
go(function () use ($messageText) {
ClsLog::notice($messageText);
});
} else {
ClsLog::notice($messageText);
}
}
}
/**
* Filter record
*
* @param array $records
*
* @return array
*/
private function recordFilter(array $records): array
{
$messages = [];
foreach ($records as $record) {
if (!isset($record['level'])) {
continue;
}
if (!$this->isHandling($record)) {
continue;
}
$record = $this->processRecord($record);
$search1 = strpos($record['messages'], '[http://testapi.2b3.cn:80/]');
$search2 = strpos($record['messages'], '[http://api.2b3.cn:80/]');
if($search1 !== false || $search2 !== false) {
continue;
}
$record['formatted'] = $this->getFormatter()->format($record);
$messages[] = $record;
}
return $messages;
}
/**
* @param array $record
*
* @return string
*/
public function formatJson(array $record): string
{
unset($record['formatted'], $record['extra']);
if ($record['level'] === Logger::NOTICE) {
unset($record['context']);
}
if ($record['datetime'] instanceof DateTime) {
$record['datetime'] = $record['datetime']->format('Y-m-d H:i:s');
}
return JsonHelper::encode($record, JSON_UNESCAPED_UNICODE);
}
/**
* Whether to handler log
*
* @param array $record
*
* @return bool
*/
public function isHandling(array $record): bool
{
if (empty($this->levelValues)) {
return true;
}
return in_array($record['level'], $this->levelValues, true);
}
}
<?php
namespace Hdll\Services\V2\Common\Config;
use Swoft\Redis\Redis;
class CfgCenter
{
const COS = 'cos'; //腾讯云存储
const CLS = 'cls'; //腾讯云日志服务
const CMQ = 'cmq'; //腾讯云cmq订阅消息
const ENCRYPT_KEY = 'encrypt_key'; //数据加密的key
const BACKEND_WEAPP = 'backend_weapp'; //蓝猫小程序配置
const FRONTEND_WEAPP = 'frontend_weapp'; //橙猫小程序配置
const ALIYUN_SMS = 'aliyun_sms'; //阿里云短信
const TENCENT_SMS = 'tencent_sms'; //腾讯云短信
const MP = 'mp'; //公众号-用于H5公众号登录和发送公众号通知
const MP_CARD = 'mp_card'; //制作卡券公众号
const PAY = 'pay'; //支付配置
const DRAW_MONEY = 'draw_money'; //提现配置
const PAY_KUANYUAN = 'pay_kuanyuan'; //宽元的支付平台配置
const PAY_YUNMAI_ISP = 'pay_yunmai_isp'; //云脉的支付服务商配置,用于托管子商户
const PAY_ZHIMEI = 'pay_zhimei'; //致美的支付配置
const PAY_TRANSFER = 'pay_transfer'; //提现打款专用的支付配置
const PAY_YUNMAIKEJI = 'pay_yunmaikeji'; // 云脉科技支付
const SELLER_DISTRIBUTION = 'seller_distribution'; //卖家分销配置
const MP_ZHIMEI = 'mp_zhimei'; //致美的公众号配置
const MP_OEMADM = 'mp_oemadm'; // OEM机构管理员公众号后台,使用云脉科技公众号
/**
* 根据用户token获取配置, 优先使用此方法读取配置
* 用法:
* $cfgdata = CfgCenter::getByUser(CfgCenter::COS, $this->user);
* var_dump($cfgdata['Region']); // 输出:ap-shanghai
* @param string $keyName
* @param \Hdll\Services\Common\Entity\User $user 用户token的实例对象
* @return mixed
*/
public static function getByUser($keyName, \Hdll\Services\Common\Entity\User $user)
{
if( is_numeric($user->getOemId()) ) { // oemId有可能等于0
return self::getByOemId($keyName, $user->getOemId());
} else if($user->getStoreId()) {
return self::getByStoreId($keyName, $user->getStoreId());
} else if($user->getUnionid()) {
return self::getByUnionId($keyName, $user->getUnionid());
}
}
/**
* 根据oemId读取指定的配置项 - 返回数组格式
* @param string $keyName
* @param int $oemId oemId==0表示是活动啦啦
* @return mixed
*/
public static function getByOemId($keyName, int $oemId)
{
return self::_get($keyName, $oemId);
}
/**
* 如果有oemId,尽量使用方法getByOemId()读取配置
* 根据storeId获取所属OEM平台的配置
*
* @param string $keyName
* @param string $storeId
* @return mixed
*/
public static function getByStoreId($keyName, int $storeId)
{
$dbConn = self::dbConnect('seller');
$result = $dbConn->get("seller", ['oemId'], ['storeId' => $storeId]);
return self::_get($keyName, (int)$result['oemId']);
}
/**
* 如果有oemId,尽量使用方法getByOemId()读取配置
* 根据sellerId获取所属OEM平台的配置
*
* @param string $keyName
* @param string $sellerId
* @return mixed
*/
public static function getBySellerId($keyName, int $sellerId)
{
$dbConn = self::dbConnect('seller');
$result = $dbConn->get("seller", ['oemId'], ['id' => $sellerId]);
return self::_get($keyName, (int)$result['oemId']);
}
/**
* 如果有oemId,尽量使用方法getByOemId()读取配置
* 根据unionId获取所属OEM平台的配置
*
* @param string $keyName
* @param string $unionId
* @return mixed
*/
public static function getByUnionId($keyName, string $unionId)
{
$dbConn = self::dbConnect('seller');
$result = $dbConn->get("seller", ['oemId'], ['unionId' => $unionId]);
return self::_get($keyName, (int)$result['oemId']);
}
/**
* 如果有oemId,尽量使用方法getCertByOemId()读取证书
* 根据店铺id获取支付证书
*
* @param integer $storeId
* @return array
*/
public static function getCertByStoreId($keyName, $storeId) {
$dbConn = self::dbConnect('seller');
$result = $dbConn->get("seller", ['oemId'], ['storeId' => $storeId]);
$oemId = (int)$result['oemId'];
$dbConn = self::dbConnect();//连接配置库
// 注意,需要返回oemId字段
$result = $dbConn->get("config", ['oemId', 'certPem', 'keyPem'], ['oemId' => $oemId, 'name' => $keyName]);
return $result;
}
/**
* 根据oemId获取支付证书
*
* @param integer $oemId
* @return array
*/
public static function getCertByOemId($keyName, int $oemId) {
$dbConn = self::dbConnect();//连接配置库
// 注意,需要返回oemId字段
$result = $dbConn->get("config", ['oemId', 'certPem', 'keyPem'], ['oemId' => $oemId, 'name' => $keyName]);
return $result;
}
/**
* 根据mchId获取对应的支付配置
*
* @param string $mchId
* @return mixed
*/
public static function getByMchId(int $mchId)
{
$dbConn = self::dbConnect();//连接配置库
$result = $dbConn->get("config", ['value'], ['mchId' => $mchId]);
$resArr = json_decode($result['value'], true);
return is_array($resArr) ? $resArr : $result['value'];
}
/**
* 根据配置名称查询所有匹配项。包含所有oem机构的配置
*
* @param string $keyName
* @return array
*/
public static function getByKey(string $keyName)
{
$result = [];
$dbConn = self::dbConnect();//连接配置库
$rows = $dbConn->select("config", ['oemId', 'value'], ['name' => $keyName]);
foreach($rows as $row) {
$result[$row['oemId']] = [
'oemId' => $row['oemId'],
'value' => json_decode($row['value'], true),
];
}
return $result;
}
public static function dbConnect($database='')
{
if($database == '') {
$database = 'config_center';
}
if (\env('ENVIRONMENT', '') == '') {
// 返回线上数据库连接
return new \Medoo\Medoo([
'database_type' => 'mysql',
'database_name' => $database,
'server' => '172.21.0.12',
'username' => 'configer',
'password' => 'Cfgsu#2390f*_',
'charset' => 'utf8'
]);
} else {
// 返回测试数据库连接
return new \Medoo\Medoo([
'database_type' => 'mysql',
'database_name' => $database,
'server' => '192.168.3.202',
'username' => 'hdller',
'password' => 'Hdlltest888',
'charset' => 'utf8'
]);
}
}
private static function _get($keyName, int $oemId = 1)
{
$prefix = "CONFIG_CENTER:oemid_$oemId:";
$data = Redis::get($prefix . $keyName);
if($data) {
$result = json_decode($data, true);
return is_array($result) ? $result : $data;
}
// 没有缓存则从数据库读取:
$valArr = self::_getConfigFromDb($keyName, $oemId);
if ($valArr) { //有内容时进行redis缓存
if (is_array($valArr)) {
$valArr['oemId'] = $oemId; //需要将oemId加入配置返回
Redis::set($prefix . $keyName, json_encode($valArr), 3600);
} else {
Redis::set($prefix . $keyName, $valArr, 3600);
}
}
return $valArr;
}
private static function _getConfigFromDb($keyName, $oemId)
{
$dbConn = self::dbConnect();
$result = $dbConn->select("config", ['value'], ['oemId' => $oemId, 'name' => $keyName]);
if (!isset($result[0]['value'])) {
if($oemId > 0) {
// 如果指定的oemId查找不到,则使用活动啦啦(oemId==0且common==1)的配置
$result = $dbConn->select("config", ['value'], ['oemId' => 0, 'common' => 1, 'name' => $keyName]);
if (!isset($result[0]['value'])) {
return;
}
} else {
return;
}
}
$valArr = json_decode($result[0]['value'], true);
if (!is_array($valArr)) {
return $result[0]['value'];
}
return $valArr;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment