# appsite
**Repository Path**: spriteShur/appsite
## Basic Information
- **Project Name**: appsite
- **Description**: AppSite 是一个以面向对象方式为主要思想的开发引擎,包括了一套可用于企业级应用的服务端程序、管理后台程序以及API接口容器和一个网站端容器。 引擎内置了众多基础核心模型和基础模块,通过相应的功能组合可以快速实现各类需求。
AppSite 可用于开发网站、服务端程序、API接口、后台管理程序或者是同时兼顾。
- **Primary Language**: PHP
- **License**: MIT
- **Default Branch**: master
- **Homepage**: https://appsite.cn
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-11-12
- **Last Updated**: 2023-11-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## AppSite
### PHP跨平台应用/网站开发引擎
简体中文 [English](README_en.md) ( 介绍、文档待补充 )
AppSite 是一个以面向对象方式为主要思想的开发引擎,包括了一套可用于企业级应用的服务端程序、管理后台程序以及API接口容器和一个网站端容器。
引擎内置了众多基础核心模型和基础模块,通过相应的功能组合可以快速实现各类需求。
AppSite 可用于开发网站、服务端程序、API接口、后台管理程序或者是同时兼顾。
### 核心模块
#### 基础对象 ASObject
AppSite使用基础对象来实现一些统一的结果处理,因为通常情况下业务型代码的返回分为 符合期望、不符合期望的两种最基本情况,ASResult即封装了这样的结果数据,使得每一步都拥有简明扼要的判断形式,同时又能够迭代式的向后传递成功/错误数据。
每一个模型类都从基类ASObject中继承了该结果属性,可以将自身的结果反馈给请求方。
```php
/**
* Sample of result returning
*/
$checkUsername = \APS\User::common()->detail( filters:['username'=>'admin'] );
if( !$checkUsername->isSucceed() ){
return $checkUsername;
}
\APS\User::common()->update( params:['groupid'=>'900'], userid: $checkUsername->getContent()['userid'] );
```
#### 数据库 ASDB
ASDB是一个用于请求mySQL数据的操作器,用于将大部分常用的数据库请求使用数组的形式来实现。
ASDB的主要常用方式,也进一步封装进了ASModel中,例如我们需要查询 文章的列表或详情,只需要在在模型实例上使用对应方法即可。
```php
/**
* Get data by ASDB methods
*/
// Get articles are featured on page 1, size 15
$getListData = \APS\ASDB::shared()->get( ['uid','title','cover'], 'item_article', ['featured'=>1], 1, 15 );
// Get article details
$getDetailData = \APS\ASDB::shared()->get( ['*'], 'item_article', ['uid'=>'sampleUID'], 1, 1 );
/**
* Get data by ASModel methods
*/
// Get articles are featured on page 1, size 15
$getArticles = \APS\Article::common()->list( ['featured'=>1], 1, 15 );
// Get article details
$getArticleDetail = \APS\Article::common()->detail( 'sampleUID' );
```
#### 基础模型 ASModel
ASModel是将数据与模型关联的一个基类。
在AppSite开发中,基础数据无需过度关注,在实际使用中,通常只需要在继承ASModel时,将对应的字段信息记录在模型属性中就可以快速调用了。
例如在Article类中,有如下定义: [Article.php](server/engine/service/Article.php)
```php
class Article extends \APS\ASModel{
const table = "item_article";
const primaryid = "uid";
const addFields = [
'uid','categoryid','areaid',...'description','introduce',
'viewtimes','sort','featured','status',
'createtime','lasttime',
];
...
const detailFields = [...];
...
const listFields = [
'uid','categoryid','areaid',...'createtime','lasttime'
];
const FilterFields = [
'uid','categoryid','areaid',...'createtime','lasttime'
];
const depthStruct = [
'gallery'=>DBField_Json,
'viewtimes'=>DBField_Int,
'featured'=>DBField_Boolean,
'createtime'=>DBField_TimeStamp,
];
const tableStruct = [
'uid' =>['type'=>DBField_String, 'len'=>8, 'nullable'=>0, 'cmt'=>'索引ID' , 'idx'=>DBIndex_Unique ],
'categoryid' =>['type'=>DBField_String, 'len'=>8, 'nullable'=>1, 'cmt'=>'分类ID' , 'idx'=>DBIndex_Index ],
'type' =>['type'=>DBField_String, 'len'=>16, 'nullable'=>1, 'cmt'=>'类型 text,cover,video,gallery...' ],
...
'title' =>['type'=>DBField_String, 'len'=>32, 'nullable'=>0, 'cmt'=>'名称名' , 'idx'=>DBIndex_FullText ],
'cover' =>['type'=>DBField_String, 'len'=>255, 'nullable'=>1, 'cmt'=>'封面' ],
'gallery' =>['type'=>DBField_Json, 'len'=>-1, 'nullable'=>1, 'cmt'=>'详情介绍' ],
...
'description' =>['type'=>DBField_String, 'len'=>255, 'nullable'=>1, 'cmt'=>'描述' , 'idx'=>DBIndex_FullText ],
'introduce' =>['type'=>DBField_RichText, 'len'=>-1, 'nullable'=>1, 'cmt'=>'详情介绍' ],
...
'viewtimes' =>['type'=>DBField_Int, 'len'=>13, 'nullable'=>0, 'cmt'=>'播放次数', 'dft'=>0, ],
'status' =>['type'=>DBField_String, 'len'=>12, 'nullable'=>0, 'cmt'=>'状态', 'dft'=>'enabled', ],
...
'createtime' =>['type'=>DBField_TimeStamp,'len'=>13, 'nullable'=>0, 'cmt'=>'创建时间', 'idx'=>DBIndex_Index, ],
'featured' =>['type'=>DBField_Boolean, 'len'=>1, 'nullable'=>0, 'cmt'=>'置顶', 'dft'=>0, 'idx'=>DBIndex_Index, ],
];
}
```
Article 在使用继承而来的方法 list() 时,就会自动使用 table, primaryid, listFields属性实现列表数据查询。
##### filterFields
用于设定查询时允许的检查字段范围(通常是建立了索引的字段,否则会降低查询效率)
##### depthStruct
用于取出数据时将数据库中字符串转换成对应数据类型
### 语义化编程(编码风格)
AppSite追求语义化编程,即代码本身具有高度语言特征,精简同时易读。
例如,在注册用户的接口文件中,我们使用以下的实现:
```php
$scope = $this->params["scope"] ?? 'common';
$registUser = User::common()->add($this->params);
if( $registUser->isSucceed() ){
$user = new User($registUser->getContent(),null,$scope);
return $user->access->authorize();
}
return $registUser;
```
#### Nginx伪静态( 网站容器、API容器、管理后台路由都需要该支持 )
```
# 图片裁切服务 Image Crop Service
location ~ \.(jpg|jpeg|png|webp)!(.*)$ {
rewrite ^(.*)\.(jpg|jpeg|png|webp)!(.*)$ $1/crop/$3.$2;
if ( -e $request_filename ) {
break;
}
rewrite ^(.*)/crop/(.*)\.(.*)$ $1&ext=.$3&file=$1.$3&method=$2;
rewrite ^(/website.*)*$ /api/common/imageCrop$1;
}
location /favicon.ico {break;}
location /website/static { break; }
location /website/theme { break; }
location /manager/theme { break; }
location /api {
rewrite ^(/api.*)*$ /api/?path=$1 break;
}
location /tester {
rewrite ^(/tester.*)*$ /tester/?path=$1 break;
}
location /manager {
rewrite ^(/manager.*)*$ /manager/?path=$1 break;
}
location /website {
rewrite ^(/website.*)*$ /website/?path=$1 break;
}
location / {
rewrite ^(/.*)*$ /website/?path=$1 break;
}
```
如果希望隐藏自己的后台系统,只需要先在后台的修改根目录配置,之后将管理后台部分的重写机制按照如下修改即可。
```
location /manager321 {
rewrite ^(/manager321.*)*$ /manager/?path=$1 break;
}
location /manager {
rewrite ^(/manager.*)*$ / break;
}
```