PHP学习——Laravel框架入门

环境搭建

此处省略,后面补充

Laravel教程微博实例

构建页面

样式美化

1
2
yarn install --no-bin-links
yarn add cross-env

使用Boostrap组件进行前端样式美化

Bootstrap再入门

上面代码将引入public/css/app.css样式文件。

header, nav 是 HTML5 提供的一种语义化标签,其实际作用与 div 一致,语义化的标签能帮助机器更方便理解代码,使代码更简洁,有助于网站的 SEO 优化。我们在上面代码使用到一些如 navbar, container 等类名在 Bootstrap 中都拥有特殊含义。

Laravel 前端工作流

介绍Sass,NPM,Yarn,Laravel Mix来构成一套完整的前端工作流。

SASS语法基础

  1. 样式文件导入

    Sass使用@import 来导入其它的样式文件从而实现样式嵌套。

  2. 变量

    Sass允许加入自己的变量,所有的变量以$开头

    1
    2
    3
    4
    $navbar-color: #3c3e42;
    .navbar-inverse {
    background-color: $navbar-color;
    }

    在编译成功后,变量会被替代为对应的值

  3. 嵌套

    Sass允许选择器中相互嵌套以减少代码量

  4. 引用父选择器

    在Sass嵌套中使用&对父选择器进行引用:

    1
    2
    3
    4
    5
    6
    a {
    color: white;
    &:hover {
    color: blue;
    }
    }

NPM

NPM 是Node.js 的包管理和任务管理工具,其强大的功能也是Node.js能够如此成功的因素之一。在使用NPM安装第三方模块(也可理解为扩展包)时,你需要在 package.json 中队需要安装的模块指定好名称和版本号。然后运行下面的命令进行安装:

1
$ npm install

在学习教程中,出于安装速度考虑,我们使用更加现代化的 Yarn 来替代 NPM 的包管理功能。然而我们仍然会使用到 NPM 的任务管理功能,如命令 npm run watch-poll

Yarn

Yarn 是 Facebook 在 2016 年 10 月开源的一个新的包管理器,用于替代现有的 NPM 客户端或者其他兼容 NPM 仓库的包管理工具。Yarn 在保留 NPM 原有工作流特性的基础上,使之变得更快、更安全、更可靠。在后面的项目开发中,我们统一使用 Yarn 来代替 NPM 进行安装包的管理。

我们可通过下面命令来安装当前项目的所有包:

1
$ yarn install

Laravel Mix

Laravel Mix 一款前端任务自动化管理工具,使用了工作流的模式对制定好的任务依次执行。Mix 提供了简洁流畅的 API,让你能够为你的 Laravel 应用定义 Webpack 编译任务。Mix 支持许多常见的 CSS 与 JavaScript 预处理器,通过简单的调用,你可以轻松地管理前端资源。我们可以在 webpack.mix.js 文件中制定一些如资源文件的编译、压缩等任务。Laravel 已默认为我们生成了 webpack.mix.js 文件,并集成了 laravel-mix 模块。

浏览器缓存问题

问题描述

现代化的浏览器,会对静态文件进行缓存,静态文件在本课程的范畴内,指的是 .css 、.js 后缀的文件。这是一个浏览器的优化功能,极大地加快了网页的加载速度,但是在我们日常开发和维护中,有时候会造成混淆。

开发时,你明明修改了样式,但是刷新浏览器却看不见变化,然后你就来回不断地修改你的样式文件,做各种测试,浏览器页面仍然一成不变。直到你重新刷新好多次,或者修改样式文件名称时,才恍然大悟,原来是浏览器缓存了。

解决方法

Laravel Mix,增加哈希值,只要修改,哈希值改变,则客户端浏览器就需要重新加载文件。

webpack.mix.js 稍作修改

1
2
3
4
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css').version();

局部视图

随着代码量增加,都存在默认视图中会变得太过臃肿,难以维护,所以最好将部分视图分离出来,成为单独得局部视图。

头部和底部视图

首先,我们需要新建一个头部视图文件。

resources/views/layouts/_header.blade.php

