diff --git a/.example.env b/.example.env index 4bc39328..c27f74ca 100644 --- a/.example.env +++ b/.example.env @@ -1 +1 @@ -APP_DEBUG = true APP_TRACE = false [APP] DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = test USERNAME = username PASSWORD = password HOSTPORT = 3306 CHARSET = utf8 DEBUG = true [LANG] default_lang = zh-cn \ No newline at end of file +APP_DEBUG = true [APP] DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = test USERNAME = username PASSWORD = password HOSTPORT = 3306 CHARSET = utf8 DEBUG = true [LANG] default_lang = zh-cn \ No newline at end of file diff --git a/.gitignore b/.gitignore index a3d20e0e..d465120e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ /.vscode /vendor *.log -thinkphp .env \ No newline at end of file diff --git a/README.md b/README.md index b540dd71..34e0e3ee 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,20 @@ ThinkPHP 6.0 > 运行环境要求PHP7.1+。 +## 主要新特性 + +* 采用`PHP7`强类型(严格模式) +* 支持更多的`PSR`规范 +* 原生多应用支持 +* 更强大和易用的查询 +* 全新的事件系统 +* 模型事件和数据库事件统一纳入事件系统 +* 模板引擎分离出核心 +* 内部功能中间件化 +* SESSION/Cookie机制改进 +* 对Swoole以及协程支持改进 +* 对IDE更加友好 +* 统一和精简大量用法 ## 安装 @@ -15,6 +29,10 @@ composer create-project topthink/think tp 6.0.*-dev composer update topthink/framework ~~~ +## 文档 + +[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content) + ## 参与开发 请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。 diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/app/BaseController.php b/app/BaseController.php new file mode 100644 index 00000000..1356436a --- /dev/null +++ b/app/BaseController.php @@ -0,0 +1,103 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace app; + +use think\App; +use think\exception\ValidateException; +use think\Validate; + +/** + * 控制器基础类 + */ +abstract class BaseController +{ + /** + * Request实例 + * @var \think\Request + */ + protected $request; + + /** + * 应用实例 + * @var \think\App + */ + protected $app; + + /** + * 是否批量验证 + * @var bool + */ + protected $batchValidate = false; + + /** + * 控制器中间件 + * @var array + */ + protected $middleware = []; + + /** + * 构造方法 + * @access public + * @param App $app 应用对象 + */ + public function __construct(App $app) + { + $this->app = $app; + $this->request = $this->app->request; + + // 控制器初始化 + $this->initialize(); + } + + // 初始化 + protected function initialize() + {} + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @return array|string|true + * @throws ValidateException + */ + protected function validate(array $data, $validate, array $message = [], bool $batch = false) + { + if (is_array($validate)) { + $v = new Validate(); + $v->rule($validate); + } else { + if (strpos($validate, '.')) { + // 支持场景 + list($validate, $scene) = explode('.', $validate); + } + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); + $v = new $class(); + if (!empty($scene)) { + $v->scene($scene); + } + } + + $v->message($message); + + // 是否批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + + return $v->failException(true)->check($data); + } + +} diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php new file mode 100644 index 00000000..375e8417 --- /dev/null +++ b/app/ExceptionHandle.php @@ -0,0 +1,68 @@ + +// +---------------------------------------------------------------------- + +namespace app; + +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\exception\Handle; +use think\exception\HttpException; +use think\exception\HttpResponseException; +use think\exception\ValidateException; +use think\Response; +use Throwable; + +/** + * 应用异常处理类 + */ +class ExceptionHandle extends Handle +{ + /** + * 不需要记录信息(日志)的异常类列表 + * @var array + */ + protected $ignoreReport = [ + HttpException::class, + HttpResponseException::class, + ModelNotFoundException::class, + DataNotFoundException::class, + ValidateException::class, + ]; + + /** + * 记录异常信息(包括日志或者其它方式记录) + * + * @access public + * @param Throwable $exception + * @return void + */ + public function report(Throwable $exception): void + { + // 使用内置的方式记录异常日志 + parent::report($exception); + } + + /** + * Render an exception into an HTTP response. + * + * @access public + * @param \think\Request $request + * @param Throwable $e + * @return Response + */ + public function render($request, Throwable $e): Response + { + // 添加自定义异常处理机制 + + // 其他错误交给系统处理 + return parent::render($request, $e); + } +} diff --git a/app/Request.php b/app/Request.php new file mode 100644 index 00000000..bf830dc6 --- /dev/null +++ b/app/Request.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- + +namespace app; + +class Request extends \think\Request +{ + +} diff --git a/app/admin/controller/Base.php b/app/admin/controller/Base.php new file mode 100644 index 00000000..273ffe1e --- /dev/null +++ b/app/admin/controller/Base.php @@ -0,0 +1,38 @@ + +// +---------------------------------------------------------------------- +namespace app\admin\controller; + +use app\BaseController; +use think\facade\View; + +/** + * @title 后台基类 + */ +class Base extends BaseController { + + public $data = array(); + public $meta = array(); + + /** + * @title 显示类 + */ + public function fetch($template){ + // 使用内置PHP模板引擎渲染模板输出 + $config = array( + 'tpl_replace_string' => array( + '__static__' => '/static', + '__img__' => '/static/admin/images', + '__css__' => '/static/admin/css', + '__js__' => '/static/admin/js', + '__public__' => '/static/admin', + ) + ); + return View::config($config)->assign($this->data)->fetch($template); + } +} diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php new file mode 100644 index 00000000..94e8f99b --- /dev/null +++ b/app/admin/controller/Index.php @@ -0,0 +1,25 @@ + +// +---------------------------------------------------------------------- +namespace app\admin\controller; + +/** + * @title 后端公共模块 + */ +class Index extends Base { + + /** + * @title 系统首页 + */ + public function index(){ + $this->data['data'] = array( + 'info' => 'ddd' + ); + return $this->fetch('', $this->data, $this->meta); + } +} diff --git a/app/admin/middleware/Admin.php b/app/admin/middleware/Admin.php new file mode 100644 index 00000000..1f57c16d --- /dev/null +++ b/app/admin/middleware/Admin.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- +namespace app\admin\middleware; + +/** + * @title 后台中间件 + */ +class Admin { + public function handle($request, \Closure $next) { + + } +} \ No newline at end of file diff --git a/app/admin/view/index/index.html b/app/admin/view/index/index.html new file mode 100644 index 00000000..535111cc --- /dev/null +++ b/app/admin/view/index/index.html @@ -0,0 +1,871 @@ + + + + + + +SentCMS后台管理系统 + + + + + + + +
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+{include file="setting"} + + + + + + + + \ No newline at end of file diff --git a/app/admin/view/setting.html b/app/admin/view/setting.html new file mode 100644 index 00000000..e8084949 --- /dev/null +++ b/app/admin/view/setting.html @@ -0,0 +1,74 @@ +
+ +
+

布局选项

+
    +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • + +
+
+

主题颜色

+ +
+
\ No newline at end of file diff --git a/app/common.php b/app/common.php new file mode 100644 index 00000000..55d22f26 --- /dev/null +++ b/app/common.php @@ -0,0 +1,12 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 diff --git a/app/event.php b/app/event.php new file mode 100644 index 00000000..26ba7eb6 --- /dev/null +++ b/app/event.php @@ -0,0 +1,27 @@ + +// +---------------------------------------------------------------------- + +// 事件定义文件 +return [ + 'bind' => [ + ], + + 'listen' => [ + 'AppInit' => [], + 'HttpRun' => [], + 'HttpEnd' => [], + 'LogLevel' => [], + 'LogWrite' => [], + ], + + 'subscribe' => [ + ], +]; diff --git a/app/index/controller/Index.php b/app/index/controller/Index.php new file mode 100644 index 00000000..c809a6f4 --- /dev/null +++ b/app/index/controller/Index.php @@ -0,0 +1,17 @@ +*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }

:)

ThinkPHP V6
13载初心不改 - 你值得信赖的PHP框架

'; + } + + public function hello($name = 'ThinkPHP6') + { + return 'hello,' . $name; + } +} diff --git a/app/middleware.php b/app/middleware.php new file mode 100644 index 00000000..e5990933 --- /dev/null +++ b/app/middleware.php @@ -0,0 +1,12 @@ + +// +---------------------------------------------------------------------- + +use app\ExceptionHandle; +use app\Request; + +// 容器Provider定义文件 +return [ + 'think\Request' => Request::class, + 'think\exception\Handle' => ExceptionHandle::class, +]; diff --git a/build.example.php b/build.example.php new file mode 100644 index 00000000..0f2222f0 --- /dev/null +++ b/build.example.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +/** + * php think build 自动生成应用的目录结构的定义示例 + */ +return [ + // 需要自动创建的文件 + '__file__' => [], + // 需要自动创建的目录 + '__dir__' => ['controller', 'model', 'view'], + // 需要自动创建的控制器 + 'controller' => ['Index'], + // 需要自动创建的模型 + 'model' => ['User'], + // 需要自动创建的模板 + 'view' => ['index/index'], +]; diff --git a/composer.json b/composer.json index 05b4556c..f0211eb8 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "require": { "php": ">=7.1.0", "topthink/framework": "6.0.*-dev", - "topthink/think-view": "^1.0" + "topthink/think-view": "^1.0", + "symfony/var-dumper":"^4.2" }, "autoload": { "psr-4": { diff --git a/config/app.php b/config/app.php index 6ea16779..e4183c69 100644 --- a/config/app.php +++ b/config/app.php @@ -17,39 +17,31 @@ use think\facade\Env; return [ // 应用地址 - 'app_host' => Env::get('app.host', ''), - // 应用Trace(环境变量优先读取) - 'app_trace' => true, + 'app_host' => Env::get('app.host', ''), // 应用的命名空间 - 'app_namespace' => '', + 'app_namespace' => '', // 是否启用路由 - 'with_route' => true, + 'with_route' => true, // 是否启用事件 - 'with_event' => true, + 'with_event' => true, // 自动多应用模式 - 'auto_multi_app' => true, + 'auto_multi_app' => true, // 应用映射(自动多应用模式有效) - 'app_map' => [], + 'app_map' => [], // 域名绑定(自动多应用模式有效) - 'domain_bind' => [], + 'domain_bind' => [], // 禁止URL访问的应用列表(自动多应用模式有效) - 'deny_app_list' => [], + 'deny_app_list' => [], // 默认应用 - 'default_app' => 'index', + 'default_app' => 'index', // 默认时区 - 'default_timezone' => 'Asia/Shanghai', - // 默认验证器 - 'default_validate' => '', - - // 默认跳转页面对应的模板文件 - 'dispatch_success_tmpl' => app()->getThinkPath() . 'tpl/dispatch_jump.tpl', - 'dispatch_error_tmpl' => app()->getThinkPath() . 'tpl/dispatch_jump.tpl', + 'default_timezone' => 'Asia/Shanghai', // 异常页面的模板文件 - 'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl', + 'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl', // 错误显示信息,非调试模式有效 - 'error_message' => '页面错误!请稍后再试~', + 'error_message' => '页面错误!请稍后再试~', // 显示错误信息 - 'show_error_msg' => false, + 'show_error_msg' => false, ]; diff --git a/config/cache.php b/config/cache.php index 985dbb1c..dc541235 100644 --- a/config/cache.php +++ b/config/cache.php @@ -8,18 +8,32 @@ // +---------------------------------------------------------------------- // | Author: liu21st // +---------------------------------------------------------------------- +use think\facade\Env; // +---------------------------------------------------------------------- // | 缓存设置 // +---------------------------------------------------------------------- return [ - // 驱动方式 - 'type' => 'File', - // 缓存保存目录 - 'path' => '', - // 缓存前缀 - 'prefix' => '', - // 缓存有效期 0表示永久缓存 - 'expire' => 0, + // 默认缓存驱动 + 'default' => Env::get('cache.driver', 'file'), + + // 缓存连接方式配置 + 'stores' => [ + 'file' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => '', + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + // 缓存标签前缀 + 'tag_prefix' => 'tag:', + // 序列化机制 例如 ['serialize', 'unserialize'] + 'serialize' => [], + ], + // 更多的缓存连接 + ], ]; diff --git a/config/database.php b/config/database.php index 48348540..18f7efe9 100644 --- a/config/database.php +++ b/config/database.php @@ -12,52 +12,58 @@ use think\facade\Env; return [ - // 数据库类型 - 'type' => Env::get('database.type', 'mysql'), - // 服务器地址 - 'hostname' => Env::get('database.hostname', '127.0.0.1'), - // 数据库名 - 'database' => Env::get('database.database', ''), - // 用户名 - 'username' => Env::get('database.username', 'root'), - // 密码 - 'password' => Env::get('database.password', ''), - // 端口 - 'hostport' => Env::get('database.hostport', '3306'), - // 连接dsn - 'dsn' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => Env::get('database.charset', 'utf8'), - // 数据库表前缀 - 'prefix' => Env::get('database.prefix', ''), - // 数据库调试模式 - 'debug' => Env::get('database.debug', true), - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', - // 是否严格检查字段是否存在 - 'fields_strict' => true, - // 数据集返回类型 - 'resultset_type' => 'array', + // 默认使用的数据库连接配置 + 'default' => Env::get('database.driver', 'mysql'), + + // 数据库连接配置信息 + 'connections' => [ + 'mysql' => [ + // 数据库类型 + 'type' => Env::get('database.type', 'mysql'), + // 服务器地址 + 'hostname' => Env::get('database.hostname', '127.0.0.1'), + // 数据库名 + 'database' => Env::get('database.database', ''), + // 用户名 + 'username' => Env::get('database.username', 'root'), + // 密码 + 'password' => Env::get('database.password', ''), + // 端口 + 'hostport' => Env::get('database.hostport', '3306'), + // 连接dsn + 'dsn' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => Env::get('database.charset', 'utf8'), + // 数据库表前缀 + 'prefix' => Env::get('database.prefix', ''), + // 数据库调试模式 + 'debug' => Env::get('database.debug', true), + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + // Builder类 + 'builder' => '', + // Query类 + 'query' => '', + // 是否需要断线重连 + 'break_reconnect' => false, + ], + + // 更多的数据库配置信息 + ], // 自动写入时间戳字段 - 'auto_timestamp' => false, + 'auto_timestamp' => 'timestamp', // 时间字段取出后的默认时间格式 'datetime_format' => 'Y-m-d H:i:s', - // 是否需要进行SQL性能分析 - 'sql_explain' => false, - // Builder类 - 'builder' => '', - // Query类 - 'query' => '\\think\\db\\Query', - // 是否需要断线重连 - 'break_reconnect' => false, - // 断线标识字符串 - 'break_match_str' => [], ]; diff --git a/config/filesystem.php b/config/filesystem.php new file mode 100644 index 00000000..a0c5744c --- /dev/null +++ b/config/filesystem.php @@ -0,0 +1,20 @@ + Env::get('filesystem.driver', 'local'), + 'disks' => [ + 'local' => [ + 'driver' => 'local', + 'root' => app()->getRuntimePath() . 'storage', + ], + 'public' => [ + 'driver' => 'local', + 'root' => app()->getRootPath() . 'public/storage', + 'url' => '/storage', + 'visibility' => 'public', + ], + // 更多的磁盘配置信息 + ], +]; diff --git a/config/lang.php b/config/lang.php index c0c3e657..7659eaa9 100644 --- a/config/lang.php +++ b/config/lang.php @@ -20,8 +20,6 @@ return [ 'default_lang' => Env::get('lang.default_lang', 'zh-cn'), // 允许的语言列表 'allow_lang_list' => [], - // 是否开启自动侦测 - 'auto_detect' => false, // 多语言自动侦测变量名 'detect_var' => 'lang', // 是否使用Cookie记录 @@ -34,4 +32,6 @@ return [ 'accept_language' => [ 'zh-hans-cn' => 'zh-cn', ], + // 是否支持语言分组 + 'allow_group' => false, ]; diff --git a/config/route.php b/config/route.php index 16cda600..1a6048d4 100644 --- a/config/route.php +++ b/config/route.php @@ -14,14 +14,8 @@ // +---------------------------------------------------------------------- return [ - // PATHINFO变量名 用于兼容模式 - 'var_pathinfo' => 's', - // 兼容PATH_INFO获取 - 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], // pathinfo分隔符 'pathinfo_depr' => '/', - // HTTPS代理标识 - 'https_agent_name' => '', // URL伪静态后缀 'url_html_suffix' => 'html', // URL普通方式参数 用于自动生成 @@ -50,16 +44,8 @@ return [ 'controller_suffix' => false, // 默认的路由变量规则 'default_route_pattern' => '[\w\.]+', - // 域名根,如thinkphp.cn - 'url_domain_root' => '', // 是否自动转换URL中的控制器和操作名 'url_convert' => true, - // 表单请求类型伪装变量 - 'var_method' => '_method', - // 表单ajax伪装变量 - 'var_ajax' => '_ajax', - // 表单pjax伪装变量 - 'var_pjax' => '_pjax', // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 'request_cache' => false, // 请求缓存有效期 diff --git a/config/session.php b/config/session.php index ae583575..7a2527a7 100644 --- a/config/session.php +++ b/config/session.php @@ -19,9 +19,9 @@ return [ // SESSION_ID的提交变量,解决flash上传跨域 'var_session_id' => '', // 驱动方式 支持file redis memcache memcached - 'type' => '', - // 是否自动开启 SESSION - 'auto_start' => true, + 'type' => 'file', // 过期时间 'expire' => 0, + // 前缀 + 'prefix' => '', ]; diff --git a/config/trace.php b/config/trace.php index 425d3014..da33a467 100644 --- a/config/trace.php +++ b/config/trace.php @@ -10,9 +10,9 @@ // +---------------------------------------------------------------------- // +---------------------------------------------------------------------- -// | Trace设置 开启 app_trace 后 有效 +// | Trace设置 开启调试模式后有效 // +---------------------------------------------------------------------- return [ - // 内置Html Console 支持扩展 + // 内置Html 支持扩展 'type' => 'Html', ]; diff --git a/web/.htaccess b/public/.htaccess similarity index 100% rename from web/.htaccess rename to public/.htaccess diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 00000000..e71815a6 Binary files /dev/null and b/public/favicon.ico differ diff --git a/web/index.php b/public/index.php similarity index 78% rename from web/index.php rename to public/index.php index dfc8ab45..e67b8d69 100644 --- a/web/index.php +++ b/public/index.php @@ -12,15 +12,6 @@ // [ 应用入口文件 ] namespace think; -// 定义应用目录 -define('BASE_PATH', substr($_SERVER['SCRIPT_NAME'], 0, -10)); - -/** - * 缓存目录设置 - * 此目录必须可写,建议移动到非WEB目录 - */ -define ( 'RUNTIME_PATH', __DIR__ . '/../data/' ); - require __DIR__ . '/../vendor/autoload.php'; // 执行HTTP应用并响应 diff --git a/web/robots.txt b/public/robots.txt similarity index 100% rename from web/robots.txt rename to public/robots.txt diff --git a/web/router.php b/public/router.php similarity index 100% rename from web/router.php rename to public/router.php diff --git a/web/static/.gitignore b/public/static/.gitignore similarity index 100% rename from web/static/.gitignore rename to public/static/.gitignore diff --git a/runtime/.gitignore b/runtime/.gitignore new file mode 100644 index 00000000..c96a04f0 --- /dev/null +++ b/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file