attokit / attobox
简单的PHP框架,用于开发。提供HTTP请求和响应处理、路由、资源构建和基本ORM支持。
Requires
- php: >=7
- catfan/medoo: ^2.0
- guzzlehttp/guzzle: *
- matthiasmullie/minify: ^1.3
- monolog/monolog: *
README
简单的PHP框架,用于开发。提供HTTP请求和响应处理、路由、资源构建和基本ORM支持。
用法
使用composer
$ cd /your/web/root
$ composer require attokit/attobox
这将在您的网站根目录中生成vendor
文件夹。
您的网站根目录需要以下文件夹
/your/web/root
/app #different actions for your website
/assets #all static resources, e.g., images, js
/library #db, custom PHP Class files
/page #PHP pages need to show directly
/record #ORM Record Class files for each table
/route #routes file
/Web.php #basic route extended from base route
您还需要在网站根目录中以下文件
/your/web/root
/.htaccess
/index.php
.htaccess
用于Apache服务器,因为所有HTTP请求都将通过index.php
,所以...
# ./.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
index.php
是网站入口。在此文件中,您需要引入attobox框架的start.php
。
# ./index.php require_once(__DIR__."/vendor/attokit/attobox/src/start.php"); Box::start([ //all init config goes here "WEB_PROTOCOL" => "http", "WEB_DOMAIN" => "localhost", "WEB_IP" => "127.0.0.1", "WEB_DOMAIN_AJAXALLOWED" => "localhost", //... ]);
/route/Web.php
需要引入。在此文件中,您必须将所有自定义控制器定义为\Atto\Box\route\Web
类的公共方法。
# ./route/Web.php namespace Atto\Box\route; class Web extends Base { /** * this will define a controller named index * @param Array $args URI array * if request url == https://your.domain/index/foo/bar * then $args = ["foo", "bar"] */ public function index(...$args) { $rtn = [ "hello" => "world" ]; //default response type is html return "string"; //echo "string" return $rtn; //echo "{'hello': 'world'}" //you can assign response type by using query string //...?format=json return "string"; //{error:false, errors:[], data:'string'} return $rtn; //{error:false, errors:[], data: {hello: 'world'}} //or Response::json($rtn); //...?format=dump return $rtn; //var_dump($rtn) //or Response::dump($rtn); //...?format=str return $rtn; //echo "{hello:'world'}" //or Response::str($rtn); /** * !!! Use return method * !!! Response::[method] is NOT Recommand */ //you can response a PHP page like using view //page file recommand in /page, but you can put it anywhere $page = path_find("page/someView.php"); Response::page($page, [ //you can access these params in view page "rtn" => $rtn, //... ]); //you can response a code Response::code(500); //other response usage such as headers, //you can check the Response Class in // vendor/attokit/attobox/src/Response.php } }
现在您可以通过https://your.domain/index
请求您的网站。
文件夹
/app
每个/app/[appname]
文件夹需要一个PHP类文件Appname.php
。必须扩展自\Atto\Box\App
。每个/app/[appname]
的目录结构如下
/app/appname
/assets
/library
/page
/record
/Appname.php
基本上,每个应用程序都可以视为虚拟主机。这些文件夹的用法与网站根目录中的文件夹相同。
/app/appname/Appname.php
必须扩展自Atto\Box\App
,此类的每个公共方法都可以作为控制器请求,如https://your.domain/appname[/method]
# ./app/appname/Appname.php namespace Atto\Box\App; use Atto\Box\App; class Appname extends App { //default route(controller) //https://your.domain/appname public function defaultRoute(...$args) { return "appname/indexController"; } //custom route(controller) //https://your.domain/appname/foobar public function foobar(...$args) { return "appname/customController"; } }
/assets
所有静态资源都应该存储在这里。例如图像、js、css等。您可以创建任何喜欢的文件夹。
默认资源路由是src
,您可以请求存储在资产文件夹中的任何资源。如果您有一个图像文件/assets/image/img01.jpg
,则可以像这样请求它:https://your.domain/src/image/img01.jpg
。您还可以通过查询字符串稍作调整图像,例如:https://your.domain/src/image/img01.jpg?thumb=128,128
。
您可以在vendor/attokit/attobox/src/modules/resource
中查看attobox支持的Mimes。
/library
您可以在其中创建自己的类。需要命名空间Atto\Box
。如果此文件夹在/app/appname
中,则命名空间应该是Atto\Box\App\appname
。
/page
简单的PHP页面可以直接导出。可以像这样请求:https://your.domain/page/pagename
,如果在应用程序文件夹中请求,则像:https://your.domain/appname/page/pagename
。
/record
见ORM支持。
/route
自定义路由类文件。公共方法可以作为控制器请求。
特殊路由文件Web.php
、Dbm.php
、Src.php
、Uac.php
,不能使用这些文件名。
ORM支持
Attobox提供简单的ORM支持。仅适用于个人开发,此框架建议使用sqlite3进行数据库操作。
SQLite文件必须存储在/library/db
或/app/appname/library/db
中,对于高级用法,您还需要在[/app/appname]/library/db/config/dbname.json
中创建一些配置参数,此配置json文件的示例可以在vendor/attokit/attobox/src/db/config_sample.json
中找到。
Record类必须创建在[/app/appname]/record/dbname/Tablename.php
中,必须扩展自Atto\Box\Record
。RecordSet类必须在与Record类相同的php文件中定义。Record对象基于表行,RecordSet包含Record对象,它可以用作迭代器,每个项目都是一个Record对象,结果将是一个索引数组。
Record类文件如下
# ./record/usr/Usr.php namespace Atto\Box\record; use Atto\Box\Record; use Atto\Box\RecordSet; use Atto\Box\Counter; class Usr extends Record { //generator method for auto increment ids //this method only triggered before insert public function __generateUid() { //create uid //use Counter in vendor/attokit/attobox/src/modules/Counter $uidx = Counter::auto("usr_usr_uid"); $uidx = str_pad($uidx, 4, "0", STR_PAD_LEFT); $uid = "U".$uidx; return $uid; } //automatically process before/after insert/update/delete protected function beforeInsert() {return $this;} protected function afterInsert($result) {return $this;} protected function beforeUpdate() {return $this;} protected function afterUpdate($result) {return $this;} } class UsrSet extends RecordSet { //custom methods public function disabled() { //disabled all usrs in usrset $this->setField("enable", 0); $this->save(); return $this; } }
CURD
使用catfan/Medoo作为数据库驱动程序。
常见的CURD方法示例
use Atto\Box\route\Base; use Atto\Box\Db; use Atto\Box\db\Table; use Atto\Box\record\Usr; class SomeRoute extends Base { //method public function dbtest() { $usrdb = Db::load("sqlite:usr"); $usrtb = $usrdb->table("usr"); //or $usrtb = Table::load("usr/usr"); //get recordset $usrs = $usrtb->whereEnable(1)->whereName("~","jack")->limit(10)->select(); //or $usrs = $usrtb->query->apply([ "where" => [ "enable" => 1, "name[~]" => "jack", //LIKE '%jack%' ], "limit" => 10 ])->select(); //get record $usr = $usrtb->whereUid("123")->single(); //read record field value as property $uname = $usr->context["name"]; //or $uname = $usr->name; $unames = $usrset->name; //[uname, uname, ...] $extra = $usr->extra; //json to array //iterate recordset for ($i=0;$i<count($usrs);$i++) { //... } //or $rst = []; $usrs->each(function($usr) use (&$rst){ //... }); //export record object to associate array $usrinfo = $usr->export( "show", //export type: ctx, db, form, show, table true, //auto calc virtual field, defined in config.json true, //auto query related table record, defined in config.json ); //edit record $usr->setField("fieldname", "value"); $usr->save(); //edit recordset multiple edit records $usrs->setField([ "field1" => "val1", "field2" => "val2", "field3" => [ "jsonkey" => "jsonval" ] ], true); //if contains json field, need be true $usrs->save(); //insert new record $newusr = $usrtb->new([ //init record data ]); $newusr->setField([ //record data ]); $newusr->save(); //delete, will automatically trigger before/afterDelete() $newusr->del(); } }