1
2
3
4
5
6
7
8
9
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container ">
<a class="navbar-brand" href="/">Weibo App</a>
<ul class="navbar-nav justify-content-end">
<li class="nav-item"><a class="nav-link" href="/help">帮助</a></li>
<li class="nav-item" ><a class="nav-link" href="#">登录</a></li>
</ul>
</div>
</nav>

可以看到,我们在头部视图的文件名前面加了下划线 _,这样做是为了指定该视图文件为局部视图,为局部视图增加前缀下划线是『约定俗成』的做法,方便了其它人快速地理解该文件的实际作用。从这里开始,我们都会为局部文件添加下划线前缀。

现在让我们再来为应用创建一个底部视图,用于置放网站的一些基础信息。

resources/views/layouts/_footer.blade.php

1
2
3
4
5
6
7
8
9
10
<footer class="footer">
<img class="brand-icon" src="https://iocaffcdn.phphub.org/uploads/sites/KDiyAbV0hj1ytHpRTOlVpucbLebonxeX.png">
<a href="https://learnku.com/laravel/courses" target=_blank>
刻意练习,每日精进
</a>

<div class="float-right">
<a href="/about" >关于</a>
</div>
</footer>

布局中的链接

Laravel中链接地址的写法

较为常见的链接地址的写法

1
<li><a href="/help">帮助</a></li>

在Laravel中,我们可以这么写

1
<li><a href=" route('help') ">帮助</a></li>

大括号括起来的部分是在HTML中内嵌PHP的Blade语法标识符,表示包含在该区块内的代码都将用PHP来编译运行。route()方法由Laravel提供,传递一个具体的路由名称来生成完整的URL。

在 Laravel 中,我们可以通过在路由后面链式调用 name 方法来为路由指定名称:

1
Route::get('/help', 'StaticPagesController@help')->name('help');

可以看到 route('help')为我们生成了完整的 URL 地址,这样当我们需要对生成的 URL 进行更改时,我们只需要改动路由文件即可,由此可见在实际开发中养成对路由的命名是一个好习惯,可以帮助我们节省很多工作量,另外也是 Laravel 项目开发的最佳实践。

均改为href="route()"的形式

静态页面

在我们后面的教程中,将会为应用添加注册登录的功能,本节让我们先来完成用户注册功能的第一步:为用户注册功能创建基本的静态页面。

注册路由

当用户访问注册url时,进入我们的注册页面

修改(添加)路由

1
2
3
4
5
Route::get('/', 'StaticPagesController@home')->name('home');
Route::get('/help', 'StaticPagesController@help')->name('help');
Route::get('/about', 'StaticPagesController@about')->name('about');

Route::get('signup', 'UsersController@create')->name('signup');

注册路由时,URI signup 和 /signup 从使用上来看,并无区别,Laravel 框架兼容这两种写法。

注意这里不在注册到StaticPagesController控制器上,因为不单是静态页面,会涉及和数据库的交互,所以围绕用户使用用户控制器来处理此逻辑。

用户模型

MVC框架的M

M-Model(模型),构建一个基本的用户模型来实现用户数据的存储,并了解Laravel如何对模型对象进行增删查改等操作。后面我们还会在此用户模型上添加用户注册和登录的功能,并对用户进行权限认证,管理员具备用户的删除操作。再构建一套用户账号激活和密码找回系统。

用户认证系统

Laravel集成了一整套用户登录注册功能,并提供了一些方便的API,但是出于学习目的,我们会借助一些简单的API来独自开发一个完整的用户认证系统。

如果定制性不高,还是建议使用Laravel的默认提供的用户认证系统。

Eloquent ORM

在接下来几章要实现的用户注册功能需要用到数据库来进行数据存储,用于放置用户的基本信息。在这期间,还需要用到数据模型- Model,利用 Laravel 提供的 Eloquent ORM 跟数据库进行交互,实现用户数据的增删改查操作。Eloquent 提供了简洁优雅的 ActiveRecord 实现来跟数据库进行交互。Active Record 是一种领域模型模式,该模式由 Martin Fowler 在 2003 年出版的《企业应用架构模式》一书中进行了详细叙述并命名。其特点是一个模型类对应关系型数据库中的一个表,模型类的一个实例对应表中的一行记录。Active Record 最大优点是允许我们简单, 直观地操作数据层。

