ntch / pocoapoco
Pocoapoco Framework.
Requires
- php: ^8.0
- aws/aws-sdk-php: ^3.217
- digitickets/lalit: ^3.1
- phpmailer/phpmailer: ^6.5
- psr/http-message: ^1.0
- psr/log: ^3.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
Pocoapoco 框架
Pocoapoco框架是由國家兩廳院資訊組,針對自家開發需求撰寫而成,透過簡單路由引擎加上 MVC 架構概念,做到程式碼的輕易控管。
框架安裝及部署
- 安裝
composer:https://packagist.org/packages/ntch/pocoapoco
composer require ntch/pocoapoco
- 伺服器
伺服器使用 Nginx,其設定檔(nginx.conf)範例如下:
# 需自行調整參數 # web_basic -> 專案名稱(執行 composer 的地方) server { listen 60000; root /{web_basic}/src/public/; index index.html index.htm index.php; location /NTCH/ { alias /{web_basic}/vendor/ntch/pocoapoco/src/; location ~ \.php$ { fastcgi_pass 127.0.0.1:30001; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param PROJECT_ROOT /{web_basic}/src/; fastcgi_param ENVIRONMENT :ENV } } location / { try_files $uri /NTCH/Bootstrap.php$is_args$args; } }
目錄結構
pocoapoco(your projects)
│
└─── src(your code)
│ │
│ │─── controllers
│ │
│ │─── libraries
│ │
│ │─── log
│ │
│ │─── models
│ │
│ │─── public
│ │
│ │─── routes
│ │
│ │─── settings
│ │
│ └─── view
│
└─── vendor(require package)
│
│ composer.json
│ composer.lock
學習
router
資料夾:routes
檔案:router.php
< routes 起手式 >
use Ntch\Pocoapoco\WebRestful\Routing\Router; $router = new Router();
< 可用路由的方法 >
$router->controller($uri, $path, $file, $method); $router->view($uri, $path, $file, $data); $router->public($path, $file); $router->mix($uri, [ 'controller' => [$path, $file], 'libraries' => [$libraryName], 'log' => ['$logName'], 'mails' => ['$mailName'], 'aws' => ['$awsName'], 'models' => ['$nickname'], ]); // example $router->controller('/uri/:parameter', '/path', 'class', 'method'); $router->view('/uri/:parameter', '/path', 'class', ["pocoapoco" => "framework"]); $router->public('/path', 'index.html'); $router->mix('/uri/:parameter', [ 'controller' => ['/path', 'class', 'method'], 'libraries' => ['name'], 'mails' => ['name'], 'aws' => ['name'], 'models' => ['name'], ]);
*model 提供的類型再請參考 model 的文件
*注意:重複符合的 uri ,以上面的為主。
*建議:常用功能方法往上放,能加速執行速度。
controller
資料夾:controllers
檔案:xxx.php
< controllers 起手式 >
use Ntch\Pocoapoco\WebRestful\Controllers\Controller; # 如要導向 view 請把 Router 導入 use Ntch\Pocoapoco\WebRestful\Routing\Router; class xxx extends Controller { public function index() { $router = new Router(); $router->view(null, '/path', 'class', array("name" => "Pocoapoco")); } }
< request 提供的物件 >
# $this->request
[request] => stdClass Object
(
[uuid] => 10AEF2B9-D783-2CAA-8E07-6BDC2EF83117
[method] => GET
[uri] => Array
(
[a] => 1
[b] => 2
[c] => 3
)
[query] => Array
(
[name] => Pocoapoco
)
[input] =>
[attribute] => Array
(
)
[authorization] => Array
(
)
[cookies] => Array
(
[php] => omfb5668s9i952d05gdbckp1ej
)
[files] => Array
(
)
[client] => Array
(
[ip] => 172.0.0.0
[port] => 60505
)
[time] => Array
(
[unix] => 1643257668.4144
[date] => 2022-01-01
[time] => 12:00:00
)
[headers] => Array
(
)
)
setting
資料夾:settings
檔案:xxx.ini
- 檔案讀取順序:先讀取 settings 根目錄,再依據 Nginx ENVIRONMENT 設定讀取,若名稱重複做覆蓋。
- libraries.ini:libraries 命名與載入層級設定,實際引入由 router 載入
- mails.ini:郵件參數設定
- aws.ini:aws iam 參數設定
- error.ini:開發與正式上線參數設定
- log.ini:log 參數設定
- project.ini:專案共用參數設定
- models.ini:資料庫參數設定
< settings 起手式 >
# libraries.ini [name] path = /path(要載入至哪個路徑下的所有檔案) models = nickname (models.ini) mails = server_name (mail.ini) aws = user (aws.ini) # 檔名:mails.ini [name] Host = pocoapoco.com Port = 25 Username = pocoapoco Password = xxxxxxxxx SMTPAuth = true|false SMTPSecure = tls|ssl CharSet = utf-8 SMTPDebug = 1|0 Timeout = 5 # 檔名:aws.ini [name] version = latest region = ap-northeast-1 key = pocoapoco secret = xxxxxxxxx # 檔名:error.ini [MAIN] debug = 1|0 page_4xx = 4xx.html page_5xx = 5xx.html mail_from = server@pocoapoco.com mail_to = royhylee@mail.npac-ntch.org:ROY mail_server = mail.ini-name [PAGE] E_EXCEPTION = 1 E_ERROR = 1 E_WARNING = 0 E_PARSE = 1 E_NOTICE = 0 E_CORE_ERROR = 1 E_CORE_WARNING = 1 E_COMPILE_ERROR = 1 E_COMPILE_WARNING = 1 E_USER_ERROR = 1 E_STRICT = 1 E_RECOVERABLE_ERROR = 1 E_DEPRECATED = 1 E_USER_DEPRECATED = 1 E_ALL = 1 [MAIL] E_EXCEPTION = 1 E_ERROR = 1 E_WARNING = 1 E_PARSE = 1 E_NOTICE = 1 E_CORE_ERROR = 1 E_CORE_WARNING = 1 E_COMPILE_ERROR = 1 E_COMPILE_WARNING = 1 E_USER_ERROR = 1 E_STRICT = 1 E_RECOVERABLE_ERROR = 1 E_DEPRECATED = 1 E_USER_DEPRECATED = 1 E_ALL = 1 # 檔名:log.ini [name] file = class folder = /path(絕對路徑) # 檔名:project.ini [name] key = value # 檔名:models.ini [server_name] type = server driver = oracle|mysql|mssql|postgres ip = xx.xx.xx.xx port = 1521 sid = oracle user = pocoapoco password = xxxxxxxxx path = /path class = class [tb_name] type = table server = server_name schema = schema_name table = tb path = /path class = class
library
資料夾:libraries
檔案:xxx.php
< library 起手式 >
# 依據 PSR-4 命名規則,給予路徑 namespace libraries\la\lb\lc; class xxx { public function index() { echo 'library import success!' . PHP_EOL; } }
< setting 定義別名 >
[lib] path = /la
< router 檔案引入至 controller 使用 >
$router->mvc('/uri', [ 'controller' => ['/path', 'class'], 'libraries' => ['lib'] ]);
< controller 使用 >
use Ntch\Pocoapoco\WebRestful\Controllers\Controller; use la\lb\lc\xxx; class test extends Controller { public function index() { $lib = new xxx(); $lib->index(); } }
model
資料夾:models
檔案:xxx.php
*提供類型:Oracle、Mysql、Mssql、Postgres
< model 起手式 >
use Ntch\Pocoapoco\WebRestful\Models\Model; class model_demo extends Model { public function schema() { $schema['COLUMN_NAME'] = [ 'DATA_TYPE' => '', 'DATA_SIZE' => '', 'NULLABLE' => '', 'DATA_DEFAULT' => '', 'KEY_TYPE' => '', 'COMMENT' => '', 'SYSTEM_SET' => '' ]; return $schema; } }
-
Oracle 提供的 DATA_TYPE
- CHAR
- NCHAR
- VARCHAR2
- NVARCHAR2
- NCLOB
- FLOAT
- NUMBER
- DATE
- TIMESTAMP
- TIMESTAMP WITH TIME ZONE
- TIMESTAMP WITH LOCAL TIME ZONE
-
Mysql 提供的 DATA_TYPE
- char
- varchar
- tinyint
- smallint
- mediumint
- bigint
- int
- float
- decimal
- timestamp
- datetime
- date
- time
- year
-
Mssql 提供的 DATA_TYPE
- char
- varchar
- nchar
- nvarchar
- tinyint
- smallint
- bigint
- int
- float
- decimal
- datetime
- date
-
Postgres 提供的 DATA_TYPE
- char
- varchar
- uuid
- bool
- date
- inet
- json
- float
- decimal
- integer
- bigint
- smallint
- timestamp
- timestamptz
- xml
< setting 設定檔定義別名 >
[server_name] type = server driver = oracle|mysql|mssql|postgres ip = xx.xx.xx.xx port = 1521 sid = oracle user = pocoapoco password = xxxxxxxxx path = /path class = class [tb_name] type = table server = server_name schema = schema_name table = tb path = /path class = class
< router 檔案引入至 controller 使用 >
$router->mvc('/uri', [ 'controller' => ['/path', 'class'], 'models' => ['nickname'] ]);
*server 為撈出該 database 所有 table,非必要引入
< controller 使用 >
use Ntch\Pocoapoco\WebRestful\Controllers\Controller; class test extends Controller { public function index() { # model 導入 $model = $this->model['nickname']; # ORM 架構 # createTable 範例 $sql = $model->createTable(); # commentTable 範例 $sql = $model->commentTable(); # select 範例 $data = $model->select(['a', 'b', 'SUM(c)' => 'c'])-> where(['b' => 1])->groupby(['a', 'b'])-> orderby(['a'])->query(); # insert 範例 $data = $model->insert()->values(['a' => 1])->query(); # update 範例 $data = $model->update()->set(['a' => 1])->where(['b' => 2])->query(); # delete 範例 $data = $model->delete()->where(['a' => [1, '>']])->query(); # merge 範例 - 僅提供 Oracle 使用 $data = $model->merge()->using('user', 'table')->on("a", "b")-> matched()->update()->set(['c' => 'c', 'd' => 'd'])-> not()->insert()->value()->query(); # commit 範例 $model->commit(); # rollback 範例 $model->rollback(); # 筆數限制 - 第 5 筆開始顯示 8 筆 # Oracle 範例 - 若兩個方法皆要使用 offset() limit() 順序可顛倒 $data = $model->select()->offset(5)->limit(8)->query(); # Mysql 範例 - 若兩個方法皆要使用 limit() offset() 順序可顛倒 $data = $mysql->select()->limit(8)->offset(5)->query(); # Mssql 範例 - 兩種方法 $data = $mssql->select()->top(8)->query(); $data = $mssql->select()->groupby()->offset(5)->fetch(8)->query(); # Postgres 範例 - 若兩個方法皆要使用 limit() offset() 順序可顛倒 $data = $postgres->select()->limit(8)->offset(5)->query(); } }
- 通用方法
- createTable()
- commentTable() // Mysql 不適用
- insert()
- values($values)
- delete()
- update()
- set($set)
- select($select)
- select_distinct($select)
- where($where)
- orderby($orderby)
- groupby($groupby)
- query()
- query_pass() // 不檢查 model schema
- commit()
- rollback()
- keyName($keyName) (指定 key 欄位)
- dataBind() // 將 array key 與 colname 相同的值合併至 model
log
< log 使用 >
# 依據 PSR-3 規則,給予層級 $this->log($level, $message, $info); // example $this->log('INFO', 'message', ['name' => 'pocoapoco']);
< mail 使用 >
$res = $mailer->header($header)-> from($from)-> to($to)-> subject($subject)-> content($source, $type, $content, $data)-> send(); // example $mailer = $this->mail['mailer']; $header = ['ID' => 'xxxxxxxx']; $from = ['server@pocoapoco.com' => 'POCOAPOCO']; $to = ['royhylee@mail.npac-ntch.org' => 'ROY LEE']; $res = $res = $mailer->header($header)-> from($from)-> to($to)-> subject('test')-> content('local', 'html', '/path/error.php', ['error' => 'message'])-> send();
- 方法
- header($header)
- from($from)
- to($to)
- subject($subject)
- content($source, $type, $content, $data)
- attachment($source, $attachment)
- image($path, $cid, $name)
- send()
aws
< aws 使用 >
$aws = $this->aws['name']; // example $aws->s3_exist('bucket', '/aws_path', 'aws_file.txt', ['key' => 'xxxxxxxxxxxx', 'md5' => 'oooooooooooo']); $aws->s3_list('bucket'); $aws->s3_upload('bucket', '/aws_path', 'aws_file.txt', '/local_path', 'local_file.txt', 2, 1) $aws->s3_read('bucket', '/aws_path', 'aws_file.txt', ['key' => 'xxxxxxxxxxxx', 'md5' => 'oooooooooooo']) $aws->s3_download('bucket', '/aws_path', 'aws_file.txt', '/local_path', 'local_file.txt', ['key' => 'xxxxxxxxxxxx', 'md5' => 'oooooooooooo']) $aws->s3_copy('source_bucket', '/source_path', 'source_file.txt', 'target_bucket', '/target_path', 'target_file.txt') $aws->s3_delete('bucket', '/aws_path', 'aws_file.txt', ['key' => 'xxxxxxxxxxxx', 'md5' => 'oooooooooooo']); $aws->s3_get('bucket', '/aws_path', 'aws_file.txt', 5, ['key' => 'xxxxxxxxxxxx', 'md5' => 'oooooooooooo']);
- 方法
- s3_exist($bucket, $awsPath, $awsFile, $sseKey)
- s3_list($bucket)
- s3_upload($bucket, $awsPath, $awsFile, $localPath, $localFile, $security, $download)
- s3_read($bucket, $awsPath, $awsFile, $sseKey)
- s3_download($bucket, $awsPath, $awsFile, $localPath, $localFile, sseKey)
- s3_copy($sourceBucket, $sourcePath, $sourceFile, $targetBucket, $targetPath, $targetFile)
- s3_delete($bucket, $awsPath, $awsFile, $sseKey)
- s3_get($bucket, $awsPath, $awsFile, $effectTime, $sseKey)