# 安装

# 环境要求

PHP >= 7.4.0
Mysql >= 5.6
Nginx 或 Apache 建议Nginx
Nginx 或 Apache 都需要配置伪静态
启用函数 putenv proc_open(composer安装扩展时用到)

# 下载安装

  1. 下载
  1. 安装:composer install
  2. 启动:php start run
  3. 访问:http://localhost:8080

如果composer install失败,请尝试在命令行进行切换配置到国内源,命令如下
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 正式部署

一般内置服务已足以开发使用,当部署至服务器环境正式使用时需要进行如下配置

  1. 将域名解析至系统根目录
  2. 修改伪静态配置(请参考下方伪静态设置)
  3. 修改环境安全配置(请参考下方安全配置)
  4. 访问您的域名打开站点,填写数据库配置信息即可一键安装

# 伪静态(必须)

  • 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>
    

# 快速应用开发教程

  1. 创建应用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           应用描述文件
  1. 创建应用CMSphp 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           应用描述文件
  1. 应用创建完成!
    到这里已经完成创建一个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": []
}
  1. 模型 Article
<?php
namespace app\test\model;

use start\Model;

/**
 * @mixin \start\Model
 */
class Article extends Model
{
    // 这里填上数据表名即进行增删改查导出导入操作,接口、模型、服务已经自动关联上的
    protected $name = "";
    protected $with = [];
}

  1. 服务 ArticleService
<?php
namespace app\test\service;

use start\Service;

/**
 * @mixin \start\Service
 */
class ArticleService extends Service
{
    // 服务所关联模型,绑定模型后服务内置接口均是调用该模型完成数据表操作
    public $model = 'app\test\model\Article';
}

  1. 控制器 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);
    }
}
上次更新: 2/2/2023, 7:27:05 PM