├── .gitignore
├── .htaccess
├── .travis.yml
├── README.md
├── app
├── async
├── console
├── cron
├── queue
├── sql
│ └── Sql20151124180913.php
└── test.php
├── assets
├── css
│ ├── bootstrap.min.css
│ └── web.css
└── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ └── glyphicons-halflings-regular.woff
├── composer.json
├── config
├── app.php
├── async.php
├── cron.php
├── database.php
├── listener.php
├── queue.php
├── routing.php
├── rpc.php
├── session.php
└── view.php
├── cron-admin.png
├── doc
├── nginx_apache负载+反向代理.txt
├── nginx_proxy&apache.txt
└── ngnix_server_config.txt
├── group-async.png
├── index.php
├── rpc_server.php
├── server.php
└── src
├── Admin
├── Controller
│ ├── Home
│ │ └── DefaultController.php
│ └── Index
│ │ └── IndexController.php
├── Views
│ ├── Default
│ │ └── index.html.twig
│ ├── Index
│ │ └── index.html.twig
│ └── index.html.twig
└── routing.php
├── Async
└── User
│ ├── Finish
│ └── UserHandler.php
│ ├── Task
│ ├── UserAddressHandler.php
│ └── UserHandler.php
│ ├── Work
│ └── UserHandler.php
│ └── clent.php
├── Dao
├── Group
│ ├── GroupDao.php
│ └── Impl
│ │ └── GroupDaoImpl.php
└── User
│ ├── Impl
│ └── UserDaoImpl.php
│ └── UserDao.php
├── Services
├── Group
│ ├── GroupService.php
│ ├── Impl
│ │ └── GroupServiceImpl.php
│ ├── Rely
│ │ └── GroupBaseService.php
│ └── Tests
│ │ └── GroupServiceTest.php
└── User
│ ├── Impl
│ └── UserServiceImpl.php
│ ├── Rely
│ └── UserBaseService.php
│ └── UserService.php
└── Web
├── Aop
└── UserServiceAop.php
├── Command
└── LogClearCommand.php
├── Controller
├── Group
│ └── GroupController.php
└── Home
│ └── DefaultController.php
├── Cron
├── InitUser.php
├── InitUserForQueue.php
├── TestCache.php
└── TestSql.php
├── Listeners
├── KernalRequestListener.php
└── KernalResponseListener.php
├── Queue
└── UpdateUser.php
├── Views
├── Default
│ └── index.html.twig
├── Error
│ ├── 404.html.twig
│ └── 500.html.twig
├── Group
│ └── index.html.twig
├── layout.html.twig
└── public
│ ├── bottom.html.twig
│ └── head.html.twig
└── routing.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /runtime
2 | /asset/css/*
3 | /asset/fonts/*
4 | /asset/js/*
5 | /asset/img/*
6 | /asset/lib/*
7 | /vendor
8 | composer.lock
9 | */.DS_Store
10 | .DS_Store
--------------------------------------------------------------------------------
/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex index.php index.html
2 |
3 |
4 | RewriteEngine on
5 |
6 | RewriteCond %{REQUEST_FILENAME} !-d
7 |
8 | RewriteCond %{REQUEST_FILENAME} !-f
9 |
10 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
11 |
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 7.2
4 | install:
5 | - composer install
6 | script:
7 | - wget https://phar.phpunit.de/phpunit-7.0.phar
8 | - php phpunit-7.0.phar --version
9 | - sudo find -L ./app -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l
10 | - sudo find -L ./src -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l
11 | - sudo find -L ./config -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l
12 | - phpunit --bootstrap app/test.php src
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Group
2 |
3 | [详细文档](https://fucongcong.gitbooks.io/group-doc/content/)
4 |
5 | #### Group推出异步协程分支 [猛戳](https://github.com/fucongcong/Group-Co)。
6 |
7 | [](https://codeclimate.com/github/fucongcong/framework)
8 | [](https://travis-ci.org/fucongcong/Group)
9 |
10 | #### 编写此框架的意义:
11 |
12 | 首先现在流行的框架有很多。编写这个框架,其实可以说这个框架的特色,与其他框架的区别。
13 |
14 | - async多task处理任务支持,业务逻辑复杂性能差?多进程帮你解决性能问题!
15 | - 一键启动rpc服务,不与主业务冲突,轻松完成后期SOA转行,支持TCP HTTP Websocket协议
16 | - 一键启动定时任务,还在用系统自带的cronjob?(支持子进程重启,自动重启,防止内存泄漏)
17 | - 一键启动队列任务,还在自己集成队列服务?
18 | - 目录结构清晰简单
19 | - 轻量级
20 | - 包管理composer支持。
21 | - 架构可扩展性,规范的命名空间化,自己扩展类库随时可行
22 | - Debug工具条支持,找性能问题?找你的sql哪里慢了?找视图层渲染变量?找模板?debug条一览无余
23 | - laravel,symfony2有的控制台,我们也有!数据库脚本自动化!自动生成基础结构!自定义扩展控制台!
24 |
25 | ##### [使用swoole http server](https://github.com/fucongcong/ssos/blob/master/php/group%E6%A1%86%E6%9E%B6%E6%B5%8B%E8%AF%95.md)
26 |
27 | ##### 未来版本开发计划:
28 | - i18n支持
29 | - 一些常用类库的丰富(中文转拼音,验证码...)
30 |
31 |
32 | 轻量级框架,通俗易懂,快速上手。点击右上star!
33 | 联系我Email: cc@xitongxue.com,coco.fu@clothesmake.com
34 |
--------------------------------------------------------------------------------
/app/async:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | setUseIncludePath(true);
10 |
11 | define('__ROOT__', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "../");
12 |
13 | $app = new App();
14 | $app -> initSelf();
15 | $provider = new Group\Cache\FileCacheServiceProvider($app::getInstance());
16 | $provider -> register();
17 |
18 | $async = new Async($argv);
19 | $async -> run();
20 |
--------------------------------------------------------------------------------
/app/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | setUseIncludePath(true);
12 |
13 | $app = new App();
14 | $app -> initSelf();
15 | $app -> registerServices();
16 | $app -> singleton('container') -> setAppPath(__ROOT__);
17 |
18 | $console = new Console($argv);
19 | $console -> run();
--------------------------------------------------------------------------------
/app/cron:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | setUseIncludePath(true);
10 |
11 | define('__ROOT__', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "../");
12 | define('__FILEROOT__', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "../");
13 |
14 | $app = new App();
15 | $app->initSelf();
16 | $provider = new Group\Cron\FileCacheServiceProvider($app::getInstance());
17 | $provider->register();
18 |
19 | $cron = new Cron($argv, $loader);
20 | $cron -> run();
21 |
22 |
--------------------------------------------------------------------------------
/app/queue:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | setUseIncludePath(true);
10 |
11 | define('__ROOT__', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "../");
12 |
13 | $app = new App();
14 | $app -> initSelf();
15 | $provider = new Group\Cache\FileCacheServiceProvider($app::getInstance());
16 | $provider -> register();
17 |
18 | $queue = new MessageQueue($argv, $loader);
19 | $queue -> run();
--------------------------------------------------------------------------------
/app/sql/Sql20151124180913.php:
--------------------------------------------------------------------------------
1 | addSql("CREATE TABLE IF NOT EXISTS `groups` (
12 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
13 | `title` varchar(255) NOT NULL,
14 | PRIMARY KEY (`id`)
15 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;");
16 |
17 | $this -> addSql("INSERT INTO `groups` (`id`, `title`) VALUES (NULL, 'demo1');");
18 |
19 | $this->addSql("CREATE TABLE IF NOT EXISTS `user` (
20 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
21 | `nickname` varchar(255) NOT NULL DEFAULT '',
22 | `email` varchar(255) NOT NULL DEFAULT '',
23 | `password` varchar(255) NOT NULL DEFAULT '',
24 | PRIMARY KEY (`id`)
25 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;");
26 |
27 | $this->addSql("
28 | INSERT INTO `user` VALUES
29 | (1, '张三', 'zhangsan@github.com', '123456'),
30 | (2, '李四', 'lisi@github.com', '123456'),
31 | (3, '李四1', 'lisi@github.com1', '1234561'),
32 | (4, '李四2', 'lisi@github.com2', '123456'),
33 | (5, '李四3', 'lisi@github.com3', '1234561'),
34 | (6, '李四4', 'lisi@github.com4', '123456'),
35 | (7, '李四5', 'lisi@github.com5', '1234561'),
36 | (8, '李四6', 'lisi@github.com6', '123456'),
37 | (9, 'coco', 'coco@qq.com', '123456'),
38 | (10, 'coco1', 'coco1@qq.com', '123456'),
39 | (11, 'coco12', 'coco1@qq.com', '123456');
40 | ");
41 | }
42 |
43 | public function back()
44 | {
45 |
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/app/test.php:
--------------------------------------------------------------------------------
1 | setUseIncludePath(true);
9 |
10 | define('__ROOT__', realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "../");
11 |
12 | $app = new App();
13 | $app -> initSelf();
14 | $app -> registerServices();
15 | $app -> singleton('container') -> setAppPath(__ROOT__);
--------------------------------------------------------------------------------
/assets/css/web.css:
--------------------------------------------------------------------------------
1 | .container{
2 | margin-top: 20px;
3 | }
4 | .footer-autumn {
5 | background-color: #333;
6 | color: #666;
7 | text-align: center;
8 | padding: 40px 0;
9 | }
--------------------------------------------------------------------------------
/assets/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fucongcong/Group/d19e26829c46ad5847101fc72f50c2955020575b/assets/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/assets/fonts/glyphicons-halflings-regular.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/assets/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fucongcong/Group/d19e26829c46ad5847101fc72f50c2955020575b/assets/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/assets/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fucongcong/Group/d19e26829c46ad5847101fc72f50c2955020575b/assets/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "group/group",
3 | "version": "1.2.4",
4 | "description": "The Group Framework.",
5 | "keywords": ["framework", "Group"],
6 | "type": "project",
7 | "license": "MIT",
8 | "autoload": {
9 | "psr-4": {
10 | "Group\\": "core/Group/"
11 | }
12 | },
13 | "authors": [
14 | {
15 | "name": "Fu congcong",
16 | "email": "cc@xitongxue.com",
17 | "homepage": "https://github.com/fucongcong",
18 | "role": "Lead Developer"
19 | }
20 | ],
21 | "require": {
22 | "php": ">=5.3",
23 | "phpunit/phpunit": "6.5.0",
24 | "group/group-framework": "dev-master"
25 | },
26 | "repositories": {
27 | "packagist": {
28 | "type": "composer",
29 | "url": "https://packagist.phpcomposer.com"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | 'dev',
6 |
7 | //只有在dev环境下才生效。tip: swoole http server下无法正常debug
8 | 'debug' => true,
9 |
10 | //zh|en|fr...
11 | 'locale' => 'zh',
12 |
13 | //时区
14 | 'timezone' => 'Asia/Shanghai',
15 |
16 | //类的映射
17 | 'aliases' => [
18 | //like 'demo' => 'src\Service\demo',
19 | ],
20 |
21 | //系统会提前加载服务
22 | 'serviceProviders' => [
23 | 'Group\Controller\TwigServiceProvider',
24 | 'Group\Redis\RedisServiceProvider',
25 | 'Group\Session\SessionServiceProvider',
26 | 'Group\Queue\QueueServiceProvider',
27 | //'Group\Rpc\RpcServiceProvider', //开启后提供rpc服务 需要安装swoole
28 | ],
29 |
30 | //需要实例化的单例
31 | 'singles' => [
32 | ],
33 |
34 | //aop切面
35 | 'aop' => [
36 | //singles实例化的单例的别名
37 | 'src\Services\User\Impl\UserServiceImpl' => [
38 | //方法执行前
39 | 'before' => [
40 | //对应 方法 -> 通知处理
41 | 'testAop' => ['src\Web\Aop\UserServiceAop::before', 'src\Web\Aop\UserServiceAop::before']
42 | ],
43 | 'after' => [
44 | 'testAop' => 'src\Web\Aop\UserServiceAop::after'
45 | ],
46 | 'throw' => [
47 | //对应 方法 -> 通知处理
48 | 'testAop' => 'src\Web\Aop\UserServiceAop::exception'
49 | ],
50 | ],
51 | ],
52 |
53 | //扩展console命令行控制台
54 | 'console_commands' => [
55 | 'log:clear' => [
56 | 'command' => 'src\Web\Command\LogClearCommand', //执行的类
57 | 'help' => '清除日志', //提示
58 | ],
59 | ],
60 |
61 | //当使用swoole http server 时,需要指定host,port
62 | 'swoole_host' => '127.0.0.1',
63 | 'swoole_port' => 9777,
64 | 'swoole_setting' => [
65 | 'reactor_num' => 4,
66 | 'worker_num' => 2, //worker process num
67 | 'backlog' => 128, //listen backlog
68 | 'max_request' => 2000,
69 | 'heartbeat_idle_time' => 30,
70 | 'heartbeat_check_interval' => 10,
71 | 'dispatch_mode' => 3,
72 | ],
73 | ];
--------------------------------------------------------------------------------
/config/async.php:
--------------------------------------------------------------------------------
1 | [],
6 |
7 | //配置swoole异步服务器
8 | 'server' => [
9 |
10 | //可以配置多个server,注意请监听不同的端口。
11 | //serverName
12 | 'user_server' => [
13 |
14 | 'serv' => '0.0.0.0',
15 |
16 | 'port' => 9519,
17 |
18 | //server配置,请根据实际情况调整参数
19 | 'config' => [
20 | //worker进程数量
21 | 'worker_num' => 2,
22 | //最大请求数,超过后讲重启worker进程
23 | 'max_request' => 50000,
24 |
25 | //task进程数量
26 | 'task_worker_num' => 5,
27 | //task进程最大处理请求上限,超过后讲重启task进程
28 | 'task_max_request' => 50000,
29 |
30 | //打开EOF检测
31 | 'open_eof_check' => true,
32 | //设置EOF 防止粘包
33 | 'package_eof' => "\r\n",
34 | 'open_eof_split' => true, //底层拆分eof的包
35 |
36 | //心跳检测,长连接超时自动断开,秒
37 | 'heartbeat_idle_time' => 300,
38 | //心跳检测间隔,秒
39 | 'heartbeat_check_interval' => 60,
40 |
41 | //1平均分配,2按FD取摸固定分配,3抢占式分配,默认为取模
42 | 'dispatch_mode' => 3,
43 |
44 | //守护进程 此参数为true会出错
45 | 'daemonize' => false,
46 |
47 | //日志
48 | 'log_file' => 'runtime/async/user_server.log',
49 |
50 | //默认设置为CPU核数,可不配置
51 | //'reactor_num' => 2,
52 | //超过此连接数后,将拒绝后续的tcp连接
53 | //'max_conn' => 10000,
54 | //其他配置详见swoole官方配置参数列表
55 | ],
56 |
57 | 'onWork' => [
58 | [
59 | //client端发送过来的处理命令
60 | 'cmd' => 'getUserInfo',
61 | //处理器
62 | 'handler' => 'src\Async\User\Work\UserHandler',
63 | ],
64 |
65 | ],
66 |
67 | //如果work中的handler有任务丢给task
68 | 'onTask' => [
69 | [
70 | //work传来的命令
71 | 'cmd' => 'getUserInfo',
72 | //task处理器
73 | 'handler' => 'src\Async\User\Task\UserHandler',
74 | //task结束时需要执行的处理器
75 | 'onFinish' => 'src\Async\User\Finish\UserHandler',
76 | ],
77 | [
78 | //work传来的命令
79 | 'cmd' => 'getUserAddress',
80 | //task处理器
81 | 'handler' => 'src\Async\User\Task\UserAddressHandler',
82 | ],
83 |
84 | ],
85 | ],
86 | ],
87 | ];
88 |
--------------------------------------------------------------------------------
/config/cron.php:
--------------------------------------------------------------------------------
1 | true,
6 |
7 | 'timezone' => "PRC",
8 |
9 | //log路径
10 | 'log_dir' => 'runtime/cron',
11 |
12 | 'job' => [
13 |
14 | [
15 | 'name' => 'initUser',//任务名
16 | 'time' => '*/1 * * * *',//定时规则 分 小时 天 周 月
17 | 'command' => 'src\Web\Cron\InitUser',//执行的类库
18 | ],
19 |
20 | // [
21 | // 'name' => 'initUserForQueue',//任务名
22 | // 'time' => '*/2 * * * *',//定时规则 分 小时 天 周 月
23 | // 'command' => 'src\Web\Cron\initUserForQueue',//执行的类库
24 | // ],
25 | ],
26 | ];
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 | [
6 |
7 | 'default' => [
8 |
9 | "driver" => "pdo_mysql",
10 |
11 | "host" => "127.0.0.1",
12 |
13 | "port" => "3306",
14 |
15 | "dbname" => "Group",
16 |
17 | "user" => "root",
18 |
19 | "password" => "123",
20 |
21 | "charset" => "utf8",
22 | ],
23 |
24 | 'write' => [
25 |
26 | 'master1' => [
27 |
28 | "driver" => "pdo_mysql",
29 |
30 | "host" => "127.0.0.1",
31 |
32 | "port" => "3306",
33 |
34 | "dbname" => "Group1",
35 |
36 | "user" => "root",
37 |
38 | "password" => "123",
39 |
40 | "charset" => "utf8",
41 | ],
42 |
43 | 'master2' => [
44 |
45 | "driver" => "pdo_mysql",
46 |
47 | "host" => "127.0.0.1",
48 |
49 | "port" => "3306",
50 |
51 | "dbname" => "Group2",
52 |
53 | "user" => "root",
54 |
55 | "password" => "123",
56 |
57 | "charset" => "utf8",
58 | ],
59 | ],
60 |
61 | 'read' => [
62 |
63 | 'slave1' => [
64 |
65 | "driver" => "pdo_mysql",
66 |
67 | "host" => "127.0.0.1",
68 |
69 | "port" => "3306",
70 |
71 | "dbname" => "Group3",
72 |
73 | "user" => "root",
74 |
75 | "password" => "123",
76 |
77 | "charset" => "utf8",
78 | ],
79 |
80 | 'slave2' => [
81 |
82 | "driver" => "pdo_mysql",
83 |
84 | "host" => "127.0.0.1",
85 |
86 | "port" => "3306",
87 |
88 | "dbname" => "Group4",
89 |
90 | "user" => "root",
91 |
92 | "password" => "123",
93 |
94 | "charset" => "utf8",
95 | ],
96 | ],
97 | ],
98 |
99 |
100 |
101 | //redis null
102 | 'cache' => 'null',
103 |
104 | 'redis' => [
105 |
106 | 'default' => [
107 | 'host' => '127.0.0.1',
108 | 'port' => 6379,
109 | 'prefix' => 'group_',
110 | 'auth' => '',
111 | //normal 正常| persistence 持久化
112 | 'connect' => 'persistence',
113 | ],
114 |
115 | ],
116 |
117 | ];
118 |
--------------------------------------------------------------------------------
/config/listener.php:
--------------------------------------------------------------------------------
1 | [
6 |
7 | //like
8 | // [
9 | // 'eventName' => 'kernal.response',
10 | // 'listener' => 'src\web\Listeners\KernalResponseListener',
11 | // 'priority' => 10,
12 | // ]
13 |
14 | ]
15 | ];
16 |
--------------------------------------------------------------------------------
/config/queue.php:
--------------------------------------------------------------------------------
1 | [
7 | // [
8 | // 'host' => "127.0.0.1",
9 | // 'port' => 11300
10 | // ],
11 | // [
12 | // 'host' => "127.0.0.1",
13 | // 'port' => 11299
14 | // ],
15 | // ],
16 | //单机
17 | 'server' => [
18 | 'host' => "127.0.0.1",
19 | 'port' => 11300
20 | ],
21 |
22 | //log路径
23 | 'log_dir' => 'runtime/queue',
24 |
25 | //tick队列任务的频率,精确到毫秒
26 | 'timer' => 100,
27 |
28 | //类文件缓存
29 | 'class_cache' => 'runtime/queue/bootstrap.class.cache',
30 |
31 | //处理队列任务
32 | 'queue_jobs' => [
33 |
34 | [
35 | 'tube' => 'update_user_info',//队列的名称
36 | 'job' => 'src\Web\Queue\UpdateUser',//需要执行的任务
37 | //处理当前队列的进程数
38 | 'task_worker_num' => 10,
39 | ],
40 | // [
41 | // 'tube' => 'testjob3',//队列的名称
42 | // 'job' => 'src\Web\Queue\TestJob',//需要执行的任务
43 | // //处理当前队列的进程数
44 | // 'task_worker_num' => 1,
45 | // ],
46 | // [
47 | // 'tube' => 'testjob2',//队列的名称
48 | // 'job' => 'src\Web\Queue\TestJob',//需要执行的任务
49 | // //处理当前队列的进程数
50 | // 'task_worker_num' => 2,
51 | // ]
52 |
53 | ],
54 |
55 |
56 |
57 | //这里是push到队列是需要用到的参数
58 | 'priority' => 10,//该任务的重要程度,越小优先处理
59 |
60 | //延迟秒数
61 | 'delaytime' => 0,
62 |
63 | //一个任务最多可以执行的秒数
64 | 'lifetime' => 60,
65 |
66 | ];
67 |
--------------------------------------------------------------------------------
/config/routing.php:
--------------------------------------------------------------------------------
1 | [
6 | 'Admin',
7 | 'Web',
8 | //more
9 | ]
10 | ];
--------------------------------------------------------------------------------
/config/rpc.php:
--------------------------------------------------------------------------------
1 | 'runtime/rpc',
5 |
6 | 'current_server' => 'tcp',
7 |
8 | 'server' => [
9 | //连接类型
10 | 'tcp' => [
11 |
12 | 'host' => '0.0.0.0',
13 | 'port' => '9396',
14 | ]
15 | ],
16 |
17 | 'setting' => [
18 | //'daemonize' => true,
19 | 'worker_num' => 25, //worker process num
20 | 'backlog' => 128, //listen backlog
21 | 'max_request' => 2000,
22 | 'heartbeat_idle_time' => 30,
23 | 'heartbeat_check_interval' => 10,
24 | 'dispatch_mode' => 3,
25 | ],
26 | ];
--------------------------------------------------------------------------------
/config/session.php:
--------------------------------------------------------------------------------
1 | 'file',
6 |
7 | //当driver为file,可以指定存储路径
8 | 'file' => 'runtime/sessions',
9 |
10 | //当driver为redis时,可配置session前缀,注意与redis配置中的前缀不冲突
11 | 'prex' => 'session',
12 |
13 | //浏览器端session过期时间
14 | 'cookie_lifetime' => '1440',
15 |
16 | //服务器端session过期时间
17 | 'lifetime' => '3600',
18 |
19 |
20 | /****************csrf/****************/
21 | //csrf验证是否开启 true|false
22 | 'csrf_check' => true,
23 |
24 | //csrf token的密匙
25 | 'csrf_secret' => 'group',
26 | ];
27 |
--------------------------------------------------------------------------------
/config/view.php:
--------------------------------------------------------------------------------
1 | 'src',
6 |
7 | //系统错误时加载的页面,注意如果修改了模板主路径,此文件的路径也要做相应修改
8 | 'error_page' => 'Web/Views/Error/500.html.twig',
9 |
10 | //路由错误时加载的页面,注意如果修改了模板主路径,此文件的路径也要做相应修改
11 | 'notfound_page' => 'Web/Views/Error/404.html.twig',
12 |
13 | //false|true
14 | 'cache' => false,
15 |
16 | //缓存的目录
17 | 'cache_dir' => 'runtime/cache/views',
18 |
19 | //模板扩展,继承自Twig_Extension,详见twig文档
20 | 'extensions' =>[
21 | //like
22 | //'src/Demo/DemoExtension',
23 | ],
24 |
25 | ];
26 |
--------------------------------------------------------------------------------
/cron-admin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fucongcong/Group/d19e26829c46ad5847101fc72f50c2955020575b/cron-admin.png
--------------------------------------------------------------------------------
/doc/nginx_apache负载+反向代理.txt:
--------------------------------------------------------------------------------
1 | ngnix反向代理:
2 | ngnix.conf:
3 | http {
4 | #这里的负载配置有好几种方式
5 | upstream lb {
6 |
7 | #ip_hash;
8 |
9 | server 127.0.0.1:8090 weight=10;
10 |
11 | server 127.0.0.1:9090 weight=10;
12 | }
13 | }
14 |
15 |
16 | server {
17 | listen 8081;
18 |
19 | server_name www.group.com;
20 |
21 | # 程序的安装路径
22 | root /var/www/Group;
23 |
24 | # 日志路径
25 | # access_log /var/log/nginx/www.group.com.access.log;
26 | # error_log /var/log/nginx/www.group.com.error.log;
27 |
28 | location / {
29 | index index.php;
30 | try_files $uri @apache;
31 | }
32 | location @apache {
33 | proxy_set_header X-Real-IP $remote_addr;
34 | proxy_set_header X-Forwarded-For $remote_addr;
35 | proxy_set_header Host $host;
36 | rewrite ^(.*)$ /index.php/$1 last;
37 | proxy_pass http://lb;
38 | }
39 | location ~ ^/(index)\.php(/|$) {
40 | proxy_set_header X-Real-IP $remote_addr;
41 | proxy_set_header X-Forwarded-For $remote_addr;
42 | proxy_set_header Host $host;
43 | proxy_pass http://lb;
44 | }
45 |
46 | location ~* \.(jpg|jpeg|gif|png|ico|swf)$ {
47 | # 过期时间为3年
48 | expires 3y;
49 |
50 | # 关闭日志记录
51 | access_log off;
52 |
53 | # 关闭gzip压缩,减少CPU消耗,因为图片的压缩率不高。
54 | gzip off;
55 | }
56 |
57 | # 配置css/js文件
58 | location ~* \.(css|js)$ {
59 | access_log off;
60 | expires 3y;
61 | }
62 | }
63 |
64 |
65 | apache(httpd.conf):
66 |
67 | 修改Listen:8090
68 | 修改DocumentRoot
69 | 开启Rewrite模块
70 | 开启解析php模块
71 |
72 | 增加Listen:9090
73 |
74 |
75 | ServerAdmin webmaster@dummy-host.localhost
76 | DocumentRoot "/var/www/Group"
77 | ServerName localhost
78 | ServerAlias localhost
79 | ErrorLog "/private/var/log/apache2/error1_log"
80 | CustomLog "/private/var/log/apache2/access1_log" common
81 |
82 | Options Indexes FollowSymLinks
83 | AllowOverride All
84 | Order allow,deny
85 | Allow from all
86 |
87 |
88 |
89 | 最后查看8090端口的access_log和9090端口的access1_log,发现已经实现负载了
90 |
--------------------------------------------------------------------------------
/doc/nginx_proxy&apache.txt:
--------------------------------------------------------------------------------
1 | ngnix反向代理:
2 |
3 | server {
4 | listen 8081;
5 |
6 | server_name www.group.com;
7 |
8 | # 程序的安装路径
9 | root /var/www/Group;
10 |
11 | # 日志路径
12 | # access_log /var/log/nginx/www.group.com.access.log;
13 | # error_log /var/log/nginx/www.group.com.error.log;
14 |
15 | location / {
16 | index index.php;
17 | try_files $uri @apache;
18 | }
19 | location @apache {
20 | proxy_set_header X-Real-IP $remote_addr;
21 | proxy_set_header X-Forwarded-For $remote_addr;
22 | proxy_set_header Host $host;
23 | rewrite ^(.*)$ /index.php$1 last;
24 | proxy_pass http://127.0.0.1:8090;
25 | }
26 | location ~ ^/(index)\.php(/|$) {
27 | proxy_set_header X-Real-IP $remote_addr;
28 | proxy_set_header X-Forwarded-For $remote_addr;
29 | proxy_set_header Host $host;
30 | proxy_pass http://127.0.0.1:8090;
31 | }
32 |
33 | location ~* \.(jpg|jpeg|gif|png|ico|swf)$ {
34 | # 过期时间为3年
35 | expires 3y;
36 |
37 | # 关闭日志记录
38 | access_log off;
39 |
40 | # 关闭gzip压缩,减少CPU消耗,因为图片的压缩率不高。
41 | gzip off;
42 | }
43 |
44 | # 配置css/js文件
45 | location ~* \.(css|js)$ {
46 | access_log off;
47 | expires 3y;
48 | }
49 | }
50 |
51 |
52 | apache(httpd.conf):
53 |
54 | 修改Listen:8090
55 | 修改DocumentRoot
56 | 开启Rewrite模块
57 | 开启解析php模块
58 |
--------------------------------------------------------------------------------
/doc/ngnix_server_config.txt:
--------------------------------------------------------------------------------
1 | server {
2 | listen 8081;
3 |
4 | server_name www.group.com;
5 |
6 | # 程序的安装路径
7 | root /var/www/Group;
8 |
9 | # 日志路径
10 | access_log /var/log/nginx/www.group.com.access.log;
11 | error_log /var/log/nginx/www.group.com.error.log;
12 |
13 | location / {
14 | index index.php;
15 | try_files $uri @rewriteapp;
16 | }
17 |
18 | location @rewriteapp {
19 | rewrite ^(.*)$ /index.php$1 last;
20 | }
21 |
22 | location ~ ^/(index)\.php(/|$) {
23 | fastcgi_pass unix:/var/run/php5-fpm.sock;
24 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
25 | fastcgi_param PATH_INFO $fastcgi_path_info;
26 | include fastcgi_params;
27 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
28 | fastcgi_param HTTPS off;
29 | fastcgi_param HTTP_X-Sendfile-Type X-Accel-Redirect;
30 | fastcgi_buffer_size 128k;
31 | fastcgi_buffers 8 128k;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/group-async.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fucongcong/Group/d19e26829c46ad5847101fc72f50c2955020575b/group-async.png
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | setUseIncludePath(true);
7 |
8 | define('SWOOLE_HTTP', false);
9 |
10 | $kernal = new \Group\Kernal();
11 | $kernal->init(realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR, $loader);
12 |
13 |
14 |
--------------------------------------------------------------------------------
/rpc_server.php:
--------------------------------------------------------------------------------
1 | init();
10 |
--------------------------------------------------------------------------------
/server.php:
--------------------------------------------------------------------------------
1 | setUseIncludePath(true);
5 |
6 | $kernal = new \Group\SwooleKernal();
7 | $kernal->init(realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR, $loader);
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Admin/Controller/Home/DefaultController.php:
--------------------------------------------------------------------------------
1 | render('Admin/Views/index.html.twig');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Admin/Controller/Index/IndexController.php:
--------------------------------------------------------------------------------
1 | render('Admin/Views/Index/index.html.twig');
12 | }
13 |
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/Admin/Views/Default/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Admin/Views/layout.html.twig' %}
2 |
3 | {% block title %}title{% endblock %}
4 |
5 | {% block body %}
6 | hello world
7 | {% endblock %}
--------------------------------------------------------------------------------
/src/Admin/Views/Index/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Admin/Views/layout.html.twig' %}
2 |
3 | {% block title %}title{% endblock %}
4 |
5 | {% block body %}
6 | hello world
7 | {% endblock %}
--------------------------------------------------------------------------------
/src/Admin/Views/index.html.twig:
--------------------------------------------------------------------------------
1 | hello admin page
--------------------------------------------------------------------------------
/src/Admin/routing.php:
--------------------------------------------------------------------------------
1 | [
7 | 'pattern' => '/admin',
8 | 'controller' => 'Admin:Home:Default:index',
9 | ],
10 | );
11 |
--------------------------------------------------------------------------------
/src/Async/User/Finish/UserHandler.php:
--------------------------------------------------------------------------------
1 | getData();
12 | if (isset($user['cmd']) && $user['cmd'] == 'needAddress') {
13 | unset($user['cmd']);
14 | $this -> task("getUserAddress", $user);
15 | } else {
16 | return $user;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Async/User/Task/UserAddressHandler.php:
--------------------------------------------------------------------------------
1 | getData();
12 |
13 | $user = $data['data'];
14 | $user['address'] = 'HZ';
15 |
16 | return $this->finish($user);
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Async/User/Task/UserHandler.php:
--------------------------------------------------------------------------------
1 | getData();
12 | $userId = $data['data'];
13 | $user = $this->getUserService()->getUser($userId);
14 | if ($userId == 1) {
15 | $user['cmd'] = 'needAddress';
16 | }
17 |
18 | return $this->finish($user);
19 | }
20 |
21 | public function getUserService()
22 | {
23 | return $this->createService("User:User");
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Async/User/Work/UserHandler.php:
--------------------------------------------------------------------------------
1 | getData();
12 | foreach ($data as $value) {
13 | $this -> task($value);
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Async/User/clent.php:
--------------------------------------------------------------------------------
1 | $cmd, 'data' => $data]);
35 | }
36 |
37 | public static function unpack($data = [])
38 | {
39 | $data = json_decode($data, true);
40 | return [$data['cmd'], $data['data']];
41 | }
42 | }
43 |
44 | $cmd = "getUserInfo";
45 | $data = [1,2,3,4,5,6,7,8,9,10];
46 | $data = DataPack::pack($cmd, $data);
47 | var_dump(asyncJob($data, true));
--------------------------------------------------------------------------------
/src/Dao/Group/GroupDao.php:
--------------------------------------------------------------------------------
1 | tables} WHERE id=:id LIMIT 0,1";
17 | //动态参数绑定
18 | $bind = array('id' => $id);
19 | //读取默认配置
20 | //$group = $this->getDefault()->fetchOne($sql, $bind);
21 |
22 | //读取写服务器配置,如果没有指定具体参数,随机写入分配的服务器
23 | //$group = $this->getWrite('master1')->fetchOne($sql, $bind);
24 | //$group = $this->getWrite('master2')->fetchOne($sql, $bind);
25 |
26 | //读取读服务器配置,如果没有指定具体参数,随机读取分配的服务器
27 | $group = $this->getDefault()->fetchOne($sql, $bind);
28 | return $group ? $group : null;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Dao/User/Impl/UserDaoImpl.php:
--------------------------------------------------------------------------------
1 | getDefault()->createQueryBuilder();
15 | $queryBuilder
16 | ->select("*")
17 | ->from($this->table)
18 | ->where('id = ?')
19 | ->setParameter(0, $id);
20 |
21 | return $queryBuilder->execute()->fetch();
22 | }
23 |
24 | public function addUser($user)
25 | {
26 | $conn = $this->getDefault();
27 | $affected = $conn->insert($this->table, $user);
28 | if ($affected <= 0) {
29 | return fasle;
30 | }
31 | return $conn->lastInsertId();
32 | }
33 |
34 | public function getUserByName($nickname)
35 | {
36 | $queryBuilder = $this->getDefault()->createQueryBuilder();
37 | $queryBuilder
38 | ->select("*")
39 | ->from($this->table)
40 | ->where('nickname = ?')
41 | ->setParameter(0, $nickname);
42 |
43 | return $queryBuilder->execute()->fetch();
44 | }
45 |
46 | public function updateUserPassword($userId, $password)
47 | {
48 | return $this->getDefault()->update($this->table, ['password' => $password], ['id' => $userId]);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Dao/User/UserDao.php:
--------------------------------------------------------------------------------
1 | getUserService() -> getUser(1);
13 | return $this->getGroupDao()->getGroup($id);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Services/Group/Rely/GroupBaseService.php:
--------------------------------------------------------------------------------
1 | createDao("Group:Group");
11 | }
12 |
13 | public function getUserService()
14 | {
15 | return $this -> createService("User:User");
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Services/Group/Tests/GroupServiceTest.php:
--------------------------------------------------------------------------------
1 | getSpecial(48);
13 |
14 | $this->assertEquals(48, 48);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Services/User/Impl/UserServiceImpl.php:
--------------------------------------------------------------------------------
1 | getUserDao()->getUser($id);
13 | }
14 |
15 | public function addUser($user)
16 | {
17 | return $this->getUserDao()->addUser($user);
18 | }
19 |
20 | public function addUsers($users)
21 | {
22 | //Transaction
23 | $connection = app('dao')->getDefault();
24 | try {
25 | $connection->beginTransaction();
26 | foreach ($users as $user) {
27 | $this->addUser($user);
28 | }
29 | $connection->commit();
30 | } catch (\Exception $e) {
31 | $connection->rollback();
32 | }
33 | }
34 |
35 | public function getUserByName($nickname)
36 | {
37 | return $this->getUserDao()->getUserByName($nickname);
38 | }
39 |
40 | public function updateUserPassword($userId, $password)
41 | {
42 | return $this->getUserDao()->updateUserPassword($userId, $password);
43 | }
44 |
45 | public function testAop($id)
46 | {
47 | if ($id > 1) {
48 | return $id;
49 | } else {
50 | throw new \Exception("Error Id", 1);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/Services/User/Rely/UserBaseService.php:
--------------------------------------------------------------------------------
1 | createDao("User:User");
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Services/User/UserService.php:
--------------------------------------------------------------------------------
1 | getMessage()]);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Web/Command/LogClearCommand.php:
--------------------------------------------------------------------------------
1 | getArgv();
14 | echo "清除\n";
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Web/Controller/Group/GroupController.php:
--------------------------------------------------------------------------------
1 | getGroupService()->getGroup(1);
14 |
15 | return $this -> render('Web/Views/Group/index.html.twig',array(
16 | 'group' => $group));
17 | }
18 |
19 | public function addAction()
20 | {
21 | return new \Response('1');
22 | }
23 |
24 | public function testAction(Request $request, $id)
25 | {
26 | //var_dump(\Rpc::call('User:User', 'getUser', [1]));
27 |
28 | // \Log::debug('123',['user'=>1]);
29 | // \Log::debug('1233',['user'=>12]);
30 | // \Log::debug('12asdasd33',['user'=>555]);
31 | // echo $id;
32 | // echo $request->query->get('token');
33 | // echo $id; echo "
";
34 | // \Cache::set('ha',123,60);
35 | // \Cache::redis() -> set('haa',123,60);
36 | // $config = \Config::getInstance();
37 | // var_dump($config -> getConfig());
38 | //echo \Session::get('aa','123');
39 | // \Session::getFlashBag() -> setAll(['group', 'good']);
40 | // \Session::getFlashBag() -> all();
41 | // $tube = 'testjob1';
42 | // $data = '这是第一个队列任务';
43 | // \Queue::put($tube, $data);
44 | $uri = $this -> route() -> getUri();
45 | $uri = \Route::getUri();
46 |
47 | $parameters = $this -> route() -> getParameters();
48 | $parameters = \Route::getParameters();
49 |
50 | $parametersName = $this -> route() -> getParametersName();
51 |
52 | $action = $this -> route() -> getAction();
53 |
54 | $methods = $this -> route() -> getMethods();
55 |
56 | $currentMethod = $this -> route() -> getCurrentMethod();
57 |
58 | $timezone = $this -> getContainer() -> getTimezone();
59 |
60 | $environment = $this -> getContainer() -> getEnvironment();
61 |
62 | $this -> setFlashMessage('info', '消息提示!');
63 |
64 | //return new JsonResponse([$id]);
65 | //var_dump($this->getGroupService()->getGroup(2));
66 | return $this -> render('Web/Views/Group/index.html.twig',array(
67 | 'uri' => $uri,
68 | 'parameters' => $parameters,
69 | 'parametersName' => $parametersName,
70 | 'action' => $action,
71 | 'methods' => $methods,
72 | 'currentMethod' => $currentMethod,
73 | 'timezone' => $timezone,
74 | 'environment' => $environment
75 | ));
76 | }
77 |
78 | public function getGroupService()
79 | {
80 | return $this -> createService("Group:Group");
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/Web/Controller/Home/DefaultController.php:
--------------------------------------------------------------------------------
1 | getUser(1));
16 |
17 | // $server = 'user_server'; //config配置的serverName
18 | // $cmd = "getUserInfo"; // 传给server的指令
19 | // $data = [1,2,3,4,5,6,7,8,9,10]; // 数据
20 | // $needRecvData = true; //默认为true,false的话server端不会返回数据
21 | // $users = \Async::call($server, $cmd, $data, $needRecvData);
22 | // dump(json_decode($users, true));
23 | //渲染模版 模版的启始路径可在config的view.php配置
24 | //
25 | \Log::info('start', []);
26 | service("User:User")->testAop(2);
27 | service("User:User")->testAop(1);
28 | \Log::info('end', []);
29 |
30 | return $this -> render('Web/Views/Default/index.html.twig');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Web/Cron/InitUser.php:
--------------------------------------------------------------------------------
1 | 'user_'.$i.time(),
15 | 'email' => 'test@qq.com'.$i.time(),
16 | 'password' => mt_rand(0, 9999),
17 | ];
18 | }
19 |
20 | $this->getUserService()->addUsers($users);
21 | }
22 |
23 | public function getUserService()
24 | {
25 | return service("User:User");
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Web/Cron/InitUserForQueue.php:
--------------------------------------------------------------------------------
1 | 'user_'.$i.time(),
15 | 'email' => 'test@qq.com'.$i.time(),
16 | 'password' => mt_rand(0, 9999),
17 | ];
18 | }
19 |
20 | $this->getUserService()->addUsers($users);
21 |
22 | foreach ($users as $user) {
23 | $res = \Queue::put('update_user_info', json_encode($user));
24 | // if ($res) {
25 | // \Cache::getRedis()->incr('cron_count');
26 | // }
27 | }
28 | }
29 |
30 | public function getUserService()
31 | {
32 | return service("User:User");
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Web/Cron/TestCache.php:
--------------------------------------------------------------------------------
1 | querySql($sql, 'default');
15 | //注意启动cache配置 否则会出错
16 | //\Cache::set('hour', '每小时执行'.date('Y-m-d H:i:s', time()));
17 | \Log::info('nihao', ['time' => date('Y-m-d H:i:s', time())], 'cron.job');
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/src/Web/Cron/TestSql.php:
--------------------------------------------------------------------------------
1 | querySql($sql, 'default');
15 | //注意启动cache配置 否则会出错
16 | //\Cache::set('test', date('Y-m-d H:i:s', time()));
17 | \Log::info('nihao', ['time' => date('Y-m-d H:i:s', time())], 'cron.job');
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/src/Web/Listeners/KernalRequestListener.php:
--------------------------------------------------------------------------------
1 | getRequest();
20 | $app['request'] = $request;
21 | $app['env'] = app('container')->getEnvironment();
22 |
23 | $userId = $this->getUserId($request);
24 | if ($userId) {
25 | $user = $this->getUserService()->getUser($userId);
26 | if ($user) {
27 | app('container')->setContext('userId', $userId);
28 | app('container')->setContext('user', $user);
29 | $app['userId'] = $userId;
30 | $app['user'] = $user;
31 | app()->singleton('twig')->addGlobal('app', $app);
32 | return;
33 | }
34 | }
35 |
36 | app('container')->setContext('userId', 0);
37 | app('container')->setContext('user', []);
38 | $app['userId'] = 0;
39 | $app['user'] = [];
40 | app()->singleton('twig')->addGlobal('app', $app);
41 | }
42 |
43 | private function getUserId($request)
44 | {
45 | return Session::get('uid');
46 | }
47 |
48 | public function getUserService()
49 | {
50 | return app()->singleton('service')->createService("User:User");
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/src/Web/Listeners/KernalResponseListener.php:
--------------------------------------------------------------------------------
1 | jobData, true);
12 | $nickname = $data['nickname'];
13 |
14 | $user = $this->getUserService()->getUserByName($nickname);
15 | if ($user) {
16 | $res = $this->getUserService()->updateUserPassword($user['id'], "password_".$this->jobId);
17 | //if ($res) \Cache::getRedis()->incr('queue_count');
18 | } else {
19 | \Queue::put('update_user_info', $this->jobData);
20 | \Log::error($this->jobId, [$data, $user], 'queue.job');
21 | }
22 | }
23 |
24 | public function getUserService()
25 | {
26 | return service("User:User");
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Web/Views/Default/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Web/Views/layout.html.twig' %}
2 |
3 | {% block body %}
4 |
5 |
34 |
35 |
36 |
37 |
Welcome Group
38 |
马上开始
39 |
40 |
41 |
42 |
43 | {% endblock %}
--------------------------------------------------------------------------------
/src/Web/Views/Error/404.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Web/Views/layout.html.twig' %}
2 |
3 | {% block body %}
4 |
5 |
34 |
35 |
36 |
37 |
Page Not Found!
38 |
39 |
40 |
41 | {% endblock %}
--------------------------------------------------------------------------------
/src/Web/Views/Error/500.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Web/Views/layout.html.twig' %}
2 |
3 | {% block body %}
4 |
5 |
34 |
35 |
36 |
37 |
500 SERVER ERROR
38 |
39 |
40 |
41 | {% endblock %}
--------------------------------------------------------------------------------
/src/Web/Views/Group/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'Web/Views/layout.html.twig' %}
2 | {% block title%}
3 | {{group.title|default("")}}
4 | {% endblock %}
5 | {% block body %}
6 |
7 |
38 |
39 |
40 |
41 |
44 |
45 |
46 |
47 |
48 | 当前路由: {{uri}}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 获取所有参数: {{dump(parameters)}}
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 获取所有参数的名称: {{dump(parametersName)}}
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | 当前action名称: {{action}}
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 系统允许的请求方法类型: {{dump(methods)}}
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | 当前请求方法: {{dump(currentMethod)}}
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | 当前时区: {{timezone}}
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | {% endblock %}
--------------------------------------------------------------------------------
/src/Web/Views/layout.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {% block title %}{% endblock %}
12 |
13 |
14 | {# #}
15 |
16 | {% block stylesheets %}
17 |
18 |
19 |
20 | {% endblock %}
21 |
22 | {% block head_scripts %}{% endblock %}
23 | {{ debugHeader() }}
24 |
25 |
26 |
27 |
28 | {% block body %}
29 |
30 |
31 | {% endblock %}
32 |
33 | {# {% include 'web/views/public/bottom.html.twig' %} #}
34 |
35 | {{ debug() }}
36 |
37 |
--------------------------------------------------------------------------------
/src/Web/Views/public/bottom.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------
/src/Web/Views/public/head.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
24 |
--------------------------------------------------------------------------------
/src/Web/routing.php:
--------------------------------------------------------------------------------
1 | [
6 | 'pattern' => '/',
7 | 'controller' => 'Web:Home:Default:index',
8 | ],
9 |
10 | 'group'=>[
11 | 'pattern' => '/group/{id}',
12 | 'controller' => 'Web:Group:Group:test',
13 | 'methods' => 'GET',
14 | ],
15 |
16 | 'create_group'=>[
17 | 'pattern' => '/group/{id}',
18 | 'controller' => 'Web:Group:Group:add',
19 | 'methods' => 'POST',
20 | ],
21 |
22 | 'user_group'=>[
23 | 'pattern' => '/user/{id}/group/{groupId}',
24 | 'controller' => 'Web:Group:Group:test',
25 | 'methods' => 'GET',
26 | ],
27 | );
28 |
--------------------------------------------------------------------------------