Laravel 项目开发前的准备

[TOC]

集成开发环境的安装

在学习PHP或使用PHP开发项目之前,您必须拥有对应的开发环境。
所谓开发环境就是一个支持 PHPMySQLWeb 主机
本地开发环境中您可选择安装最新版本的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;
    }

七牛云或其他oss的安装,配置

开启fileinfo扩展

composer require zgldh/qiniu-laravel-storage

在config/filesystems.php里的disks中新增如下选项

    'disks' => [
        ....
        'qiniu' => [
            'driver' => 'qiniu',
            'domains' => [
                'default' => env('QINIU_IMGS_DOMAINS_DEFAULT'), //你的七牛域名
                'https' => '',         //你的HTTPS域名
                'custom' => env('QINIU_IMGS_DOMAINS_CUSTOM'),                //Useless 没啥用,请直接使用上面的 default 项
            ],
            'access_key' => env('QINIU_ACCESS_KEY'),  //AccessKey
            'secret_key' => env('QINIU_SECRET_KEY'),  //SecretKey
            'bucket' => env('QINIU_IMGS_BUCKET'),  //Bucket名字
            'notify_url' => '',  //持久化处理回调地址
            'access' => 'public',  //空间访问控制 public 或 private
            'hotlink_prevention_key' => 'null', // CDN 时间戳防盗链的 key。 设置为 null 则不启用本功能。
//            'hotlink_prevention_key' => 'cbab68a279xxxxxxxxxxab509a', // 同上,备用
            'url' => env('QINIU_IMGS_DOMAINS_DEFAULT'),   // 填写文件访问根url
        ],
    ],

定时任务的服务器设置

crontab -e
新增项目 artisan 路径,方便后期执行定时任务

伪静态的设置

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

项目上线后的优化

1.配置优化

php artisan config:cache
php artisan route:cache
php artisan optimize --force

2、关闭APP_DEBUG

Laravel 特性

生命周期

  • 访问入口文件 public/index.php
  • 加载 Composer 生成的自动加载器定义
  • 创建应用 / 服务容器 的实例
    • 服务容器:一个用于管理类依赖以及实现依赖注入的强有力工具
  • 请求被发送到 HTTP 内核或者 Console 内核
    • 具体取决于进入应用的请求类型,此处只讨论HTTP类型的,它位于 app/Http/Kernel.php
    • Kernel继承自Illuminate\Foundation\HTTP\kernel 类,该类定义了一个将在执行请求之前运行的bootstrappers 数组
    • Kernel扩展了父类,定义了一个 HTTP 中间件 列表
  • 执行handle 方法,接收Request接口并返回Response接口

服务提供者

  • 最重要的内核引导操作之一是为应用程序加载 service providers。应用程序的所有服务提供者都在config/app.php 中的 providers 数组中,这是一个用来组织启动代码和容器绑定的地方
  • 服务容器接收到 HTTP 请求时会去执行服务提供者的 register方法,将各个服务绑定到容器内;之后,到了实际处理请求阶段,依据使用情况按需加载所需服务,也就是用到才加载,这样能够很明显提升性能
  • 其实任何扩展包都不需要服务提供者,因为服务提供者只是启动服务组件并让它们可以直接使用

Facades 门面

Facades 为应用程序的服务容器中可用的类提供了「静态代理」

项目实战

路由的定义

数据库迁移

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!