kit-cosovan / base-frame
FrameworkPHP是一个轻量级的PHP框架,专为快速构建Web应用而设计。该框架提供了简单易用的工具,用于处理路由、数据库、模板等Web开发的各个方面。
v1.0
2024-07-22 18:08 UTC
Requires
- ext-pdo: *
- phpmailer/phpmailer: ^6.9
- symfony/var-dumper: ^6.0
README
基础框架是一个轻量级且灵活的PHP框架,提供了快速开发Web应用所需的所有工具。它已预先配置,您可以立即开始创建自己的视图、模型和控制器。
安装
使用Composer
您可以通过Composer安装基础框架。将以下行添加到您的composer.json
文件的require
部分
"kit-cosovan/base-frame": "^1.0"
然后运行
composer install
核心组件
index.php
:此文件已包含基本的框架设置,是您应用程序的入口点。您无需修改它即可开始开发。app/Controllers
:存储控制器文件的目录。app/Models
:存储模型的目录。app/Views
:存储视图的目录,包括错误和模板文件夹。config
:框架设置,包括路由和初始化。core
:框架的核心类,如Application、Controller、Database等。helpers
:可在整个应用程序中使用的实用函数。
入门指南
- 创建控制器:导航到
app/Controllers
目录并创建新的控制器文件以处理请求。 - 创建模型:转到
app/Models
目录并创建与数据库交互的模型。 - 创建视图:前往
app/Views
目录并创建用于显示数据的视图文件。 - 配置路由:编辑
config/routes.php
文件以设置应用程序的路由。
使用示例
应用程序方法
应用程序有三个主要方法。
- 方法
run
:启动应用程序。
$app = new \PHPFramework\Application(); $app->run();
- 方法
get
:允许您从容器中获取数据。它接受两个参数get($key, $default)
。如果按键不存在数据,则返回第二个参数传递的值,或返回null
。
$app = new \PHPFramework\Application(); $app->get('data');
- 方法
set
:允许您将数据放入容器中。它接受两个参数set($key, $value)
。通过$key
设置$value
的值。
$app = new \PHPFramework\Application(); $app->set('data', ['some data' => 'value']);
get和set方法对调试和存储应用程序中的某些数据很有用。
缓存方法
缓存有三个主要方法。
- 方法
get
:允许您从容器中获取数据。它接受两个参数get($key, $default)
。如果按键不存在数据,则返回第二个参数传递的值,或返回null
。
$cache = new \PHPFramework\Cache(); $cache->get('tags');
- 方法
set
:缓存数据指定的时间,默认为一个小时。它接受3个参数set($key, $data, $time)
。将数据$data
设置在$key
下,时间为$time
。
$cache = new \PHPFramework\Cache(); $cache->set('tags', ['tag1' => 'value1', 'tag2' => 'value2'], 7200);
- 方法
forget
:从缓存中删除数据。它接受一个参数forget($key)
。数据的键。
$cache = new \PHPFramework\Cache(); $cache->forget('tags');
控制器方法
控制器有一个方法。方法render
:渲染视图。接受三个参数render($view, $data = [], $layout = '')
。$view
- 文件名(无扩展名:home.php
= home
)。$data
- 传递给视图的数据。$layout
- 视图中使用的页面模板。文件名(无扩展名:default.php
= default
)。
app()->view->render('home', ['title' => 'Home page'], 'default')
数据库方法
在使用数据库之前,请记住设置配置文件。这是强制性的。
- 方法
query
:允许您查询数据库。接受两个参数query($query, $params = [])
。查询本身以及如果查询需要则参数。查询方法排除了SQL注入的可能性。
db()->query("SELECT COUNT(*) FROM posts WHERE category_id = ?", [$category['id']])
- 方法
get
:返回查询中的所有行。
db()->query("SELECT COUNT(*) FROM posts WHERE category_id = ?", [$category['id']])->get()
- 方法
getOne
:返回所需行。
db()->query("SELECT * FROM tags WHERE slug = ?", [$slug])->getOne()
- 方法
findAll
:返回表中的所有行。接受一个参数findAll($tbl)
- 表名。
db()->findAll('categories')
- 方法
findOne
:通过id从表中返回一行。接受两个参数findOne($tbl, $id)
。$tbl
- 表名,$id
- 项目id。
db()->findOne('categories', 5)
- 方法
findOrFail
:通过id从表中返回一行。接受两个参数findOrFail($tbl, $id)
。$tbl
- 表名,$id
- 项目id。如果未找到行,则返回错误。
db()->findOrFail('categories', 5)
- 方法
getInsertId
:返回字符串的id。
db()->getInsertId()
- 方法
rowCount
:返回最后一条SQL语句影响的行数。
db()->rowCount()
- 方法
getColumn
:返回请求的列的数据。
db()->query("SELECT $data FROM $tbl WHERE $param = ?", [$value])->getColumn()
- 方法
getCount
:返回表中的行数。接受一个参数getCount($tbl)
- 表名。
db()->getCount($tbl);
- 方法
getQueries
:返回页面上使用的所有SQL查询。对调试很有用。
db()->getQueries();
模型的方法
在创建模型时,有几个强制性的变量需要创建。
- 变量
$table
- 模型所引用的表名。 - 变量
$fillable
- 填充时必须的字段名数组。当使用表单时。 - 变量
$rules
- 要填充的字段验证规则的数组。
模型创建示例
class User extends Model { public string $table = 'users'; public array $fillable = ['name', 'email', 'password', 'repassword',]; public array $rules = [ 'name' => ['required' => true, 'max' => 100], 'email' => ['email' => true, 'max' => 100, 'unique' => 'users:email'], 'password' => ['required' => true, 'min' => 6], 'repassword' => ['match' => 'password'], 'avatar' => ['ext' => 'jpg|png', 'size' => 1_048_576], ]; }
模型有几个验证规则。
- 规则
required
- 必须填写的字段。'required' => true
- 规则
int
- 字段必须是数字。'int' => true
- 规则
min
- 最小字符数。'min' => 6
- 规则
max
- 最大字符数。'max' => 100
- 规则
email
- 字段必须是电子邮件类型。'email' => true
- 规则
unique
- 字段值不能在表中出现。'unique' => 'users:email'
- 规则
file
- 接受文件的字段必须填写。'file' => true
- 规则
ext
- 允许的文件扩展名。'ext' => 'jpg|png'
- 规则
size
- 允许的文件大小。'size' => 1_048_576
- 规则
match
- 字段必须与另一个字段的值匹配。'match' => 'password'
- 方法
save
:将模型数据保存到数据库中,并返回保存行的id。
class User extends Model { public function saveUser() { $id = $this->save(); return $id; } }
- 方法
update
:更新数据库中的数据。并返回表中的行数。
class User extends Model { public function update() { $rows = $this->update(); return $rows; } }
- 方法
loadData
:加载模型数据。创建模型时的强制方法。
public function update() { $model = new User(); $model->loadData(); }
- 方法
delete
:delete($id)
方法接受一个参数 - 要删除的行的id。从数据库中删除该行。并返回表中的行数。
class User extends Model { public function delete() { $id = $this->save(); $rows = $this->delete($id); return $rows; } }
- 方法
validate
:validate($data = [], $rules = [])
方法接受两个参数:$data
是已验证数据数组,$rules
是验证规则数组。默认情况下,这两个参数都等于空数组。在成功验证的情况下返回true,在出错的情况下返回false。
class User extends Model { public function validate() { $model->validate($model->attributes, [ 'title' => ['required' => true, 'max' => 255], 'slug' => ['required' => true, 'max' => 255, 'unique' => 'tags:slug,id'] ]) } }
- 方法
getErrors
:getErrors()
方法返回错误数组。 - 方法
hasErrors
:hasErrors()
方法检查错误。 - 方法
listErrors
:listErrors()
方法呈现错误列表。
分页方法
分页类输出分页,基于Bootstrap类。如果您使用自己的自定义样式,请随意修改样式的源代码。
创建类时,您需要输入三个参数
- $page - 有效的页码。
- $per_page - 每页的实体数量。
- $total - 实体的总数。
创建分页的示例。```php public function index() { $page = (int)request()->get('page', 1); $total = db()->query("SELECT COUNT(*) FROM $tbl WHERE $param = ?", [$value])->getColumn(); $per_page = 5; $pagination = new Pagination($page, $per_page, $total); $start = $pagination->getStart(); } ```
- 方法
getStart
:`getStart()` 方法返回页面显示实体列表的起始行号。
public function index() { $pagination = new Pagination($page, $per_page, $total); $start = $pagination->getStart(); }
- 方法
getHtml
:`getHtml()` 方法返回基本的Bootstrap页码标记。
<?php echo $pagination->getHtml(); ?>
- 为了更方便地渲染标记,我建议使用以下结构
<?php if ($pagination->count_pages >= 2) : ?> <div class="text-start py-4"> <div class="custom-pagination"> <?= $pagination ?> </div> </div> <?php endif; ?>
- 方法
__toString
:`__toString()` 方法将 `getHtml()` 方法返回的结果转换为字符串。
分页类有几个变量可供使用或修改。
- $count_pages - 页数数量。
- $current_page - 当前页码。
- $uri - 页面URL。
- $max_pages - 分页中显示每个页码的最大页数。
请求方法
- 方法
getPath
:`getPath()` 方法返回当前页面的URL地址。
public function index() { $path = request()->getPath(); }
- 方法
isGet
:`isGet()` 方法检查请求方法是否为GET。如果有GET请求,则返回true
,否则返回false
。
public function index() { $request_data = request()->isGet() ? $_GET : $_POST; }
- 方法
isPost
:`isPost()` 方法检查请求方法是否为POST。如果有POST请求,则返回true
,否则返回false
。
public function index() { $request_data = request()->isPost() ? $_POST : $_GET; }
- 方法
get
:`get($name, $default = null)` 方法返回$name
键的查询数据,如果没有数据,则返回默认值$default
。查询本身必须是GET类型。
public function pagination() { $page = (int)request()->get('page', 1); }
- 方法
post
:`post($name, $default = null)` 方法返回$name
键的查询数据,如果没有数据,则返回默认值$default
。查询本身必须是POST类型。
public function user() { $nickname = request()->post('nickname', ''); }
- 方法
post
:`post($name, $default = null)` 方法返回$name
键的查询数据,如果没有数据,则返回默认值$default
。查询本身必须是POST类型。
public function user() { $nickname = request()->post('nickname', ''); }
- 方法
getData
:`getData()` 方法返回请求数据作为一个数组,键值对匹配全局数组$_GET
或$_POST
,取决于传递给页面的请求类型。
public function data() { $request_data = request()->getData(); }
响应方法
响应类有两个重要的方法。
- 方法
setResponceCode
:`setResponceCode($code)` 方法将服务器响应代码设置为传递给它的参数。
public function responce() { $error_404 = app()->responce->setResponceCode(404); }
- 方法
redirect
:`redirect($url = '')` 方法将用户重定向到传递给它的参数指定的页面。
public function redirect() { $main_page = app()->responce->redirect('/'); }
路由方法
- 方法
getRoutes
:`getRoutes()` 方法返回应用中存在的所有路由。
public function router() { $routes = app()->router->getRoutes(); }
- 方法
add
:`add($uri, $callback, $method)` 方法允许您的路由同时由POST方法和GET方法处理。传递的参数是路由的URL地址、处理路由的回调函数和请求方法,或者方法的数组。
$app = new \PHPFramework\Application(); $app->router->add('/register', [\App\Controllers\UserController::class, 'register'], ['get', 'post'])
- 方法
get
:`get($uri, $callback)` 方法允许您的路由由GET方法处理。路由的URL地址作为参数传递,回调函数处理此路由。
$app = new \PHPFramework\Application(); $app->router->get('/logout', [\App\Controllers\UserController::class, 'logout'])
- 方法
post
:`post($uri, $callback)` 方法允许您的路由由POST方法处理。路由的URL地址作为参数传递,回调函数处理此路由。
$app = new \PHPFramework\Application(); $app->router->post('/comment/store', [\App\Controllers\CommentController::class, 'store'])
- 方法
only
:only($middleware)
方法允许您的路由只对特定类型的用户可用。
$app = new \PHPFramework\Application(); $app->router->add('/register', [\App\Controllers\UserController::class, 'register'], ['get', 'post'])->only('guest');
Session 方法的用法
- 方法
setFlash
:setFlash($key, $value)
方法设置警告,随后使用标准的 bootstrap 标记来渲染。
session()->setFlash('success', 'You have successfully registered.');
- 方法
getFlash
:getFlash($key)
方法允许您获取在会话中设置在特定键下的值。这将从这个会话中删除这个值。
$error_message = session()->getFlash('error');
- 方法
set
:set($key, $value)
方法将键值对设置到全局数组$_SESSION
中。
session()->set('user', $user_data);
- 方法
get
:get($key, $default = null)
方法返回在全局数组$_SESSION
中特定键下设置的值。如果未找到值 - 返回参数$default
。
session()->get('user');
- 方法
has
:has($key)
方法检查全局数组$_SESSION
是否在键$key
下设置了值。
if (session()->has('user') { $user_name = session()->get('user')['name']; }
- 方法
forget
:forget($key)
方法从全局数组$_SESSION
中删除$key
值。
if (session()->has('user') { session()->forget('user'); }
View 方法的用法
- 方法
render
:render($view, $data = [], $layout = '')
方法渲染视图并将数据传递给它。可以传递第三个可选参数作为模板。第三个参数默认定义为默认值,渲染名为 default.php 的文件。
public function index() { return app()->view->render('users/register', ['title' => 'Register']) }
- 方法
renderPartial
:renderPartial($view, $data = [])
方法仅渲染视图的一部分,而不重新加载整个页面。它还接受传递给视图的数据。
<?= app()->view->renderPartial('incs/header', ['title' => $title]); ?>
辅助函数
- 函数
view()
:简化了使用View
类的render
方法的操作。接受与render
方法相同的参数。
public function index() { return view('users/register', ['title' => 'Register']); }
- 函数
request()
:允许您无需创建Request
类的副本,而是使用返回该副本的便捷函数。
$page = request()->get('page', 1)
- 函数
response()
:简化了使用Response
类的setResponseCode
方法的操作。接受与setResponseCode
方法相同的参数。
public function index() { return response(404); }
- 函数
router()
:允许您无需创建Router
类的副本,而是使用返回该副本的便捷函数。
router()->get('/logout', [\App\Controllers\UserController::class, 'logout'])
- 函数
redirect()
:简化了使用Response
类的redirect
方法的操作。接受与redirect
方法相同的参数。
public function index() { redirect('/'); }
- 函数
db()
:允许您无需创建Database
类的副本,而是使用返回该副本的便捷函数。
public function index() { db()->query("UPDATE posts SET views = views + 1 WHERE slug = ?", [$slug]); }
- 函数
base_url($path = '')
:返回包含传入值的字符串形式的 URL 地址。输出是以下类型的完整地址:[www.yoursite.com/$path](http://www.yoursite.com/%60$path%60 "www.yoursite.com/`$path`")
<a href="<?= base_url("/register"); ?>">
- 函数
html($str)
:标准htmlspecialchars
函数的简短版本。 - 函数
old($fieldname)
:在处理表单时很有用。如果验证未通过,将之前输入的值插入到字段中。
<input type="text" name="name" class="form-control <?= get_validation_class('name', $errors ?? []); ?>" id="name" placeholder="Your Name" value="<?= old('name'); ?>">
- 函数
oldfFromSession($arr, $fieldname)
:如果表单值被写入全局数组$_SESSION
作为数组,则此函数将帮助从那里检索之前输入的值。
class PostController extends BaseController { public function store() { // Some code if (!$model->validate()) { session()->set('form_data', $model->attributes); session()->set('form_errors', $model->getErrors()); session()->setFlash('error', 'Validation Error'); redirect(base_url('/admin/posts/create')); } // Some code } } ... <textarea id="content" name="content" class="form-control summernote <?= get_validation_class('content', $errors ?? []); ?>" rows="3" placeholder="Content"> <?= oldfFromSession('form_data', 'content'); ?> </textarea>
- 函数
selected($arr, $fieldname, $value, $data = [])
:用于处理表单中选中的值。
<div class="col-md-6"> <div class="form-group"> <label>Select Tags</label> <select multiple name="tag_id[]" id="tag_id" class="form-control select2"> <?php foreach ($tags as $tag) : ?> <option value="<?= $tag['id']; ?>" <?= selected('form_data', 'tag_id', $tag['id']); ?>><?= $tag['title']; ?></option> <?php endforeach; ?> </select> </div> </div>
- 函数
get_errors($fieldname, $errors = [])
:输出验证错误。
<div class="col-md-6"> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control <?= get_validation_class('title', $errors ?? []); ?>" name="title" id="title" placeholder="Enter your title" value="<?= oldfFromSession('form_data', 'title'); ?>"> <?= get_errors('title', $errors ?? []); ?> </div> </div>
- 函数
get_validation_class($fieldname, $errors = [])
:通过标准的 bootstrap 标记突出显示已通过/失败验证的字段。
<div class="col-md-6"> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control <?= get_validation_class('title', $errors ?? []); ?>" name="title" id="title" placeholder="Enter your title" value="<?= oldfFromSession('form_data', 'title'); ?>"> <?= get_errors('title', $errors ?? []); ?> </div> </div>
- 函数
abort($error = '', $code = 404)
:调用作为第二个参数传入的错误页面。默认情况下,将调用框架内的 404 页面。可以传入错误文本作为第一个参数。
public function Fail($result) { if (!$result) { abort(); } return $result; }
- 函数
session()
:允许您无需创建Session
类的副本,而是使用返回该副本的便捷函数。
session()->setFlash('success', 'Success message');
- 函数
cache()
:允许您不创建Cache
类的副本,而是使用一个返回该副本的便利函数。
cache()->forget('user');
- 函数
get_alerts()
:渲染会话中记录的警告。
<main id="main"> <section> <div class="container"> <?= get_alerts() ?> </div> </section> </main>
- 函数
get_file_ext($file_name)
:获取文件的扩展名。将文件的全名作为参数。
$file_ext = (false === $i) ? get_file_ext($file['name']) : get_file_ext($file['name'][$i]);
- 函数
upload_file($file, $i = false, $path = false)
:该函数接受三个参数。文件名、如果一次性上传多个文件时使用的迭代次数、文件已存在时的路径。如果不存在,则创建一个新的文件夹,格式为年/月/日,其中将您的文件以哈希名称放入该文件夹。返回 false,或文件的域名路径。
if ($image) { if ($file_url = upload_file($image)) { dump($file_url); } }
- 函数
check_auth()
:该函数检查用户数据是否写入会话。它返回一个布尔值。
if (check_auth()) { session()->forget('user'); }
- 函数
check_auth()
:该函数检查用户数据是否写入会话。它返回一个布尔值。
if (check_auth()) { session()->forget('user'); }
- 函数
send_mail(array $to, string $subject, string $body, array $attachments = [])
:该函数发送电子邮件。它基于 PHPMailer 工作原理。
注意
还值得注意的是,这项技术与其他库(如:phpmailer 和 symfony/var-dumper)一起工作。前者允许您方便地处理电子邮件,后者用于调试。