学习，有时候慢即为快。只有思考总结，印象才能深刻。不然囫囵吞枣，很快就又忘记了。
CI框架请求的处理逻辑与步骤跟着视频学了好几个请求的处理，比如登录，忘记密码，重置密码等。大致思考一下这种框架的通用逻辑，方便后面再写的时候比对。请求进入路由先要维护对应的Routes.php文件，比如下面这一串请求。设置对应的get/post方法， $routes->group('', ['filter' => 'cifilter:guest'], static function ($routes) { // $routes->view('example-auth','example-auth'); $routes->get('login', 'AuthController::loginForm', ['as' => 'admin.login.form']); $routes->post('login', 'AuthController::loginHandler', ['as' => 'admin.login.handler']); $routes->get('forgot-password', 'AuthController::forgotForm', ['as' => 'admin.forgot.form']); $routes->post('send-password-reset-link', 'AuthController::sendPasswordResetLink', ['as' => 'send-password-reset-link']); $routes->get('password/reset/(:any)', 'AuthController::resetPassword/$1', ['as' => 'admin.reset-password']); $routes->post('reset-password-handler/(:any)', 'AuthController::resetPasswordHandler/$1', ['as' => 'reset-password-handler']); });第一个参数是url的访问路径，第二个对应控制器的相应方法，as方法可以将routes 命名一个简单命令，这样在其他地方可以直接引用。例如在view中引用 <form action="<?= route_to('send-password-reset-link');?>" method="POST">在参数里可以设置对应的filter 在/Config/Filter.php进行注册 public array $aliases = [ 'csrf' => CSRF::class, 'toolbar' => DebugToolbar::class, 'honeypot' => Honeypot::class, 'invalidchars' => InvalidChars::class, 'secureheaders' => SecureHeaders::class, 'cifilter' => CIFilter::class, ];路由转入控制器建立相应的控制器以及方法，同时进行相应的逻辑判定。在控制器里面，需要注意可以加载相应的helper 类供后面使用。protected $helpers = ['url', 'form', 'CIMail']; 例如，加载url, form和CIMail这个helper类，其中CIMail为自己创建的文件。在控制器里面，可以使用validate方法，但是如果有自己创建的类，需要在/Config/Validation.php里面注册相应的类。 public array $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, CreditCardRules::class, IsPasswordStrong::class, ];之后再function里面就可以调用IsPasswordStrong$isValid = $this->validate([ 'new_password' => [ 'rules' => 'required|min_length[5]|max_length[20]|is_password_strong[new_password]', 'errors' => [ 'required' => 'Enter new password', 'min_length' => 'New password must have at least 5 characters', 'max_length' => 'New password must have at most 20 characters', 'is_password_strong' => 'new password is not strong enough', ] ], 'confirm_new_password' => [ 'rules' => 'required|matches[new_password]', 'errors' => [ 'required' => 'Confirm new password', 'matches' => 'Passwords not match', ] ] ]);控制器进行跳转View常用的返回跳转有。直接返回view界面 并且附带数据。 public function loginForm() { $data = [ 'pageTitle' => 'Login', 'validation' => null ]; return view('backend/pages/auth/login', $data); }返回跳转到指定的route.使用这个方法可以跳转到admin.forot.form路由并附带一个success信息return redirect()->route('admin.forgot.form')->with('success', 'We have email your password reset link')返回上一个界面返回上一个界面并且将之前的输入信息返回，同时附带fail提示信息return redirect()->back()->with('fail','Something went wrong!')->withInput();View界面展示附带flash data的展示 <?php if (!empty(session()->getFlashdata('fail'))) : ?> <?= session()->getFlashdata('fail'); ?> × <?php endif; ?>传入变量的引用。//控制器传入View 的数据 <?php $data = [ 'pageTitle' => 'Login', 'validation' => null ]; ?> //view 界面引用数据中的值 <?= isset($pageTitle) ? $pageTitle : "New Page Title"; ?> Validation部分的引用在view里面设置了validation变量，再从控制器的方法中传入validator, 在view界面进行error读取。controller里面的设置<?php return view('backend/pages/auth/login', [ 'pageTitle' => 'Login', 'validation' => $this->validator, ]); ?>View界面的读取验证错误结果//先初始化一个validation <?php $validation = \Config\Services::validation(); ?> <?php if ($validation->getError('login_id')) : ?> <?= $validation->getError('login_id'); ?> <?php endif; ?>总结透过这段逻辑就实现了从请求到路由到控制器再到view展示的步骤。对于MVC来说，model部分是和controller里面进行交互处理。所以并未特别备注。后面再研究一下model的交互。
CodeIgniter设计验证登录需求为在登录时验证账户是邮箱地址还是账户名，同时验证账户密码长度以及是否存在资料库中。1. 登录界面设计从DeskApp里面直接复制对应的html代码即可，同时需要注意这个在于将HTML进行切割成不同的layout 部分。这样方便后面的复用。针对页首页脚侧边栏等采用<?= include('inc/footer.php'); ?>)方式来引用。 而对于要传入的内容则使用 <?= $this->renderSection('content'); ?> ，在具体的页面里使用extend扩展其他页面，而section则传入相应的值。<?= $this->extend('backend/layout/auth-layout')?> <?= $this->section('content'); ?> Auth page content here ......... <?= $this->endSection();?>2. 控制器设置在admin group下面增加login的get 和Post方法的控制器。分别用于打开login界面和提交登录系统。$routes->view()可以直接展示view界面，而不用控制器中转。使用['as'=>'admin.handler']可以设置别名，方便在view界面进行控制，使用范例<form action="<?= route_to('admin.login.handler') ?> " method="POST">$routes->group('admin',static function($routes){ $routes->group('',[],static function($routes){ $routes->get('home','AdminController::index',['as'=>'admin.home']); $routes->get('logout','AdminController::logoutHandler',['as'=>'admin.logout']); }); $routes->group('',[],static function($routes){ // $routes->view('example-auth','example-auth'); $routes->get('login','AuthController::loginForm',['as'=>'admin.login.form']); $routes->post('login','AuthController::loginHandler',['as'=>'admin.login.handler']); }); });3. Validation是用$this->validate()方法去验证log_id 。rules为验证的规则，一般采用系统默认的一些规则。其中要注意的是is_not_unique,这个方法的参数是table.column,可以直接去数据库进行查询是否存在。 public function loginHandler() { $fieldType = filter_var($this->request->getVar('login_id'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; if ($fieldType == 'email') { //is_not_unique[table.column]是直接验证字段在表内的存在 $isValid = $this->validate([ 'login_id' => [ 'rules' => 'required|valid_email|is_not_unique[users.email]', 'errors' => [ 'required' => 'Email is required', 'valid_email' => 'Email is not valid', 'is_not_unique' => 'Email is not exists in our system.' ] ], 'password' => [ 'rules' => 'required|min_length[5]|max_length[45]', 'errors' => [ 'required' => 'password is required', 'min_length' => 'min_length is 5', 'max_length' => 'max_length is 45.' ] ] ]); } else { $isValid = $this->validate([ 'login_id' => [ 'rules' => 'required|is_not_unique[users.username]', 'errors' => [ 'required' => 'username is required', 'is_not_unique' => 'username is not exists in our system.' ] ], 'password' => [ 'rules' => 'required|min_length[5]|max_length[45]', 'errors' => [ 'required' => 'password is required', 'min_length' => 'min_length is 5', 'max_length' => 'max_length is 45.' ] ] ]); }4. 界面传参在示例文件中，将view界面创建了一个validation实例。<?php $validation = \Config\Services::validation(); ?> 。而将控制器里面的实例$this->validator()传给了view界面的$validation。使用geterror()获取对应的验证信息。<?php if ($validation->getError('login_id')) : ?> <?= $validation->getError('login_id'); ?> <?php endif; ?>CodeIgniter设计登出直接调用function移除session里面的相关数据。 public static function forget() { $session = session(); $session->remove('logged_in'); $session->remove('userdata'); }
从案例中学习框架网页访问需要设置url 对应的Routers 位于 app/Config/Routes.php 通过routes的指向到对应的控制器类（需要引用对应的类，不然无法识别）在控制前内部写对应的方法，默认index()在方法内部return view('page'),这里page是对应的视图page在Views里面建立page.php 用于前段展示return view（）方法可以串联不同的page进行展示数据库配置env文件应该修改文件名加点，否则配置文件不生效建立数据库和模型使用Migration和Seeder是可以初始化table并且填入一些sample数据的php spark make:migration Create_User_table 可以创建一个migrate文件，然后使用$this->forge()命令去创建相应的数据和表。 php spark migrate去执行这个文件、php spark make:model User命令创建一个UserModelphp spark make:seeder UserSeeder 可以创建一个seeder文件。在文件里创建默认的数据。php spark db:seed UserSeeder执行将seeder中的数据放入数据库中Migrate文件的代码<?php namespace App\Database\Migrations; use CodeIgniter\Database\Migration; class AddBlog extends Migration { public function up() { $this->forge->addField([ 'blog_id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, 'auto_increment' => true, ], 'blog_title' => [ 'type' => 'VARCHAR', 'constraint' => '100', ], 'blog_description' => [ 'type' => 'TEXT', 'null' => true, ], ]); $this->forge->addKey('blog_id', true); $this->forge->createTable('blog'); } public function down() { $this->forge->dropTable('blog'); } }Seeder的文件代码<?php namespace App\Database\Seeds; use CodeIgniter\Database\Seeder; class SimpleSeeder extends Seeder { public function run() { $data = [ 'username' => 'darth', 'email' => 'darth@theempire.com', ]; // Simple Queries $this->db->query('INSERT INTO users (username, email) VALUES(:username:, :email:)', $data); // Using Query Builder $this->db->table('users')->insert($data); } }
最近发现一个提升成就感的事情，就是维修东西。鼠标充电电池坏了，所以拆了找了个玩具车的电池替代上。电动消毒喷雾器电机坏了，从网上买了个配件，重新焊上了。修复成功。
冬天到啦，越来越冷最近了解了一下几个PHP框架。发现写框架的真的是大神。对于代码的理解和运用真是炉火纯青。