Laravel 项目开发前的准备
集成开发环境的安装
在学习PHP或使用PHP开发项目之前,您必须拥有对应的开发环境。
所谓开发环境就是一个支持 PHP
和 MySQL
的 Web 主机
。
本地开发环境中您可选择安装最新版本的phpstudy,在服务器端可选择安装宝塔面板后根据提示安装相应版本的 PHP解释器
,MySQL数据库
和Web主机
。
你可以在终端中运行以下命令(万能安装脚本):
if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec
框架的选择
如果不是以学习为目的,千万不要使用原生代码去完成项目!即使是出于性能考虑也不要去使用原生代码去写项目(PHP开发的Web系统瓶颈一般都不在语言本身的执行层面)!框架一般是成熟,稳健的。比如国内的Thinkphp,以及国际流行的Laravel、CI 、YII、ZF。这些框架都是经过多年打磨,可以处理系统很多细节问题,使用成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。其实框架本身也是原生代码,随着你对语言本身以及代码设计方面的认知逐渐提高,完全可以开发自己的框架。
Laravel 框架的安装
通过 Composer 安装
需要注意,默认镜像源可能会无法使用,可替换为阿里云的PHP Composer 全量镜像源
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
如果你的终端已经安装了Composer(安装Composer之前必须安装Php),你可以直接使用 Composer 来创建一个新的 Laravel 项目。
composer create-project laravel/laravel example-app
Laravel 项目的开始
安装Git
不管是本地自己开发的项目还是多人协作的项目,一个好的版本控制工具都是必不可少的,我个人使用的是Git,SVN也有过了解,至于两者的区别,在此不做赘述。
sudo yum update
yum install -y git
git --version
Linux系统下,安装好即可使用,在windows下还需要配置环境变量,以便在各种终端中使用。
将Git\bin添加到为环境变量
查看已存在的 SSH 密钥
ED25519 算法
cat ~/.ssh/id_ed25519.pub
RSA 算法
cat ~/.ssh/id_rsa.pub
如果返回一长串以 ssh-ed25519 或 ssh-rsa 开头的字符串, 说明已存在本地公钥,你可以跳过步骤生成 SSH 密钥,直接拷贝本机中的公钥到服务器端。
生成 SSH 密钥
注释会出现在.pub
文件中,一般可使用邮箱作为注释内容。
- 基于
ED25519
算法,生成密钥对命令如下:
ssh-keygen -t ed25519 -C "<注释内容>"
- 基于
RSA
算法,生成密钥对命令如下:
ssh-keygen -t rsa -C "<注释内容>"
设置完成后再次查看SSH 密钥是否存在,存在则拷贝本机中的公钥到服务器端
设置Git
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"
创建Git仓库
cd example-app
git init
git status
已有文件夹或仓库本地仓库
cd existing_folder
git init
git remote add origin 仓库地址
git add .
git commit -m"注释内容"
git push -u origin master
设置.gitignore忽略文件
如果你能提前预见或者希望哪些文件不被上传,请将其添加到忽略文件中,这样既不用手动一个一个文件添加,避免造成提交时的冲突
这几类文件是有必要设置为忽略提交的
1.不能提交
高度敏感的项目配置信息(最好把配置信息都放到.env中,方便维护,防止泄露)
2.不必提交
有公共资源的第三方类库
3.无用提交
项目运行中生成的日志,图片,文档
.env
/public/
/storage/
/vendor
.gitignore
composer.lock
忽略规则简单说明
# 表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹;不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。
需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下:
!*.zip
!/mtk/one.txt
唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。
注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效!还有其他一些更为复杂的配置在项目中基本遇不到,如果需要,可以查询官方的Git忽略提交规则
Laravel项目框架的设置
.env文件中的数据库配置必须正确填写后项目才能调用数据库
- 数据库配置
DB_DATABASE=DATABASE
DB_USERNAME=USERNAME
DB_PASSWORD=PASSWORD
上述是系统默认的配置,如果想要进行读写分离,可以在自行增加配置项即可
DB_HOST_READ=HOST
DB_DATABASE_READ=DATABASE
DB_USERNAME_READ=USERNAME
DB_PASSWORD_READ=PASSWORD
- 生成APP_KEY
加密的 cookie 是 Laravel 中的重要安全特性。新建或克隆 Laravel 应用时生成APP_KEY 是最重要的初始步骤之一。
应用程序密钥是一个 32 位字符的随机字符串,应用程序运行后,便会在cookie中通过Encrypt /Decrypt(对称加密)加密解密算法使用APP_KEY,达到防篡改
的目的。
一个非常普遍的误解是认为APP_KEY 用于登录密码HASH值的加密(单向哈希加密),从而不敢更换APP_KEY,以防止改变密码的HASH值,其实登录时使用的并非是对称加密,而是被 哈希散列
。
php artisan key:generate
.config/app.php设置
修改时区,如果不修改,比如一个定时任务本该在24:00执行,但是因为时区问题,实际将在8:00执行,中国时间与UTC的时差均为+8
'timezone' => 'UTC', 72行改为
'timezone' => 'PRC' ,
语言本地化
'locale' => 'en', 85行改为
'locale' => 'zh-CN',
数据库迁移防报错配置
在运行 php artisan migrate 时会出现报错
PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes")
网络上的解决方案
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
我在最早遇到这个问题的时候,并没有深思问题产生的原因,一度认为是框架的不完善,在这里我们分析下问题产生的原因:
上面的修改是字符串类型的默认长度由255修改为191,为什么我们要做这个修改呢,而官方不主动修复这个BUG。这是因为框架是国际化的,在其他国家使用的编码格式跟我们是不同的。
- innodb存储引擎,多列索引的长度限制
每个列的长度不能大于767 bytes;所有组成索引列的长度和不能大于3072 bytes
- myisam存储引擎,多列索引长度限制
每个列的长度不能大于1000 bytes,所有组成索引列的长度和不能大于1000 bytes
- GBK是双字节的,UTF8是三字节的,utf8mb4是四字节的,laravel数据库迁移时默认字符串长度为255。
按照以上规则,如果使用GBK,或者UTF8编码,则索引中包含字符串类型,则长度为255*3= 765 bytes,不管使用哪个存储引擎都不会触发长度限制;在编码为tf8mb4时,若引擎为myisam,索引长度就会超过对应限度就会产生该种报错。而默认字符串长度改为191后,则长度为191*4=764 bytes,从而符合了长度限制
419问题的解决 跨站点请求伪造(CSRF) Cross Site Request Forgery
- 什么是CSRF
一个恶意站点请求A站点时,如果A站点的Cookie处于登录态,则访问时浏览器会自动带上A站点登录态 的Cookie,从而骗取服务端信任,完成敏感操作。常用防护操作为- 验证referrer或origin,
- 添加校验token
- 尽量使用 POST,限制 GET(GET请求太容易被攻击了,甚至可以通过标签直接写入一个转账给B的URL,那么打开网页就会被执行请求,这个是其他攻击,不是CSRF)
由于【post】访问会经过【Csrf】中间件的验证,故而会报错【419】,所以需要此步操作。
- 关闭Csrf中间件验证 【app/Http/Kernel.php】文件
这个方式极不安全,不建议操作
protected $middlewareGroups = [
'web' => [
//\App\Http\Middleware\VerifyCsrfToken::class,
],
- 修改验证规则【app\Http\Middleware\VerifyCsrfToken.php】文件
use Closure;
public function handle($request, Closure $next)
{
if($request->method() == 'POST') {
return $next($request);
}
if ($request->method() == 'GET' || $this->tokensMatch($request)) {
return $next($request);
}
}
- 设置CSRF 白名单 【app\Http\Middleware\VerifyCsrfToken.php】文件
protected $except = [
'address/*',//对应路由
];
现在很多web的交互方式都是通过API接口访问的,至于API接口的安全问题,在其他专题中做专门讲解
跨域资源共享 CORS(Cross-Origin Resource Sharing)
跨域是指从一个域名的网页去请求另一个域名的资源
解决方案: 创建允许跨域的中间件,设定跨域资源共享规则
public function handle($request, Closure $next)
{
$response = $next($request);
$IlluminateResponse = 'Illuminate\Http\Response';
$SymfonyResopnse = 'Symfony\Component\HttpFoundation\Response';
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, PATCH, DELETE',
//'Access-Control-Allow-Headers' => 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Authorization , Access-Control-Request-Headers, X-CSRF-TOKEN',
'Access-Control-Allow-Headers' => '*',
'Access-Control-Expose-Headers' => '*',
'Access-Control-Allow-Methods' => '*',
'Access-Control-Allow-Credentials' => 'true',
];
if ($response instanceof $IlluminateResponse) {
foreach ($headers as $key => $value) {
$response->header($key, $value);
}
return $response;
}
if ($response instanceof $SymfonyResopnse) {
foreach ($headers as $key => $value) {
$response->headers->set($key, $value);
}
return $response;
}
return $response;
}
伪静态的设置
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Laravel 特性
生命周期
- 访问入口文件
public/index.php
- 加载 Composer 生成的自动加载器定义
- 创建应用 / 服务容器 的实例
- 服务容器:一个用于管理类依赖以及实现依赖注入的强有力工具
- 请求被发送到 HTTP 内核或者 Console 内核
- 具体取决于进入应用的请求类型,此处只讨论HTTP类型的,它位于
app/Http/Kernel.php
- Kernel继承自
Illuminate\Foundation\HTTP\kernel 类
,该类定义了一个将在执行请求之前运行的bootstrappers 数组 - Kernel扩展了父类,定义了一个 HTTP 中间件 列表
- 具体取决于进入应用的请求类型,此处只讨论HTTP类型的,它位于
- 执行handle 方法,接收
Request
接口并返回Response
接口
服务提供者
- 最重要的内核引导操作之一是为应用程序加载 service providers。应用程序的所有服务提供者都在
config/app.php
中的 providers 数组中,这是一个用来组织启动代码和容器绑定的地方 - 当
服务容器
接收到 HTTP 请求时会去执行服务提供者的 register方法,将各个服务绑定到容器内;之后,到了实际处理请求阶段,依据使用情况按需加载所需服务,也就是用到才加载,这样能够很明显提升性能 - 其实任何扩展包都不需要服务提供者,因为服务提供者只是启动服务组件并让它们可以直接使用
Facades 门面
Facades 为应用程序的服务容器
中可用的类提供了「静态代理」
项目实战
路由的定义
数据库迁移
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: