# 安装
# 环境要求
PHP >= 7.4.0
Mysql >= 5.6
Nginx 或 Apache 建议Nginx
Nginx 或 Apache 都需要配置伪静态
启用函数 putenv proc_open(composer安装扩展时用到)
# 下载安装
- 下载
- 点击下载 (opens new window) 纯净版(仅含框架代码,需要执行
composer install
) - 点击下载 (opens new window) 完整版(内置示例应用,已执行过
composer install
) - 命令下载
git clone git@github.com:simplestart-cn/start-cms.git
- 安装:
composer install
- 启动:
php start run
- 访问:
http://localhost:8080
如果composer install失败,请尝试在命令行进行切换配置到国内源,命令如下
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
# 正式部署
一般内置服务已足以开发使用,当部署至服务器环境正式使用时需要进行如下配置
- 将域名解析至系统根目录
- 修改伪静态配置(请参考下方伪静态设置)
- 修改环境安全配置(请参考下方安全配置)
- 访问您的域名打开站点,填写数据库配置信息即可一键安装
# 伪静态(必须)
- Niginx
- 修改nginx.conf配件文件,添加以下内容即可
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
location /web {
try_files $uri $uri/ /web/index.html;
}
- Apache
- 确保已经启用Apache的伪静态,确保目录已经配置好权限,修改配置
- 把下面的内容保存为.htaccess文件放到根目录下
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
- 把下面的内容保存到httpd.conf或者httpd-vhost.conf
<Directory "你的站点目录/web">
AllowOverride All
Allow from all
Require all granted
DirectoryIndex index.html index.php index.htm
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.html?/$1 [QSA,PT,L]
</Directory>
# 安全配置(必须)
- LNMP环境(Linux + Nginx + Mysql + PHP)
- 修改nginx.conf配件文件,添加以下内容
# 禁止访问的文件 location ~ ^/(\.env|\.user.ini|\.htaccess|\.git|\.svn|\.project) { return 404; } # 禁止访问的目录 location ~ ^/(?:build|tests|config|lib|vendor|extend)/ { deny all; }
- ...
- LAMP环境(Linux + Apache + Mysql + PHP)
- 把下面的内容保存到httpd.conf或者httpd-vhost.conf
<Files ~ ".env$"> Order allow,deny Deny from all </Files>
# 快速应用开发教程
- 创建应用
php start make:app + 应用名
- 可选项 --apidoc 生成apidoc配置文件(apidoc.json,apidoc.php,apidoc.md)
- 可选项 --common 生成公共文件(common.php,event.php,middleware.php)
php start make:app test --apidoc
// 生成如下目录
www WEB部署目录
├─app 应用目录
│ ├─test 应用名
│ | ├─controller 控制器目录
│ | ├─model 模型目录
│ | ├─service 服务目录
│ | ├─apidoc.json apidoc配置文件
│ | ├─apidoc.md apidoc描述文件
│ | ├─apidoc.php apidoc变量声明
│ | ├─app.json 应用描述文件
- 创建应用CMS
php start make:cms + 应用名@模型名
- 可选项 --apidoc(生成的controller会包含apidoc接口注释)
如需单独分别创建Controller、Model, Service 请移步浏览关于代码生成的详细说明
php start make:cms test@Article --apidoc
// 生成如下文件
www WEB部署目录
├─app 应用目录
│ ├─test 应用名
│ | ├─controller 控制器目录
│ | | ├─Article.php 接口
│ | | ├─Index.php 默认
│ | ├─model 模型目录
│ | | ├─Article.php 模型
│ | ├─service 服务目录
│ | | ├─ArticleService.php 服务
│ | ├─apidoc.json apidoc配置文件
│ | ├─apidoc.md apidoc描述文件
│ | ├─apidoc.php apidoc变量声明
│ | ├─app.json 应用描述文件
- 应用创建完成!
到这里已经完成创建一个API开发模式的应用,标准CMS(Controller+Model+Service)分层代码已生成,其中生成的主要文件如下
1.应用描述:app.json
{
"icon": "",
"name": "test",
"entry": "/test/index",
"title": "应用名称",
"summary": "应用简介",
"description": "应用详情",
"version": "v1.0.0",
"licence": "",
"author": "",
"documentation": {
"guide": "使用者手册",
"developer": "开发者手册"
},
"dependencies": [],
"startcms": {
"min-version": "v1.0.0"
},
"auth": [],
"config": []
}
- 模型 Article
<?php
namespace app\test\model;
use start\Model;
/**
* @mixin \start\Model
*/
class Article extends Model
{
// 这里填上数据表名即进行增删改查导出导入操作,接口、模型、服务已经自动关联上的
protected $name = "";
protected $with = [];
}
- 服务 ArticleService
<?php
namespace app\test\service;
use start\Service;
/**
* @mixin \start\Service
*/
class ArticleService extends Service
{
// 服务所关联模型,绑定模型后服务内置接口均是调用该模型完成数据表操作
public $model = 'app\test\model\Article';
}
- 控制器 Article
根据开发规范,控制器只允许调用服务层ArticleService,所以控制器与模型同名即可,无需后缀
test/article/info => 前端请求 axios.get('test/article/info')
test/article/page => 前端请求 axios.get('test/article/page')
test/article/create => 前端请求 axios.post('test/article/create')
test/article/update => 前端请求 axios.post('test/article/update')
...
<?php
declare (strict_types = 1);
namespace app\test\controller;
use start\Controller;
use app\test\service\ArticleService;
class Article extends Controller
{
/**
* 查看记录
* @auth
*/
public function page()
{
$input = $this->formValidate([
'keyword.default' => '',
]);
if (!empty($input['keyword'])) {
$input['title@like'] = $input['keyword'];
}
$list = ArticleService::getPage($input);
$this->success($list);
}
/**
* 获取列表
* @admin
*/
public function list()
{
$input = $this->formValidate([
'keyword.default' => '',
'status.value' => 1,
]);
if (!empty($input['keyword'])) {
$input['title@like'] = $input['keyword'];
}
$list = ArticleService::getList($input);
$this->success($list);
}
/**
* 查看详情
* @auth
*/
public function info()
{
$input = $this->formValidate([
'id.require' => 'id不能为空'
]);
$model = ArticleService::getInfo($input['id']);
$this->success($model);
}
/**
* 新增记录
* @auth
*/
public function create()
{
$input = $this->formValidate([
'title.require' => '名称不能为空',
]);
$model = ArticleService::create($input);
if ($model) {
$this->success('操作成功', $model);
} else {
$this->error('操作失败');
}
}
/**
* 更新记录
* @auth
*/
public function update()
{
$input = $this->formValidate([
'id.require' => 'id不能为空',
'title.require|ifexist' => '名称不能为空'
]);
$model = ArticleService::update($input);
if ($model) {
$this->success('操作成功', $model);
} else {
$this->error('操作失败');
}
}
/**
* 删除记录
* @auth
*/
public function remove()
{
$input = $this->formValidate([
'id.require' => 'id不能为空',
]);
if (ArticleService::remove($input['id'])) {
$this->success('操作成功');
} else {
$this->error('操作失败');
}
}
/**
* 更新状态
* @auth
*/
public function updateStatus()
{
$input = $this->formValidate([
'id.require' => 'id不能为空',
'status.require' => 'status不能为空'
], true);
if (ArticleService::update($input)) {
$this->success('操作成功');
} else {
$this->error('操作失败');
}
}
/**
* 批量更新
* @auth
*/
public function updateList()
{
$input = $this->formValidate([
'list.require' => 'list不能为空',
]);
foreach ($input['list'] as $item) {
if (!isset($item['id']) || empty($item['id'])) {
throw_error('item主键id不能为空');
}
}
if (ArticleService::saveAll($input['list'], ['status'])) {
$this->success('操作成功');
} else {
$this->error('操作失败');
}
}
/**
* 批量删除
* @auth
*/
public function removeList()
{
$input = $this->formValidate([
'list.require' => 'list不能为空',
], true);
if (ArticleService::remove($input['list'])) {
$this->success('操作成功');
} else {
$this->error('操作失败');
}
}
/**
* 批量导入
* @auth
*/
public function importList()
{
$input = $this->formValidate([
'list.require' => 'list不能为空',
]);
$data = ArticleService::import($input['list'], ['title']);
if ($data) {
$this->success('操作成功', $data);
} else {
$this->error('操作失败');
}
}
/**
* 批量导出
* @auth
*/
public function exportList()
{
$input = $this->formValidate([
'keyword.default' => '',
'status.value' => 1,
'per_page.default' => 2000
]);
if (!empty($input['keyword'])) {
$input['title@like'] = $input['keyword'];
}
$data = ArticleService::getPage($input);
$this->success($data);
}
}