init
This commit is contained in:
214
core/basic/Basic.php
Normal file
214
core/basic/Basic.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年11月4日
|
||||
* 系统基础类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
class Basic
|
||||
{
|
||||
|
||||
protected static $models = array();
|
||||
|
||||
// 实现类文件自动加载
|
||||
public static function autoLoad($className)
|
||||
{
|
||||
if (substr($className, 0, 4) == 'core') { // 框架类文件命名空间转换
|
||||
$class_file = CORE_PATH . '/' . str_replace('\\', '/', substr($className, 5)) . '.php';
|
||||
} elseif (substr($className, 0, 3) == 'app') { // 应用类文件命名空间转换
|
||||
$class_file = APP_PATH . '/' . str_replace('\\', '/', substr($className, 4)) . '.php';
|
||||
} elseif (strpos($className, '\\')) { // 如果带有命名空间,使用全路径载入
|
||||
$class_file = ROOT_PATH . '/' . str_replace('\\', '/', $className) . '.php';
|
||||
} else { // 默认载入内核基础目录下文件
|
||||
$class_file = CORE_PATH . '/basic/' . $className . '.php';
|
||||
}
|
||||
if (! file_exists($class_file)) {
|
||||
error('自动加载类文件时发生错误,类名【' . $className . '】,文件:【' . $class_file . '】');
|
||||
}
|
||||
require $class_file;
|
||||
}
|
||||
|
||||
// 自定义错误函数
|
||||
public static function errorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if (! (error_reporting() & $errno)) {
|
||||
// 如果这个错误类型没有包含在error_reporting里,如加了@的错误则不报告
|
||||
return;
|
||||
}
|
||||
switch ($errno) {
|
||||
case E_ERROR:
|
||||
$err_level = 'ERROR';
|
||||
break;
|
||||
case E_WARNING:
|
||||
$err_level = 'WARNING';
|
||||
break;
|
||||
case E_PARSE:
|
||||
$err_level = 'PARSE';
|
||||
break;
|
||||
case E_NOTICE:
|
||||
$err_level = 'NOTICE';
|
||||
break;
|
||||
case E_RECOVERABLE_ERROR:
|
||||
case E_CORE_ERROR:
|
||||
case E_COMPILE_ERROR:
|
||||
case E_USER_ERROR:
|
||||
$err_level = 'FATAL ERROR';
|
||||
break;
|
||||
default:
|
||||
$err_level = 'UNKNOW';
|
||||
break;
|
||||
}
|
||||
$info = "<h3>$err_level:</h3>\n";
|
||||
$info .= "<p><b>Code:</b> $errno;</p>\n";
|
||||
$info .= "<p><b>Desc:</b> $errstr;</p>\n";
|
||||
$info .= "<p><b>File:</b> $errfile;</p>\n";
|
||||
$info .= "<p><b>Line:</b> $errline;</p>\n";
|
||||
|
||||
if ($err_level == 'WARNING' || $err_level == 'NOTICE') {
|
||||
echo $info;
|
||||
} else {
|
||||
error($info);
|
||||
}
|
||||
}
|
||||
|
||||
// 异常捕获
|
||||
public static function exceptionHandler($exception)
|
||||
{
|
||||
error("程序运行异常: " . $exception->getMessage() . ",位置:" . $exception->getFile() . ',第' . $exception->getLine() . '行。');
|
||||
}
|
||||
|
||||
// 致命错误捕获
|
||||
public static function shutdownFunction()
|
||||
{
|
||||
$error = error_get_last();
|
||||
define('E_FATAL', E_ERROR | E_RECOVERABLE_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR);
|
||||
if ($error && ($error["type"] === ($error["type"] & E_FATAL))) {
|
||||
$errno = $error["type"];
|
||||
$errstr = $error["message"];
|
||||
$errfile = $error["file"];
|
||||
$errline = $error["line"];
|
||||
self::errorHandler($errno, $errstr, $errfile, $errline);
|
||||
}
|
||||
}
|
||||
|
||||
// 会话处理程序设置
|
||||
public static function setSessionHandler()
|
||||
{
|
||||
if (ini_get('session.auto_start')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 配置会话安全参数
|
||||
session_name('PbootSystem');
|
||||
ini_set("session.use_trans_sid", 0);
|
||||
ini_set("session.use_cookies", 1);
|
||||
ini_set("session.use_only_cookies", 1);
|
||||
session_set_cookie_params(0, SITE_DIR . '/', null, null, true);
|
||||
|
||||
switch (Config::get('session.handler')) {
|
||||
case 'memcache':
|
||||
if (! extension_loaded('memcache'))
|
||||
error('PHP运行环境未安装memcache.dll扩展!');
|
||||
ini_set("session.save_handler", "memcache");
|
||||
ini_set("session.save_path", Config::get('seesion.path'));
|
||||
break;
|
||||
default:
|
||||
if (Config::get('session_in_sitepath')) {
|
||||
$save_path = RUN_PATH . '/session/';
|
||||
if (! check_dir($save_path, true))
|
||||
error('设置的会话目录创建失败!' . $save_path);
|
||||
ini_set("session.save_handler", "files");
|
||||
$depth = 1;
|
||||
ini_set("session.save_path", $depth . ';' . $save_path);
|
||||
if (! is_dir($save_path . '/0/0') || ! is_dir($save_path . '/v/v')) {
|
||||
create_session_dir($save_path, $depth);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 实例化模型
|
||||
public static function createModel($name = null, $new = false)
|
||||
{
|
||||
// 自动同名模型控制器
|
||||
if (! $name)
|
||||
$name = C;
|
||||
|
||||
// 获取类名
|
||||
if (strpos($name, '.') !== false) {
|
||||
$path = explode('.', $name);
|
||||
$class_name = '\\app\\' . $path[0] . '\\model';
|
||||
$len = count($path);
|
||||
for ($i = 1; $i < $len - 1; $i ++) {
|
||||
$class_name .= '\\' . $path[$i];
|
||||
}
|
||||
$class_name .= '\\' . ucfirst($path[$i]) . 'Model';
|
||||
} else {
|
||||
$class_name = '\\app\\' . M . '\\model\\' . ucfirst($name) . 'Model';
|
||||
}
|
||||
|
||||
// 根据需要实例化
|
||||
$key = md5($class_name);
|
||||
if (! isset(self::$models[$key]) || $new) {
|
||||
self::$models[$key] = new $class_name();
|
||||
}
|
||||
|
||||
return self::$models[$key];
|
||||
}
|
||||
|
||||
// 创建数据接口
|
||||
public static function createApi($args = null)
|
||||
{
|
||||
// 直接调用方式
|
||||
if (! is_array($args)) {
|
||||
$args = func_get_args();
|
||||
}
|
||||
|
||||
// 分离参数
|
||||
$name = $args[0];
|
||||
unset($args[0]);
|
||||
$param = $args;
|
||||
|
||||
// 如果只是传递了方法,则自动完善模块及模型控制器
|
||||
if (strpos($name, '.') === false) {
|
||||
$name = M . '.' . C . '.' . $name;
|
||||
}
|
||||
|
||||
$path = explode('.', $name); // 第一个为模块 $path[0],倒数第二个为模型$path[$i],倒数第一个为方法$path[$i+1]
|
||||
$class_name = '\\app\\' . $path[0] . '\\model';
|
||||
$len = count($path);
|
||||
for ($i = 1; $i < $len - 2; $i ++) {
|
||||
$class_name .= '\\' . $path[$i];
|
||||
}
|
||||
$class_name .= '\\' . ucfirst($path[$i]) . 'Model';
|
||||
$key = md5($class_name);
|
||||
|
||||
if (isset(self::$models[$key])) {
|
||||
$model = self::$models[$key];
|
||||
} else {
|
||||
$model = new $class_name();
|
||||
self::$models[$key] = $model;
|
||||
}
|
||||
|
||||
// 调取接口方法
|
||||
if (is_array($param)) {
|
||||
$rs = call_user_func_array(array(
|
||||
$model,
|
||||
$path[$i + 1]
|
||||
), $param);
|
||||
}
|
||||
|
||||
// 返回结果,如果不是json数据,则转换
|
||||
if (! ! $return = json_decode($rs)) {
|
||||
return $rs;
|
||||
} else {
|
||||
return json_encode($rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
core/basic/Cache.php
Normal file
57
core/basic/Cache.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年10月24日
|
||||
* 缓存统一调用类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
use core\basic\Config;
|
||||
use core\cache\Memcache;
|
||||
|
||||
class Cache
|
||||
{
|
||||
|
||||
// 获取缓存实例
|
||||
protected static function getCacheInstance()
|
||||
{
|
||||
switch (Config::get('cache.handler')) {
|
||||
case 'memcache':
|
||||
$instance = Memcache::getInstance();
|
||||
break;
|
||||
default:
|
||||
$instance = Memcache::getInstance();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
// 写入缓存
|
||||
public static function set($key, $value)
|
||||
{
|
||||
$cache = self::getCacheInstance();
|
||||
return $cache->set($key, $value);
|
||||
}
|
||||
|
||||
// 读取缓存
|
||||
public static function get($key)
|
||||
{
|
||||
$cache = self::getCacheInstance();
|
||||
return $cache->get($key);
|
||||
}
|
||||
|
||||
// 删除缓存
|
||||
public static function delete($key)
|
||||
{
|
||||
$cache = self::getCacheInstance();
|
||||
return $cache->delete($key);
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
public static function flush()
|
||||
{
|
||||
$cache = self::getCacheInstance();
|
||||
return $cache->flush();
|
||||
}
|
||||
}
|
||||
137
core/basic/Check.php
Normal file
137
core/basic/Check.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2016年11月6日
|
||||
* 系统环境检查类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
use core\basic\Config;
|
||||
|
||||
class Check
|
||||
{
|
||||
|
||||
// 启动应用检查
|
||||
public static function checkApp()
|
||||
{
|
||||
if (! is_dir(APP_PATH)) {
|
||||
error('您的系统文件无法正常读取,请检查是否上传完整!');
|
||||
}
|
||||
|
||||
// 判断自动转换状态
|
||||
if (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) {
|
||||
error('您的服务器环境PHP.ini中magic_quotes_gpc配置为On状态,会导致数据存储异常,请设置为Off状态或切换为更高版本PHP。');
|
||||
}
|
||||
|
||||
// 判断目录列表函数
|
||||
if (! function_exists('scandir')) {
|
||||
error('您的服务器环境PHP.ini配置中已经禁用scandir函数,会导致无法正常读取配置及模板文件,请先去除。');
|
||||
}
|
||||
|
||||
// 检查gd扩展
|
||||
if (! extension_loaded('gd')) {
|
||||
error('您的服务器环境不支持gd扩展,将无法使用验证码!');
|
||||
}
|
||||
|
||||
// 检查mbstring扩展
|
||||
if (! extension_loaded('mbstring')) {
|
||||
error('您的服务器环境不支持mbstring扩展,请先安装并启用!');
|
||||
}
|
||||
|
||||
// 检查curl扩展
|
||||
if (! extension_loaded('curl')) {
|
||||
error('您的服务器环境不支持curl扩展,请先安装并启用!');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查PHP版本
|
||||
public static function checkPHP()
|
||||
{
|
||||
if (PHP_VERSION < '5.3') {
|
||||
error('您服务器的PHP版本太低,本程序要求版本不小于 5.3');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查mysqli扩展库
|
||||
public static function checkMysqli()
|
||||
{
|
||||
if (! extension_loaded('mysqli')) {
|
||||
error('您的服务器环境不支持mysqli扩展,将无法正常使用数据库!');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查curl扩展库
|
||||
public static function checkCurl()
|
||||
{
|
||||
if (! extension_loaded('curl')) {
|
||||
error('您的服务器环境不支持curl扩展,将无法使用API模式!');
|
||||
}
|
||||
}
|
||||
|
||||
// 目录路径检查,不存在时根据配置文件选择是否自动创建
|
||||
public static function checkBasicDir()
|
||||
{
|
||||
if (Config::get('debug')) {
|
||||
check_dir(APP_PATH, true);
|
||||
check_dir(APP_PATH . '/common', true);
|
||||
check_dir(CONF_PATH, true);
|
||||
}
|
||||
|
||||
// 目录权限判断
|
||||
if (! check_dir(RUN_PATH, true)) {
|
||||
error('缓存目录创建失败,可能写入权限不足!' . RUN_PATH);
|
||||
}
|
||||
if (! check_dir(DOC_PATH . STATIC_DIR . '/upload', true)) {
|
||||
error('上传目录创建失败,可能写入权限不足!' . DOC_PATH . STATIC_DIR . '/upload');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查系统默认首页的文件是否存在,不存在进行自动创建
|
||||
public static function checkAppFile()
|
||||
{
|
||||
$apps = Config::get('public_app', true);
|
||||
check_dir(APP_CONTROLLER_PATH, true);
|
||||
check_file(CONF_PATH . '/config.php', true, "<?php \r\n return array(\r\n\t //'控制项'=>'值' 以分号,分割\r\n);");
|
||||
check_file(APP_CONTROLLER_PATH . '/IndexController.php', true, "<?php \r\r namespace app\\" . M . "\\controller;\r\r use core\\basic\\Controller; \r\r class IndexController extends Controller{\r\r\tpublic function index(){\r\t\t\$this->display('index.html');\r\t} \r\r}");
|
||||
check_file(APP_PATH . '/common/' . ucfirst(M) . 'Controller.php', true, "<?php \r\rnamespace app\\common;\r\ruse core\\basic\\Controller; \r\rclass " . ucfirst(M) . "Controller extends Controller{ \r\r}");
|
||||
// check_file(APP_PATH . '/common/' . ucfirst(M) . 'Model.php', true, "<?php \r\rnamespace app\\common;\r\ruse core\\basic\\Model; \r\rclass " . ucfirst(M) . "Model extends Model{ \r\r}");
|
||||
}
|
||||
|
||||
// 检查客户端浏览器是否被允许,在同时设置黑白名单时,黑名单具有优先级更高,在设置了白名单时,将只允许白名单访问
|
||||
public static function checkBs()
|
||||
{
|
||||
$allow_bs = Config::get('access_rule.allow_bs', true);
|
||||
$deny_bs = Config::get('access_rule.deny_bs', true);
|
||||
// 都未设置时,直接通过
|
||||
if (! $allow_bs && ! $deny_bs)
|
||||
return true;
|
||||
// 客户端使用的系统
|
||||
$user_bs = get_user_bs();
|
||||
// 如果在黑名单则直接拒绝
|
||||
if (in_array($user_bs, $deny_bs)) {
|
||||
error('本站点设置了不允许' . $user_bs . '内核浏览器访问,请使用其它版本IE、火狐、谷歌等,国产浏览器请使用极速模式!');
|
||||
} elseif ($allow_bs && ! in_array($user_bs, $allow_bs)) {
|
||||
error('本站点设置了只允许' . implode(',', $allow_bs) . '内核浏览器访问,请使用这些浏览器!');
|
||||
}
|
||||
}
|
||||
|
||||
// 检查客户端操作系统是否被允许,在同时设置黑白名单时,黑名单具有优先级更高,在设置了白名单时,将只允许白名单访问
|
||||
public static function checkOs()
|
||||
{
|
||||
$allow_os = Config::get('access_rule.allow_os', true);
|
||||
$deny_os = Config::get('access_rule.deny_os', true);
|
||||
// 都未设置时,直接通过
|
||||
if (! $allow_os && ! $deny_os)
|
||||
return true;
|
||||
// 客户端使用的系统
|
||||
$user_os = get_user_os();
|
||||
// 如果在黑名单则直接拒绝
|
||||
if (in_array($user_os, $deny_os)) {
|
||||
error('本站点设置了不允许' . $user_os . '访问,请使用其它操作系统!');
|
||||
} elseif ($allow_os && ! in_array($user_os, $allow_os)) {
|
||||
error('本站点设置了只允许' . implode(',', $allow_os) . '访问,请使用这些操作系统!');
|
||||
}
|
||||
}
|
||||
}
|
||||
174
core/basic/Config.php
Normal file
174
core/basic/Config.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年10月15日
|
||||
* 配置信息读取类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
class Config
|
||||
{
|
||||
|
||||
// 存储配置信息
|
||||
protected static $configs;
|
||||
|
||||
// 直接获取配置参数
|
||||
public static function get($item = null, $array = false)
|
||||
{
|
||||
// 自动载入配置文件
|
||||
if (! isset(self::$configs)) {
|
||||
self::$configs = self::loadConfig();
|
||||
}
|
||||
// 返回全部配置
|
||||
if ($item === null) {
|
||||
return self::$configs;
|
||||
}
|
||||
$items = explode('.', $item);
|
||||
if (isset(self::$configs[$items[0]])) {
|
||||
$value = self::$configs[$items[0]];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
$items_len = count($items);
|
||||
for ($i = 1; $i < $items_len; $i ++) {
|
||||
if (isset($value[$items[$i]])) {
|
||||
$value = $value[$items[$i]];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 强制返回数据为数组形式
|
||||
if ($array && ! is_array($value)) {
|
||||
if ($value) {
|
||||
$value = explode(',', $value);
|
||||
$value = array_map('trim', $value); // 去空格
|
||||
} else {
|
||||
$value = array();
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
// 写入配置文件
|
||||
public static function set($itemName, array $data, $multistage = false, $assign = true)
|
||||
{
|
||||
if ($data) {
|
||||
$path = RUN_PATH . '/config/' . $itemName . '.php';
|
||||
|
||||
// 是否使用多级
|
||||
if ($multistage) {
|
||||
// 如果获取到配置信息,执行合并
|
||||
if (! ! $configs = self::get($itemName)) {
|
||||
$data = mult_array_merge($configs, $data);
|
||||
}
|
||||
$config[$itemName] = $data;
|
||||
} else {
|
||||
$config = $data;
|
||||
}
|
||||
|
||||
// 写入
|
||||
if (check_file($path, true)) {
|
||||
$result = file_put_contents($path, "<?php\nreturn " . var_export($config, true) . ";");
|
||||
if ($assign) { // 缓存后是否注入配置
|
||||
self::assign($path);
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 载入配置文件
|
||||
private static function loadConfig()
|
||||
{
|
||||
// 载入配置惯性文件
|
||||
if (file_exists(CORE_PATH . '/convention.php')) {
|
||||
$configs = require CORE_PATH . '/convention.php';
|
||||
} else {
|
||||
die('系统框架文件丢失,惯性配置文件不存在!');
|
||||
}
|
||||
|
||||
// 载入用户主配置文件
|
||||
if (file_exists(CONF_PATH . '/config.php')) {
|
||||
$config = require CONF_PATH . '/config.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入用户数据库配置文件
|
||||
if (file_exists(CONF_PATH . '/database.php')) {
|
||||
$config = require CONF_PATH . '/database.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入用户路由配置文件
|
||||
if (file_exists(CONF_PATH . '/route.php')) {
|
||||
$config = require CONF_PATH . '/route.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入扩展的配置文件
|
||||
$ext_path = CONF_PATH . '/ext';
|
||||
if (is_dir($ext_path) && function_exists('scandir')) {
|
||||
$files = scandir($ext_path);
|
||||
for ($i = 0; $i < count($files); $i ++) {
|
||||
$file = $ext_path . '/' . $files[$i];
|
||||
if (is_file($file)) {
|
||||
$config = require $file;
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 载入系统路由文件
|
||||
if (file_exists(APP_PATH . '/common/route.php')) {
|
||||
$config = require APP_PATH . '/common/route.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入应用版本文件
|
||||
if (file_exists(APP_PATH . '/common/version.php')) {
|
||||
$config = require APP_PATH . '/common/version.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入系统配置缓存
|
||||
if (file_exists(RUN_PATH . '/config/' . md5('config') . '.php')) {
|
||||
$config = require RUN_PATH . '/config/' . md5('config') . '.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 载入区域配置缓存
|
||||
if (file_exists(RUN_PATH . '/config/' . md5('area') . '.php')) {
|
||||
$config = require RUN_PATH . '/config/' . md5('area') . '.php';
|
||||
$configs = mult_array_merge($configs, $config);
|
||||
}
|
||||
|
||||
// 清理缓冲区,避免配置文件出现Bom时影响显示
|
||||
@ob_clean();
|
||||
return $configs;
|
||||
}
|
||||
|
||||
// 配置文件注入
|
||||
public static function assign($filePath)
|
||||
{
|
||||
if (! file_exists($filePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$assign_config = require $filePath;
|
||||
if (! is_array($assign_config))
|
||||
return;
|
||||
|
||||
if (self::$configs) {
|
||||
$configs = mult_array_merge(self::$configs, $assign_config);
|
||||
} else {
|
||||
$configs = $assign_config;
|
||||
}
|
||||
self::$configs = $configs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
117
core/basic/Controller.php
Normal file
117
core/basic/Controller.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2016年11月6日
|
||||
* 应用控制基类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
use core\view\View;
|
||||
use core\view\Paging;
|
||||
|
||||
class Controller
|
||||
{
|
||||
|
||||
// 显示模板
|
||||
final protected function display($file)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
$content = $view->parser($file);
|
||||
$content = $this->runtime($content);
|
||||
echo $this->gzip($content);
|
||||
exit();
|
||||
}
|
||||
|
||||
// 解析模板
|
||||
final protected function parser($file)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
return $view->parser($file);
|
||||
}
|
||||
|
||||
// 缓存页面内容,默认直接显示内容,可传递第二参数false返回内容
|
||||
final protected function cache($content, $display = true)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
if (Config::get('tpl_html_cache')) {
|
||||
$content = str_replace('{pboot:runtime}', 'Cached at ' . date('Y-m-d H:i:s'), $content);
|
||||
} else {
|
||||
$content = $this->runtime($content);
|
||||
}
|
||||
$view->cache($content); // 压缩前缓存
|
||||
$content = $this->gzip($content);
|
||||
if ($display) {
|
||||
echo $content;
|
||||
exit();
|
||||
} else {
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置视图主题
|
||||
final protected function setTheme($themeName)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
$view->assign('theme', $themeName);
|
||||
}
|
||||
|
||||
// 变量注入接口
|
||||
final protected function assign($var, $value)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
$view->assign($var, $value);
|
||||
}
|
||||
|
||||
// 变量获取接口
|
||||
final protected function getVar($var)
|
||||
{
|
||||
$view = View::getInstance();
|
||||
return $view->getVar($var);
|
||||
}
|
||||
|
||||
// 手动生成分页信息,返回限制语句
|
||||
final protected function page($tatal, $morePageStr = false)
|
||||
{
|
||||
$page = Paging::getInstance();
|
||||
return $page->limit($tatal, $morePageStr);
|
||||
}
|
||||
|
||||
// 获取配置信息
|
||||
final protected function config($item = null, $array = false)
|
||||
{
|
||||
return Config::get($item, $array);
|
||||
}
|
||||
|
||||
// 缓存配置信息
|
||||
final protected function setConfig($itemName, array $data)
|
||||
{
|
||||
return Config::set($itemName, $data);
|
||||
}
|
||||
|
||||
// 写入日志信息
|
||||
final protected function log($content, $level = "info")
|
||||
{
|
||||
Log::write($content, $level);
|
||||
}
|
||||
|
||||
// 解析运行时间标签
|
||||
private function runtime($content)
|
||||
{
|
||||
return str_replace('{pboot:runtime}', 'Processed in ' . round(microtime(true) - START_TIME, 6) . ' second(s).', $content);
|
||||
}
|
||||
|
||||
// 压缩内容
|
||||
private function gzip($content)
|
||||
{
|
||||
if (Config::get('gzip') && ! headers_sent() && extension_loaded("zlib") && strstr($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip")) {
|
||||
$content = gzencode($content, 6);
|
||||
header("Content-Encoding: gzip");
|
||||
header("Vary: Accept-Encoding");
|
||||
header("Content-Length: " . strlen($content));
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
37
core/basic/Db.php
Normal file
37
core/basic/Db.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年11月1日
|
||||
* 数据库快速操作类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
use core\basic\Model;
|
||||
|
||||
class Db
|
||||
{
|
||||
|
||||
// 对象方式动态调用数据库操作方法
|
||||
public function __call($methed, $args)
|
||||
{
|
||||
$model = new Model();
|
||||
$result = call_user_func_array(array(
|
||||
$model,
|
||||
$methed
|
||||
), $args);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// 静态方式动态调用数据库操作方法
|
||||
public static function __callstatic($methed, $args)
|
||||
{
|
||||
$model = new Model();
|
||||
$result = call_user_func_array(array(
|
||||
$model,
|
||||
$methed
|
||||
), $args);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
10
core/basic/Kernel.php
Normal file
10
core/basic/Kernel.php
Normal file
File diff suppressed because one or more lines are too long
70
core/basic/Log.php
Normal file
70
core/basic/Log.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年10月24日
|
||||
* 日志统一调用类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
use core\log\LogText;
|
||||
use core\log\LogDb;
|
||||
|
||||
class Log
|
||||
{
|
||||
|
||||
// 获取缓存实例
|
||||
protected static function getLogInstance()
|
||||
{
|
||||
switch (Config::get('log_record_type')) {
|
||||
case 'text':
|
||||
$instance = LogText::getInstance();
|
||||
break;
|
||||
case 'db':
|
||||
$instance = LogDb::getInstance();
|
||||
break;
|
||||
default:
|
||||
$instance = LogText::getInstance();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志写入
|
||||
*
|
||||
* @param string $content
|
||||
* 日志内容
|
||||
* @param string $level
|
||||
* 内容级别
|
||||
*/
|
||||
public static function write($content, $level = "info", $username = null)
|
||||
{
|
||||
$log = self::getLogInstance();
|
||||
$log->write($content, $level, $username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误日志快速写入,error级别
|
||||
*
|
||||
* @param string $content
|
||||
* 日志内容
|
||||
*/
|
||||
public static function error($content)
|
||||
{
|
||||
$log = self::getLogInstance();
|
||||
$log->error($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础日志快速写入, info级别
|
||||
*
|
||||
* @param string $content
|
||||
* 日志内容
|
||||
*/
|
||||
public static function info($content)
|
||||
{
|
||||
$log = self::getLogInstance();
|
||||
$log->info($content);
|
||||
}
|
||||
}
|
||||
1435
core/basic/Model.php
Normal file
1435
core/basic/Model.php
Normal file
File diff suppressed because it is too large
Load Diff
56
core/basic/Response.php
Normal file
56
core/basic/Response.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年11月5日
|
||||
* 内容输出类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
class Response
|
||||
{
|
||||
|
||||
// 根据配置文件选择
|
||||
public static function handle($data)
|
||||
{
|
||||
if (Config::get('return_data_type') == 'html') {
|
||||
print_r($data);
|
||||
} else {
|
||||
if (array_key_exists('code', $data)) {
|
||||
$code = $data['code'];
|
||||
unset($data['code']);
|
||||
self::json($code, $data);
|
||||
} else {
|
||||
self::json(1, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 服务端API返回JSON数据
|
||||
public static function json($code, $data, $tourl = null)
|
||||
{
|
||||
@ob_clean();
|
||||
$output['code'] = $code ?: 0;
|
||||
$output['data'] = $data ?: array();
|
||||
$output['tourl'] = $tourl ?: "";
|
||||
|
||||
if (defined('ROWTOTAL')) {
|
||||
$output['rowtotal'] = ROWTOTAL;
|
||||
} else {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$output['rowtotal'] = count($data);
|
||||
} else {
|
||||
$output['rowtotal'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_VERSION >= 5.4) { // 中文不编码 5.4+
|
||||
$option = JSON_UNESCAPED_UNICODE;
|
||||
} else {
|
||||
$option = JSON_HEX_TAG;
|
||||
}
|
||||
echo json_encode($output, $option);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
545
core/basic/Smtp.php
Normal file
545
core/basic/Smtp.php
Normal file
@@ -0,0 +1,545 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2018年3月21日
|
||||
* 邮件发送类
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
class Smtp
|
||||
{
|
||||
|
||||
// 邮件传输代理服务器地址
|
||||
protected $sendServer;
|
||||
|
||||
// 邮件传输代理服务器端口
|
||||
protected $port;
|
||||
|
||||
// 是否是安全连接
|
||||
protected $isSecurity;
|
||||
|
||||
// 邮件传输代理用户名
|
||||
protected $userName;
|
||||
|
||||
// 邮件传输代理密码
|
||||
protected $password;
|
||||
|
||||
// 发件人
|
||||
protected $from;
|
||||
|
||||
// 收件人
|
||||
protected $to = array();
|
||||
|
||||
// 抄送
|
||||
protected $cc = array();
|
||||
|
||||
// 秘密抄送
|
||||
protected $bcc = array();
|
||||
|
||||
// 主题
|
||||
protected $subject;
|
||||
|
||||
// 邮件正文
|
||||
protected $body;
|
||||
|
||||
// 附件
|
||||
protected $attachment = array();
|
||||
|
||||
// 调试模式
|
||||
protected $debug;
|
||||
|
||||
// 错误信息
|
||||
protected $errorMessage;
|
||||
|
||||
// 资源句柄
|
||||
protected $socket;
|
||||
|
||||
/**
|
||||
* 设置邮件传输代理,默认为安全链接
|
||||
*
|
||||
* @param string $server
|
||||
* 代理服务器的ip或者域名
|
||||
* @param string $username
|
||||
* 认证账号
|
||||
* @param string $password
|
||||
* 认证密码
|
||||
* @param int $port
|
||||
* 代理服务器的端口,smtp默认25号端口
|
||||
* @param boolean $isSecurity
|
||||
* 到服务器的连接是否为安全连接,默认false
|
||||
* @return boolean
|
||||
*/
|
||||
public function __construct($server = "", $username = "", $password = "", $port = 465, $isSecurity = true, $debug = false)
|
||||
{
|
||||
if ($server) {
|
||||
$this->sendServer = $server;
|
||||
$this->port = $port;
|
||||
$this->isSecurity = $isSecurity ? true : false;
|
||||
$this->debug = $debug;
|
||||
$this->userName = empty($username) ? "" : base64_encode($username);
|
||||
$this->password = empty($password) ? "" : base64_encode($password);
|
||||
$this->from = $username;
|
||||
} else {
|
||||
$smtp = Config::get();
|
||||
$this->sendServer = $smtp['smtp_server'];
|
||||
$this->port = $smtp['smtp_port'];
|
||||
$this->isSecurity = $smtp['smtp_ssl'] ? true : false;
|
||||
$this->debug = $debug;
|
||||
$this->userName = base64_encode($smtp['smtp_username']);
|
||||
$this->password = base64_encode($smtp['smtp_password']);
|
||||
$this->from = $smtp['smtp_username'];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置收件人,多个收件人,调用多次或用逗号隔开.
|
||||
*
|
||||
* @param string $to
|
||||
* 收件人地址
|
||||
* @return boolean
|
||||
*/
|
||||
public function setReceiver($to)
|
||||
{
|
||||
if (strpos($to, ',')) {
|
||||
$this->to = explode(',', $to);
|
||||
} else {
|
||||
$this->to[] = $to;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置抄送,多个抄送,调用多次或用逗号隔开.
|
||||
*
|
||||
* @param string $cc
|
||||
* 抄送地址
|
||||
* @return boolean
|
||||
*/
|
||||
public function setCc($cc)
|
||||
{
|
||||
if (strpos($cc, ',')) {
|
||||
$this->cc = explode(',', $cc);
|
||||
} else {
|
||||
$this->cc[] = $cc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置秘密抄送,多个秘密抄送,调用多次或用逗号隔开.
|
||||
*
|
||||
* @param string $bcc
|
||||
* 秘密抄送地址
|
||||
* @return boolean
|
||||
*/
|
||||
public function setBcc($bcc)
|
||||
{
|
||||
if (strpos($bcc, ',')) {
|
||||
$this->bcc = explode(',', $bcc);
|
||||
} else {
|
||||
$this->bcc[] = $bcc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置邮件附件,多个附件,调用多次
|
||||
*
|
||||
* @param string $file
|
||||
* 文件地址
|
||||
* @return boolean
|
||||
*/
|
||||
public function addAttachment($file)
|
||||
{
|
||||
if (! file_exists($file)) {
|
||||
$this->errorMessage = "file " . $file . " does not exist.";
|
||||
return false;
|
||||
}
|
||||
$this->attachment[] = $file;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置邮件信息
|
||||
*
|
||||
* @param string $body
|
||||
* 邮件主题
|
||||
* @param string $subject
|
||||
* 邮件主体内容,可以是纯文本,也可是是HTML文本
|
||||
* @return boolean
|
||||
*/
|
||||
public function setMail($subject, $body)
|
||||
{
|
||||
$this->subject = base64_encode($subject);
|
||||
$this->body = base64_encode($body);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function sendMail($to = '', $subject = '', $body = '')
|
||||
{
|
||||
if ($to) {
|
||||
$this->setReceiver($to);
|
||||
$this->setMail($subject, $body);
|
||||
}
|
||||
$command = $this->getCommand();
|
||||
if (! $this->socket($this->isSecurity)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($command as $value) {
|
||||
$result = $this->sendCommand($value[0], $value[1]);
|
||||
if ($result) {
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 关闭连接
|
||||
$this->close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误信息
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function error()
|
||||
{
|
||||
if (! isset($this->errorMessage)) {
|
||||
$this->errorMessage = "";
|
||||
}
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回mail命令
|
||||
*
|
||||
* @access protected
|
||||
* @return array
|
||||
*/
|
||||
protected function getCommand()
|
||||
{
|
||||
$separator = "----=_Part_" . md5($this->from . time()) . uniqid(); // 分隔符
|
||||
$command = array(
|
||||
array(
|
||||
"HELO sendmail\r\n",
|
||||
250
|
||||
)
|
||||
);
|
||||
if (! empty($this->userName)) {
|
||||
$command[] = array(
|
||||
"AUTH LOGIN\r\n",
|
||||
334
|
||||
);
|
||||
$command[] = array(
|
||||
$this->userName . "\r\n",
|
||||
334
|
||||
);
|
||||
$command[] = array(
|
||||
$this->password . "\r\n",
|
||||
235
|
||||
);
|
||||
}
|
||||
// 设置发件人
|
||||
$command[] = array(
|
||||
"MAIL FROM: <" . $this->from . ">\r\n",
|
||||
250
|
||||
);
|
||||
$header = "FROM: <" . $this->from . ">\r\n";
|
||||
// 设置收件人
|
||||
if (! empty($this->to)) {
|
||||
$count = count($this->to);
|
||||
if ($count == 1) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->to[0] . ">\r\n",
|
||||
250
|
||||
);
|
||||
$header .= "TO: <" . $this->to[0] . ">\r\n";
|
||||
} else {
|
||||
for ($i = 0; $i < $count; $i ++) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->to[$i] . ">\r\n",
|
||||
250
|
||||
);
|
||||
if ($i == 0) {
|
||||
$header .= "TO: <" . $this->to[$i] . ">";
|
||||
} elseif ($i + 1 == $count) {
|
||||
$header .= ",<" . $this->to[$i] . ">\r\n";
|
||||
} else {
|
||||
$header .= ",<" . $this->to[$i] . ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置抄送
|
||||
if (! empty($this->cc)) {
|
||||
$count = count($this->cc);
|
||||
if ($count == 1) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->cc[0] . ">\r\n",
|
||||
250
|
||||
);
|
||||
$header .= "CC: <" . $this->cc[0] . ">\r\n";
|
||||
} else {
|
||||
for ($i = 0; $i < $count; $i ++) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->cc[$i] . ">\r\n",
|
||||
250
|
||||
);
|
||||
if ($i == 0) {
|
||||
$header .= "CC: <" . $this->cc[$i] . ">";
|
||||
} elseif ($i + 1 == $count) {
|
||||
$header .= ",<" . $this->cc[$i] . ">\r\n";
|
||||
} else {
|
||||
$header .= ",<" . $this->cc[$i] . ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置秘密抄送
|
||||
if (! empty($this->bcc)) {
|
||||
$count = count($this->bcc);
|
||||
if ($count == 1) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->bcc[0] . ">\r\n",
|
||||
250
|
||||
);
|
||||
$header .= "BCC: <" . $this->bcc[0] . ">\r\n";
|
||||
} else {
|
||||
for ($i = 0; $i < $count; $i ++) {
|
||||
$command[] = array(
|
||||
"RCPT TO: <" . $this->bcc[$i] . ">\r\n",
|
||||
250
|
||||
);
|
||||
if ($i == 0) {
|
||||
$header .= "BCC: <" . $this->bcc[$i] . ">";
|
||||
} elseif ($i + 1 == $count) {
|
||||
$header .= ",<" . $this->bcc[$i] . ">\r\n";
|
||||
} else {
|
||||
$header .= ",<" . $this->bcc[$i] . ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 主题
|
||||
$header .= "Subject: =?UTF-8?B?" . $this->subject . "?=\r\n";
|
||||
if (isset($this->attachment)) {
|
||||
// 含有附件的邮件头需要声明成这个
|
||||
$header .= "Content-Type: multipart/mixed;\r\n";
|
||||
} elseif (false) {
|
||||
// 邮件体含有图片资源的,且包含的图片在邮件内部时声明成这个,如果是引用的远程图片,就不需要了
|
||||
$header .= "Content-Type: multipart/related;\r\n";
|
||||
} else {
|
||||
// html或者纯文本的邮件声明成这个
|
||||
$header .= "Content-Type: multipart/alternative;\r\n";
|
||||
}
|
||||
// 邮件头分隔符
|
||||
$header .= "\t" . 'boundary="' . $separator . '"';
|
||||
$header .= "\r\nMIME-Version: 1.0\r\n";
|
||||
// 这里开始是邮件的body部分,body部分分成几段发送
|
||||
$header .= "\r\n--" . $separator . "\r\n";
|
||||
$header .= "Content-Type:text/html; charset=utf-8\r\n";
|
||||
$header .= "Content-Transfer-Encoding: base64\r\n\r\n";
|
||||
$header .= $this->body . "\r\n";
|
||||
$header .= "--" . $separator . "\r\n";
|
||||
// 加入附件
|
||||
if (! empty($this->attachment)) {
|
||||
$count = count($this->attachment);
|
||||
for ($i = 0; $i < $count; $i ++) {
|
||||
$header .= "\r\n--" . $separator . "\r\n";
|
||||
$header .= "Content-Type: " . $this->getMIMEType($this->attachment[$i]) . '; name="=?UTF-8?B?' . base64_encode(basename($this->attachment[$i])) . '?="' . "\r\n";
|
||||
$header .= "Content-Transfer-Encoding: base64\r\n";
|
||||
$header .= 'Content-Disposition: attachment; filename="=?UTF-8?B?' . base64_encode(basename($this->attachment[$i])) . '?="' . "\r\n";
|
||||
$header .= "\r\n";
|
||||
$header .= $this->readFile($this->attachment[$i]);
|
||||
$header .= "\r\n--" . $separator . "\r\n";
|
||||
}
|
||||
}
|
||||
// 结束邮件数据发送
|
||||
$header .= "\r\n.\r\n";
|
||||
|
||||
$command[] = array(
|
||||
"DATA\r\n",
|
||||
354
|
||||
);
|
||||
$command[] = array(
|
||||
$header,
|
||||
250
|
||||
);
|
||||
$command[] = array(
|
||||
"QUIT\r\n",
|
||||
221
|
||||
);
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送命令
|
||||
*
|
||||
* @param string $command
|
||||
* 发送到服务器的smtp命令
|
||||
* @param int $code
|
||||
* 期望服务器返回的响应吗
|
||||
* @return boolean
|
||||
*/
|
||||
protected function sendCommand($command, $code)
|
||||
{
|
||||
if ($this->debug) {
|
||||
echo 'Send command:' . $command . ',expected code:' . $code . '<br />';
|
||||
}
|
||||
try {
|
||||
if (fwrite($this->socket, $command)) {
|
||||
// 当邮件内容分多次发送时,没有$code,服务器没有返回
|
||||
if (empty($code)) {
|
||||
return true;
|
||||
}
|
||||
// 读取服务器返回
|
||||
$data = trim(fread($this->socket, 1024));
|
||||
if (! mb_check_encoding($data, 'utf-8')) {
|
||||
$data = iconv('gbk', 'utf-8', $data);
|
||||
}
|
||||
if ($this->debug) {
|
||||
echo 'response:' . $data . '<br /><br />';
|
||||
}
|
||||
if ($data) {
|
||||
$pattern = "/^" . $code . "+?/";
|
||||
if (preg_match($pattern, $data)) {
|
||||
return true;
|
||||
} else {
|
||||
$this->errorMessage = $data;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->errorMessage = "Error: " . $command . " send failed";
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->errorMessage = "Error:" . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取附件文件内容,返回base64编码后的文件内容
|
||||
*
|
||||
* @param string $file
|
||||
* 文件
|
||||
* @return mixed
|
||||
*/
|
||||
protected function readFile($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
$file_obj = file_get_contents($file);
|
||||
return base64_encode($file_obj);
|
||||
} else {
|
||||
$this->errorMessage = "file " . $file . " dose not exist";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件MIME类型
|
||||
*
|
||||
* @param string $file
|
||||
* 文件
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getMIMEType($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
$mime = mime_content_type($file);
|
||||
return $mime;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立到服务器的网络连接
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function socket($ssl = true)
|
||||
{
|
||||
if ($ssl && ! extension_loaded('openssl')) {
|
||||
$this->errorMessage = '服务器未启用openssl扩展,无法使用加密方式发送邮件!';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (function_exists('stream_socket_client')) {
|
||||
|
||||
if (! function_exists('stream_socket_enable_crypto')) {
|
||||
$this->errorMessage = '服务器已经禁用stream_socket_enable_crypto函数,无法发送邮件!';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! function_exists('stream_set_blocking')) {
|
||||
$this->errorMessage = '服务器已经禁用stream_set_blocking函数,无法发送邮件!';
|
||||
return false;
|
||||
}
|
||||
|
||||
// 建立连接
|
||||
$remoteAddr = "tcp://" . $this->sendServer . ":" . $this->port;
|
||||
$this->socket = stream_socket_client($remoteAddr, $errno, $errstr, 30);
|
||||
if (! $this->socket) {
|
||||
$this->errorMessage = $errstr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置加密方式
|
||||
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
|
||||
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
|
||||
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
|
||||
}
|
||||
stream_socket_enable_crypto($this->socket, $ssl, $crypto_method);
|
||||
} elseif (function_exists('fsockopen')) {
|
||||
if ($ssl) {
|
||||
$remoteAddr = "ssl://" . $this->sendServer;
|
||||
} else {
|
||||
$remoteAddr = "tcp://" . $this->sendServer;
|
||||
}
|
||||
$this->socket = fsockopen($remoteAddr, $this->port, $errno, $errstr, 30);
|
||||
if (! $this->socket) {
|
||||
$this->errorMessage = $errstr;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->errorMessage = '服务器已经禁用stream_socket_client和fsockopen函数,请至少开启一个才能发送邮件!';
|
||||
return false;
|
||||
}
|
||||
|
||||
stream_set_blocking($this->socket, 1); // 设置阻塞模式
|
||||
$str = fread($this->socket, 1024);
|
||||
if (! preg_match("/220+?/", $str)) {
|
||||
$this->errorMessage = $str;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭安全socket
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function close()
|
||||
{
|
||||
if (isset($this->socket) && is_object($this->socket)) {
|
||||
stream_socket_shutdown($this->socket, STREAM_SHUT_WR);
|
||||
return true;
|
||||
}
|
||||
$this->errorMessage = "No resource can to be close";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
156
core/basic/Url.php
Normal file
156
core/basic/Url.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright (C)2016-2099 Hnaoyun Inc.
|
||||
* @author XingMeng
|
||||
* @email hnxsh@foxmail.com
|
||||
* @date 2017年11月6日
|
||||
* 生成指定模块下控制器方法的跳转路径
|
||||
*/
|
||||
namespace core\basic;
|
||||
|
||||
class Url
|
||||
{
|
||||
|
||||
// 存储已经生成过的地址信息
|
||||
private static $urls = array();
|
||||
|
||||
// 接收控制器方法完整访问路径,如:/home/Index/index /模块/控制器/方法/.. 路径,生成可访问地址
|
||||
public static function get($path, $suffix = null)
|
||||
{
|
||||
if (strpos($path, 'http') === 0 || ! $path) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$path = trim_slash($path); // 去除两端斜线
|
||||
|
||||
if (! isset(self::$urls[$path])) {
|
||||
|
||||
$path_arr = explode('/', $path); // 地址数组
|
||||
|
||||
if ($suffix && Config::get('app_url_type') == 2 && strrpos(strtolower($_SERVER["SCRIPT_NAME"]), 'index.php') !== false) {
|
||||
$url_ext = Config::get('url_rule_suffix'); // 伪静态文件形式
|
||||
} elseif (Config::get('app_url_type') == 1 || Config::get('app_url_type') == 2) {
|
||||
$url_ext = '/'; // pathinfo目录形式
|
||||
} else {
|
||||
$url_ext = '';
|
||||
}
|
||||
|
||||
// 路由处理
|
||||
if (! ! $routes = Config::get('url_route')) {
|
||||
foreach ($routes as $key => $value) {
|
||||
// 去除两端斜线
|
||||
$value = trim_slash($value);
|
||||
$key = trim_slash($key);
|
||||
|
||||
// 替换原来正则为替换内容
|
||||
if (preg_match_all('/\(.*?\)/', $key, $source)) {
|
||||
foreach ($source[0] as $kk => $vk) {
|
||||
$key = str_replace($vk, '$' . ($kk + 1), $key);
|
||||
}
|
||||
}
|
||||
|
||||
// 替换原来替换内容为正则
|
||||
if (preg_match_all('/\$([0-9]+)/', $value, $destination)) {
|
||||
foreach ($destination[1] as $kv => $vv) {
|
||||
$value = str_replace($destination[0][$kv], $source[0][$vv - 1], $value);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行匹配替换
|
||||
if (preg_match('{' . $value . '$}i', $path)) {
|
||||
$path = preg_replace('{' . $value . '$}i', $key, $path);
|
||||
} elseif (preg_match('{' . $value . '\/}i', $path)) {
|
||||
$path = preg_replace('{' . $value . '\/}i', $key . '/', $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 域名绑定处理匹配
|
||||
$cut_str = '';
|
||||
if (! ! $domains = Config::get('app_domain_bind')) {
|
||||
foreach ($domains as $key => $value) {
|
||||
$value = trim_slash($value); // 去除两端斜线
|
||||
if (strpos($path, $value . '/') === 0) {
|
||||
$cut_str = $value;
|
||||
$server_name = get_http_host();
|
||||
if ($server_name != $key) { // 绑定的域名与当前域名不一致时,添加主机地址
|
||||
$host = is_https() ? 'https://' . $key : 'http://' . $key;
|
||||
} else {
|
||||
$host = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 入口文件绑定匹配
|
||||
if (defined('URL_BIND') && $path_arr[0] == M) {
|
||||
$cut_str = trim_slash(URL_BIND);
|
||||
}
|
||||
|
||||
// 执行URL简化
|
||||
if ($cut_str) {
|
||||
$path = substr($path, strlen($cut_str) + 1);
|
||||
}
|
||||
|
||||
// 保存处理过的地址
|
||||
if ($path) {
|
||||
self::$urls[$path] = $host . url_index_path() . '/' . $path . $url_ext;
|
||||
} else {
|
||||
self::$urls[$path] = $host . url_index_path(); // 获取根路径前置地址
|
||||
}
|
||||
}
|
||||
return self::$urls[$path];
|
||||
}
|
||||
|
||||
// 生成前端地址
|
||||
public static function home($path, $suffix = null, $qs = null)
|
||||
{
|
||||
if (! isset(self::$urls[md5($path . $suffix . $qs)])) {
|
||||
$url_rule_type = Config::get('url_rule_type') ?: 3;
|
||||
$url_rule_suffix = Config::get('url_rule_suffix') ?: '.html';
|
||||
|
||||
if ($suffix === true) {
|
||||
$suffix = $url_rule_suffix;
|
||||
} elseif ($suffix === false) {
|
||||
$suffix = '';
|
||||
} else {
|
||||
$suffix = '/';
|
||||
}
|
||||
|
||||
$path = trim($path, '/');
|
||||
|
||||
// 去除默认模块及控制器部分
|
||||
$path = str_replace('home/Index/', '', $path);
|
||||
|
||||
if (! $path) {
|
||||
if ($url_rule_type == 1) {
|
||||
$link = SITE_INDEX_DIR . '/index.php';
|
||||
} elseif ($url_rule_type == 2) {
|
||||
$link = SITE_INDEX_DIR;
|
||||
} else {
|
||||
$link = SITE_INDEX_DIR . '/?';
|
||||
}
|
||||
} else {
|
||||
switch ($url_rule_type) {
|
||||
case '1': // 普通模式
|
||||
$qs = $qs ? "?" . $qs : '';
|
||||
$link = SITE_INDEX_DIR . '/index.php' . '/' . $path . $suffix . $qs;
|
||||
break;
|
||||
case '2': // 伪静态模式
|
||||
$qs = $qs ? "?" . $qs : '';
|
||||
$link = SITE_INDEX_DIR . '/' . $path . $suffix . $qs;
|
||||
break;
|
||||
case '3': // 兼容模式
|
||||
$qs = $qs ? "&" . $qs : '';
|
||||
$link = SITE_INDEX_DIR . '/?' . $path . $suffix . $qs;
|
||||
break;
|
||||
default:
|
||||
error('地址模式设置错误,请登录后台重新设置!');
|
||||
}
|
||||
}
|
||||
self::$urls[md5($path . $suffix . $qs)] = $link;
|
||||
}
|
||||
return self::$urls[md5($path . $suffix . $qs)];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user