MallLogic
<?php
namespace console\logic;
// ......
/**
*
* @author vogin
*
*/
class MallLogic
{
// 20 天
const CHECK_DURATION = 1728000;
/**
* 获取https证书信息
*
* @return boolean|array
*/
public static function getHttpsCertInfo ($domain)
{
$context = stream_context_create([
'ssl' => [
'verify_host' => false,
'verify_peer' => false,
'verify_peer_name' => false,
'capture_peer_cert' => true,
'capture_peer_cert_chain' => true
]
]);
$client = stream_socket_client("ssl://" . $domain . ":443", $errno, $errstr, 3, STREAM_CLIENT_CONNECT, $context);
if(! $client)
{
return false;
}
$params = stream_context_get_params($client);
$cert = $params['options']['ssl']['peer_certificate'];
$cert_info = openssl_x509_parse($cert);
fclose($client);
return $cert_info;
}
/**
* 检测 https证书状态
*/
public static function checkHttpsDomain ()
{
// [此处的 $domains 从数据库获取对应的内容]
$domains = [];
$error_message = '';
$nodes = [];
foreach($domains as $data)
{
$label = $data['label'];
$domain = $data['value'];
try
{
// 获取证书信息
$cert_info = static::getHttpsCertInfo($domain);
if(empty($cert_info))
{
throw new UserException('未获取到信息');
}
// 获取成功
$validTo_time_t = $cert_info['validTo_time_t'];
$validTo_time_d = date('Y-m-d H:i:s', $validTo_time_t);
// 将内容转为节点
$node = new HttpsCheckNode();
$node->label = $label;
$node->domain = $domain;
$node->expire = $validTo_time_d;
$node->expireStamp = $validTo_time_t;
$nodes[] = $node;
}
catch(Exception $e)
{
// 获取失败
$error_message .= $label . '[ ' . $domain . ' ]证书检测异常:' . $e->getMessage() . PHP_EOL;
}
}
// 排序
// 自定义排序
usort($nodes, function (HttpsCheckNode $node1, HttpsCheckNode $node2)
{
if($node1->expireStamp == $node2->expireStamp)
{
return 0;
}
// 正序 > 从小到大
return ($node1->expireStamp < $node2->expireStamp) ? - 1 : 1;
});
$msg = '';
// 当前时间
$now = time();
/**
*
* @var HttpsCheckNode $node
*/
foreach($nodes as $node)
{
$expire_msg = '';
// 判断是否快到期
if($node->expireStamp - $now < self::CHECK_DURATION)
{
$expire_msg = ',还有' . intval(($node->expireStamp - $now) / 86400) . '天过期';
}
$msg .= $node->label . '[ ' . $node->domain . ' ]的https证书有效期至(' . $node->expire . ')' . $expire_msg . PHP_EOL;
}
// 组装错误信息
$msg .= $error_message;
$res = DingDingLogic::send("[Https证书检测系统]提示:\n" . $msg);
echo '钉钉发送结果:' . $res . PHP_EOL;
}
}
DingDingLogic
<?php
namespace console\logic;
/**
* 钉钉内容自定义发送内容
*
* @author vogin
*
*/
class DingDingLogic
{
// 此处改为钉钉的webhook地址
const WEBHOOK = '.....';
/**
* 发送message
*
* @param string $msg
* 信息内容
*/
public static function send ($msg)
{
$data = array(
'msgtype' => 'text',
'text' => array(
'content' => $msg
)
);
$data_str = json_encode($data);
return static::post(self::WEBHOOK, $data_str);
}
/**
* 给钉钉发送post内容
*
* @param string $url
* 接口地址
* @param string $post_str
* json的post内容
* @return mixed
*/
public static function post ($url, $post_str)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json;charset=utf-8'
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_str);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}