Initial project files: BESCMS full source
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
<?php namespace Frame;
|
||||
|
||||
use CodeIgniter\Cache\CacheFactory;
|
||||
use CodeIgniter\Cache\CacheInterface;
|
||||
use CodeIgniter\Cache\ResponseCache;
|
||||
|
||||
class Cache {
|
||||
|
||||
private $cache;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
$config = config(\Config\Cache::class);
|
||||
|
||||
|
||||
$this->cache = CacheFactory::getHandler($config);
|
||||
}
|
||||
|
||||
public function save($key, $value, $time = 3600) {
|
||||
return $this->cache->save(SYS_KEY.$key, $value, $time);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
return $this->cache->get(SYS_KEY.$key);
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
$this->cache->delete(SYS_KEY.$key);
|
||||
}
|
||||
|
||||
public function clean()
|
||||
{
|
||||
$this->cache->clean();
|
||||
}
|
||||
|
||||
public function test($name) {
|
||||
|
||||
$config = new \Config\Cache();
|
||||
$config->handler = $name;
|
||||
$adapter = new $config->validHandlers[$config->handler]($config);
|
||||
if (!$adapter->isSupported()) {
|
||||
return dr_return_data(0, dr_lang('PHP环境没有安装[%s]扩展', $config->handler));
|
||||
}
|
||||
|
||||
$adapter->initialize();
|
||||
$rt = $adapter->save('test', 'phpcmf', 60);
|
||||
if (!$rt) {
|
||||
return dr_return_data(1, dr_lang('缓存方式[%s]存储失败', $config->handler));
|
||||
} elseif ($adapter->get('test') == 'phpcmf') {
|
||||
return dr_return_data(1, dr_lang('缓存方式[%s]已生效', $config->handler));
|
||||
} else {
|
||||
return dr_return_data(0, dr_lang('缓存方式[%s]未生效', $config->handler));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php namespace Frame;
|
||||
|
||||
|
||||
// 控制器引导类
|
||||
abstract class Controller {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function set_cookie($name, $value = '', $expire = '')
|
||||
{
|
||||
if (!$name) {
|
||||
return false;
|
||||
} elseif (headers_sent()) {
|
||||
// 已经发送了头部信息
|
||||
log_message('debug', '页面存在输出内容无法设置Cookie');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算过期时间戳
|
||||
if ($expire === '' || $expire === null) {
|
||||
$ts = 0; // 会话期
|
||||
} elseif (is_numeric($expire)) {
|
||||
$expire = (int) $expire;
|
||||
// <= 10 年视为相对秒,否则视为绝对时间戳
|
||||
$ts = ($expire > 0 && $expire <= 315576000) ? time() + $expire : $expire;
|
||||
} else {
|
||||
$ts = strtotime((string) $expire) ?: 0;
|
||||
}
|
||||
|
||||
// 使用原生 setcookie(PHP 7.3+ 支持 options 数组)
|
||||
return setcookie($name, (string) $value, [
|
||||
'expires' => $ts,
|
||||
'path' => '/',
|
||||
'domain' => '', // 需要时可填写你的域名
|
||||
'secure' => false, // HTTPS 环境可设为 true
|
||||
'httponly' => true, // 防止 JS 读取
|
||||
'samesite' => 'Lax', // 可改为 'Strict' 或 'None'(None 需 secure=true)
|
||||
]);
|
||||
}
|
||||
|
||||
function get_cookie($name)
|
||||
{
|
||||
if ($name === '') {
|
||||
return null;
|
||||
}
|
||||
return array_key_exists($name, $_COOKIE) ? $_COOKIE[$name] : null;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php namespace Frame;
|
||||
|
||||
|
||||
|
||||
|
||||
// 数据库引导类
|
||||
class Model {
|
||||
|
||||
static private $db;
|
||||
static private $dbs = [];
|
||||
|
||||
static function _load_db() {
|
||||
|
||||
// 数据库
|
||||
if (self::$db) {
|
||||
return [self::$db, self::$db->DBPrefix];
|
||||
}
|
||||
|
||||
self::$db = \Config\Database::connect('default');
|
||||
|
||||
return [self::$db, self::$db->DBPrefix];
|
||||
}
|
||||
|
||||
static function _load_db_source($name) {
|
||||
|
||||
// 数据库
|
||||
if (isset(self::$dbs[$name]) && self::$dbs[$name]) {
|
||||
return [self::$dbs[$name], self::$dbs[$name]->DBPrefix];
|
||||
}
|
||||
|
||||
$dbConfig = config(\Config\Database::class);
|
||||
$dbName = $dbConfig->get_group($name);
|
||||
if ($dbName != $name) {
|
||||
log_message('error', '数据源('.$name.')加载失败');
|
||||
}
|
||||
self::$dbs[$name] = \Config\Database::connect($dbName, false);
|
||||
|
||||
return [self::$dbs[$name], self::$dbs[$name]->DBPrefix];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Frame;
|
||||
|
||||
require CMSPATH.'Core/Phpcmf.php';
|
||||
|
||||
class Run
|
||||
{
|
||||
|
||||
/**
|
||||
* App startup time.
|
||||
*
|
||||
* @var float|null
|
||||
*/
|
||||
protected $startTime;
|
||||
|
||||
/**
|
||||
* Total app execution time
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $totalTime;
|
||||
|
||||
/**
|
||||
* Main application configuration
|
||||
*
|
||||
* @var App
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Timer instance.
|
||||
*
|
||||
* @var Timer
|
||||
*/
|
||||
protected $benchmark;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->startTime = microtime(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the Benchmark
|
||||
*
|
||||
* The timer is used to display total script execution both in the
|
||||
* debug toolbar, and potentially on the displayed page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function startBenchmark()
|
||||
{
|
||||
if ($this->startTime === null) {
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
|
||||
$this->benchmark = new \CodeIgniter\Debug\Timer();
|
||||
$this->benchmark->start('total_execution', $this->startTime);
|
||||
$this->benchmark->start('bootstrap');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array with our basic performance stats collected.
|
||||
*/
|
||||
public function getPerformanceStats(): array
|
||||
{
|
||||
// After filter debug toolbar requires 'total_execution'.
|
||||
$this->totalTime = $this->benchmark->getElapsedTime('total_execution');
|
||||
|
||||
return [
|
||||
'startTime' => $this->startTime,
|
||||
'totalTime' => $this->totalTime,
|
||||
];
|
||||
}
|
||||
|
||||
public function bootWeb()
|
||||
{
|
||||
|
||||
if (CI_DEBUG) {
|
||||
$this->startBenchmark();
|
||||
\CodeIgniter\Events\Events::trigger('pre_system');
|
||||
}
|
||||
|
||||
$controller = 'Home';
|
||||
$method = 'index';
|
||||
|
||||
if (IS_ADMIN) {
|
||||
$namespace = '\\Phpcmf\\'.(APP_DIR ? 'Controllers' : 'Control').'\\Admin';
|
||||
} elseif (IS_MEMBER) {
|
||||
$namespace = '\\Phpcmf\\'.(APP_DIR == 'member' ? 'Controllers' : 'Controllers\\Member');
|
||||
} elseif (IS_API) {
|
||||
$namespace = '\\Phpcmf\\'.(APP_DIR ? 'Controllers' : 'Control').'\\Api';
|
||||
} else {
|
||||
$namespace = '\\Phpcmf\\'.(APP_DIR ? 'Controllers' : 'Control');
|
||||
}
|
||||
|
||||
isset($_GET['c']) && $_GET['c'] && is_string($_GET['c']) && $controller = (ucfirst(dr_safe_filename($_GET['c'])));
|
||||
isset($_GET['m']) && $_GET['m'] && is_string($_GET['m']) && $method = (dr_safe_filename($_GET['m']));
|
||||
|
||||
$class = $namespace.'\\'.$controller;
|
||||
if (! class_exists($class)) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forControllerNotFound($class);
|
||||
exit('<font color=red>控制器不存在</font>');
|
||||
}
|
||||
|
||||
$app = new $class;
|
||||
|
||||
if (! method_exists($app, $method)) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forMethodNotFound($class, $method);
|
||||
exit('<font color=red>方法不存在</font>');
|
||||
}
|
||||
|
||||
if (IS_POST && SYS_CSRF) {
|
||||
// SYS_CSRF
|
||||
if (in_array(\Phpcmf\Service::L('router')->uri(), \Phpcmf\Service::Filters())) {
|
||||
// 过滤白名单内的控制器
|
||||
} elseif ((defined('IS_API_HTTP') && IS_API_HTTP) || (defined('IS_API') && IS_API)) {
|
||||
// api 请求下不做验证
|
||||
} elseif (SYS_CSRF == 1 && IS_ADMIN) {
|
||||
// 宽松模式,后台不验证
|
||||
} else {
|
||||
$token = \Phpcmf\Service::L('Security')->csrf_token();
|
||||
$value = \Phpcmf\Service::L('Security')->csrf_hash();
|
||||
$post = isset($_POST[$token]) && $_POST[$token] ? dr_safe_replace($_POST[$token]) : 'null';
|
||||
if ($post == $value) {
|
||||
// 验证通过
|
||||
} else {
|
||||
// 验证失败
|
||||
$msg = SYS_DEBUG ? 'CSRF验证拦截(系统码'.$value.' / 提交码'.$post.')' : 'CSRF验证拦截';
|
||||
SYS_DEBUG && log_message('debug', $msg);
|
||||
dr_exit_msg(0, $msg, '', [
|
||||
'name' => $token,
|
||||
'value' => $value
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$app->$method();
|
||||
|
||||
if (CI_DEBUG) {
|
||||
$tool = new \CodeIgniter\Debug\Toolbar(config(\Config\Toolbar::class));
|
||||
$tool->prepare($this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php namespace Frame;
|
||||
|
||||
class Session
|
||||
{
|
||||
private $sessionStarted = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
// 配置可按需调整
|
||||
if (!headers_sent()) {
|
||||
// 避免多处输出后再启动报错
|
||||
ini_set('session.use_strict_mode', '1');
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
// 如需跨域或HTTPS,可在外部统一设置
|
||||
}
|
||||
@session_start();
|
||||
}
|
||||
$this->sessionStarted = (session_status() === PHP_SESSION_ACTIVE);
|
||||
|
||||
if (!isset($_SESSION['_tempdata']) || !is_array($_SESSION['_tempdata'])) {
|
||||
$_SESSION['_tempdata'] = [];
|
||||
}
|
||||
|
||||
$this->cleanupExpiredTempdata();
|
||||
}
|
||||
|
||||
// 设置常规会话数据(支持数组批量,或单个键值)
|
||||
public function set($key, $value = null)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $k => $v) {
|
||||
$_SESSION[$k] = $v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$_SESSION[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 设置临时数据(带过期时间,单位秒)
|
||||
public function setTempdata($key, $value, $time)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$expire = time() + max(0, (int) $time);
|
||||
$_SESSION['_tempdata'][$key] = [
|
||||
'value' => $value,
|
||||
'expire' => $expire,
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取临时数据($key 为 null 返回所有未过期临时数据)
|
||||
// 注意:读取不会删除;如需一次性使用,可调用 getTempdataOnce
|
||||
public function getTempdata($key = null)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->cleanupExpiredTempdata();
|
||||
|
||||
if ($key === null) {
|
||||
$result = [];
|
||||
foreach ($_SESSION['_tempdata'] as $k => $item) {
|
||||
$result[$k] = $item['value'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return isset($_SESSION['_tempdata'][$key]) ? $_SESSION['_tempdata'][$key]['value'] : null;
|
||||
}
|
||||
|
||||
// 一次性获取临时数据(读取后即删除)
|
||||
public function getTempdataOnce($key)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->cleanupExpiredTempdata();
|
||||
|
||||
if (!isset($_SESSION['_tempdata'][$key])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = $_SESSION['_tempdata'][$key]['value'];
|
||||
unset($_SESSION['_tempdata'][$key]);
|
||||
return $value;
|
||||
}
|
||||
|
||||
// 获取常规会话数据($key 为 null 返回所有)
|
||||
public function get($key = null)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($key === null) {
|
||||
$data = $_SESSION;
|
||||
unset($data['_tempdata']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
return $_SESSION[$key] ?? null;
|
||||
}
|
||||
|
||||
// 移除常规会话数据(支持数组)
|
||||
public function remove($key)
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $k) {
|
||||
if (array_key_exists($k, $_SESSION)) {
|
||||
unset($_SESSION[$k]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $_SESSION)) {
|
||||
unset($_SESSION[$key]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 销毁会话(可选)
|
||||
public function destroy()
|
||||
{
|
||||
if (!$this->sessionStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$_SESSION = [];
|
||||
if (ini_get('session.use_cookies')) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
|
||||
}
|
||||
session_destroy();
|
||||
$this->sessionStarted = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取 Session ID(可选)
|
||||
public function getId()
|
||||
{
|
||||
return $this->sessionStarted ? session_id() : null;
|
||||
}
|
||||
|
||||
// 私有:清理过期临时数据
|
||||
private function cleanupExpiredTempdata()
|
||||
{
|
||||
if (empty($_SESSION['_tempdata']) || !is_array($_SESSION['_tempdata'])) {
|
||||
$_SESSION['_tempdata'] = [];
|
||||
return;
|
||||
}
|
||||
|
||||
$now = time();
|
||||
foreach ($_SESSION['_tempdata'] as $k => $item) {
|
||||
if (!isset($item['expire']) || $item['expire'] <= $now) {
|
||||
unset($_SESSION['_tempdata'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user