数据库迁移

Laravel中通过数据库迁移来管理数据库表结构,迁移就像数据库中的版本控制。

好处

  1. 多人并行开发
  2. 代码版本管理
  3. 数据库版本控制:如:回滚重置更新
  4. 兼容多种数据库系统
  5. 部署方便

默认迁移文件

所有迁移文件统一放置在 database/migrations 文件夹里

我们看到Laravel已经默认创建好了两个迁移文件。

  • database/migrations/2014_10_12_000000_create_users_table.php
  • database/migrations/2014_10_12_100000_create_password_resets_table.php

加入时间戳避免多人开发时候的命名冲突。

创建数据库表

up方法里,通过调用 Schema 类的create方法来创建users表:

1
2
3
Schema::create('users', function (Blueprint $table) {
...
});

两个参数 - 参数1:表名称 - 参数2:Blueprint实例的必报(函数依赖关系必报)

定义数据表字段

CreateUsersTable 类中通过 Blueprint 的实例 $table 为 users 表创建所需的数据库字段。接下来让我们来详细讲解 Blueprint 实例 $table 的基本用法:

1
$table->increments('id');

由 increments 方法创建了一个 integer 类型的自增长 id。

1
$table->string('name');

由 string 方法创建了一个 name 字段,用于保存用户名称。

1
$table->string('email')->unique();

由 string 方法创建了一个 email 字段,且在最后指定该字段的值为唯一值,用于保存用户邮箱。

1
$table->timestamp('email_verified_at')->nullable();

Email 验证时间,空的话意味着用户还未验证邮箱。nullable()方法表示字段可空。

1
$table->string('password', 60);

由 string 方法创建了一个 password 字段,且在 string 方法中指定保存的值最大长度为 60,用于保存用户密码。

1
$table->rememberToken();

由 rememberToken 方法为用户创建一个 remember_token 字段,用于保存『记住我』的相关信息。

1
$table->timestamps();

由 timestamps 方法创建了一个 created_at 和一个 updated_at 字段,分别用于保存用户的创建时间和更新时间。注意和前面email的timestap字段区分开。

回滚迁移

down 方法会在回滚命令发起时被调用,是 up 方法的逆向操作。在上面的代码中,up 创建了 users 表,那么这里将会通过调用 Schema 的 drop 方法来删除 users 表。

1
Schema::dropIfExists('users');

用户注册

本章节为注册页添加一个注册表单

隐式绑定

由于我们使用了 view('users.show', compact('user')) 将用户数据与视图进行绑定,因此在视图中可以直接使用 $user 来访问用户实例。

会话管理

由于 HTTP 协议是无状态的,所以 Laravel 提供了一种用于临时保存用户数据的方法 - 会话(Session),并附带支持多种会话后端驱动,可通过统一的 API 进行使用。

我们可以使用 session() 方法来访问会话实例。而当我们想存入一条缓存的数据,让它只在下一次的请求内有效时,则可以使用 flash 方法。flash 方法接收两个参数,第一个为会话的键,第二个为会话的值,我们可以通过下面这行代码的为会话赋值。

接下来的消息提示我们会用会话进行闪存,并分别为其设定好指定的键。danger, warning, success, info 这四个键名在 Bootstrap 分别具有不同样式展现效果,因此后面我们将使用这几个键名作为消息提示的专有设定。

用户CRUD

新增的 edit 动作主要做了以下几个操作:

利用了 Laravel 的『隐性路由模型绑定』功能,直接读取对应 ID 的用户实例 $user,未找到则报错; 将查找到的用户实例 $user 与编辑视图进行绑定; 在将用户数据与视图进行绑定之后,便可以在视图上通过 $user 来访问用户对象。接下来让我们接着完成用户编辑页面的构建。

编辑成功 现在的用户编辑功能还有两个地方需要优化:

  1. 在每次更改个人资料的时候都输入完整的密码,才能更新其它信息,对于不想对密码进行更新的用户,这个过程会比较繁琐;

  2. 更新成功之后在页面上没有进行任何提示,而是直接跳转到用户的个人页面,用户体验非常不好;