Laravel笔记

1,013 阅读9分钟
Laravel框架的特点:

所有的URL访问都必须事先定好路由规则

composer配置中国镜像

<https://pkg.phpcomposer.com/>

Composer部署Laravel项目
创建一个名为laravel的laravel项目
  • composer create-project laravel/laravel --prefer-dist ./文件名
    • composer 表示执行composer程序
    • create-project 通过composer去创建项目
    • laravel/laravel需要创建的项目名称
    • --prefer-dist 有限下载压缩包方式,而不是直接从github上下载源码
    • ./ 表示创建的项目目录名称,也可以用目录名 ,不用 ./
  • 注意:如果要下载其它的版本,比如5.4版本中最小版本号,可以使用下面这个命令
    • composer create-project laravel/laravel=5.4.* edu --prefer-dist
  • 更新composer composer self-update

目录结构分析

app目录:
  • 项目的核心目录,主要用于存放核心代码,也包括控制器、模型
    • 控制器存放位置:app\Http\Controllers
      • 控制器分目录管理:app\Http\Controllers\Auth
      • 基类控制器:app\Http\Controllers\Controller.php
    • 模型文件:app\User.php
bootstrap目录:(laravel启动目录)
  • 存放框架启动时候的目录
config目录:
  • 项目的配置目录,主要用于存放配置文件,比如数据库的配置
    • App.php 项目的主要配置文件
    • auth.php 用于定义用户认证(登录)的配置文件
    • database.php 针对数据库的配置
    • filesystems.php 上传文件,文件存储需要用到的配置文件
artisan脚手架文件:
  • 主要用于生成的代码的(自动生成),比如生成控制器,模型文件等。
    • 执行命令:php artisan
      • 注意:php必须添加环境变量,并且保证版本
      • artisan 必须存在命令行当前的工作路径下
routes目录
  • 存放路由文件
resources\views目录
  • 保存视图文件

启动方式

方式一:(不推荐使用)
  • php artisan serve
  • 注意:这种启动方式与apache是没有关系的
  • 不推荐原因:
    • 能够跑php代码,但是不启动数据库
    • 该方式启动后,如果修改项目配置.env的话,则需要重新启动
方式二:
  • 配置Apache2.4.39\conf\vhosts 文件夹下的文件,但是要确保vhosts中的文件在httpd.conf文件中引入

  • 或者配置Apache2.4.39\conf\extra\httpd-vhosts.conf文件也可以,但是要确保在httpd.conf文件中引入

  • 下面以配置Apache2.4.39\conf\vhosts\localhost_80.conf文件为例

    # 下面是 2019/10/23看视频配置的
    <VirtualHost _default_:80>
        # 站点的根目录
        DocumentRoot "E:\test\Laravel\laravel-test\public"
        # 站点需要绑定的域名
        ServerName www.jacqui.com
        # 别名 (简洁版的域名)
        ServerAlias jacqui.com
    
        FcgidInitialEnv PHPRC "D:/phpStudy/phpstudy_pro/Extensions/php/php7.3.4nts"
        AddHandler fcgid-script .php
        FcgidWrapper "D:/phpStudy/phpstudy_pro/Extensions/php/php7.3.4nts/php-cgi.exe" .php
    
      #  针对站点的详细的配置 
      <Directory "E:\test\Laravel\laravel-test\public">
          Options FollowSymLinks ExecCGI
          AllowOverride All
          Order allow,deny
          Allow from all
          Require all granted
    	  DirectoryIndex index.php index.html
      </Directory>
      ErrorDocument 400 /error/400.html
      ErrorDocument 403 /error/403.html
      ErrorDocument 404 /error/404.html
      ErrorDocument 500 /error/500.html
      ErrorDocument 501 /error/501.html
      ErrorDocument 502 /error/502.html
      ErrorDocument 503 /error/503.html
      ErrorDocument 504 /error/504.html
      ErrorDocument 505 /error/505.html
      ErrorDocument 506 /error/506.html
      ErrorDocument 507 /error/507.html
      ErrorDocument 510 /error/510.html
    </VirtualHost>
    
    • 配置完成之后,修改hosts文件(线上叫DNS域名解析)

      • win + r 输入 drivers 到达 C:\Windows\System32\drivers\etc\hosts

      • 修改该文件

        # 修改于2019/10/23
        127.0.0.1 www.jacqui.com jacqui.com
        
  • 在浏览器中输入 www.jacqui.com 或者 jacqui.com 能访问成功,说明配置成功了

路由

定义
将用户的请求,按照事先规划的方案提交给指定的控制器或者功能函数来进行处理【路由就是访问地址的形式】
  1. 路由配置文件
    • 地址:router/web.php
  2. 路由定义的格式
    • Route::请求方式('请求的URL', 匿名函数或控制响应的方法);
    // 根路由
    Route::get('/', function () {
        return view('welcome');  // 函数的返回值就是请求的响应 ==>resources\views\welcome.blade.php
    });
    
    • 访问 /home 地址

      // 访问 /home  ‘/’可加可不加,建议加上
      Route::get('/home', function () {
          // return view('welcome');
          echo '当前访问的是home视图';
      });
      
  3. 路由请求方式
    • 有时候注册路由响应多个HTTP请求----可以通过 match 或 any 注册一个路由来响应所有HTTP请求

      match 表示匹配自己定义的请求方式的路由
      Route::match(['get','post'],'/',function() {
          
      })
      
      any 表示匹配任意请求方式的路由
      Route::any('/',function() {
          
      })
      
路由参数
  • 路由参数其实就是给路由传递参数,参数分为必选参数和可选参数

    • 必选参数 {参数名}

      • Route::get('user/{id}', function ($id) { 
           return 'User '.$id;
         });
         
         在浏览器中输入 http://jacqui.com/user/1
        
    • 可选参数 {参数名?} 可选参数需要设置默认值,否则会报错

      • // 可选参数
        Route::get('test2/{id?}', function ($id = '') {
            // return view('welcome');
            // echo `当前用户的id是${$id}`;
            echo '当前用户的id是:'.$id;
        });
        
    • 通过 ? 形式传递get参数

      • // 通过 ? 形式传递get参数
        Route::get('/test3', function () {
            // return view('welcome');
            // echo `当前用户的id是${$id}`;
            echo '当前用户的id是:' . $_GET['id'];
        });
        
路由别名
  • // 路由重命名
    Route::get('/test4', function () {
        // return view('welcome');
        // echo `当前用户的id是${$id}`;
        echo '当前用户的id是:' . $_GET['id'];
    }) -> name('aaa');
    
  • 查看路由的命令

    • 在项目根目录,打开命令行工具 ==》php artisan ==》会出现一系列的命令 ==》找查看路由的命令
      • php artisan route:list
路由群组

Route::group(公共属性数组,回调函数)

// 路由群组
Route::group(['prefix' => 'admin'],function() {
    Route::get('test1', function () {
        // /admin/test1
        echo '当前页面是/admin/test1';
    });
    Route::get('test2', function () {
        // /admin/test2
        echo '当前页面是/admin/test2';
    });
});

控制器

注意:控制器基础结构代码,不需要自己去手动解决,可以通过artisan命令来自动生成

  • php artisan make:controller TestController

  • 控制器路由

    • 使用上面的命令,创建一个控制器

    • 在创建的控制器中使用路由

    • class TestController extends Controller
      {
          // 测试控制器路由的使用
          public function test1() {
              return phpinfo();
          }
      }
      
    • 在web.php中写控制器路由Route::请求方式('路由','控制器@方法')

      // 控制器路由的写法
      // Route::get('/home/test/test1','控制器@方法')
      Route::get('/home/test/test1','TestController@test1');
      

控制器分目录管理

  • 手动在Controller文件夹下创建用于目录管理的文件夹
  • 使用命令创建管理器
    • php artisan make:controller 目录名/控制器名

分目录路由管理

  • web.php写路由规则

  • // 分目录路由管理
    Route::get('路由地址表达式,'分目录名称\控制器名称@方法名');
    Route::get('/backEnd/test','BackEnd\TestController@test1');
    

接受用户输入

  • laravel如果需要使用 facades 的话,但是又不想写那么长的引入操作:

    • 在config/app.php中定义别名:

      •  // 自己添加的别名
         'Input' => Illuminate\Support\Facades\Request::class,  
              Illuminate\Support\Facades\Input::class // 会报错
        
    • 在控制器文件中引入,接受用户输入参数的类

      • 写法一:use Illuminate\Support\Facades\Input;
      • 写法二:use Input;
    • 在控制器中写下面的函数

      // Input获取参数
      public function testParams() {
      	// 获取一个值,如果用户在浏览器中没有输入,则使用第二个参数当默认值        
      	echo Input::get('id','10088');
      }
      
  • 获取用户请求的url中参数信息(下面的方法既可以获取get中的信息也可以获取post中的信息)

    • Input::get('参数的名字','如果参数没有被传递,使用该默认值')

    • Input::all(); 获取所有的用户输入

      •  // 获取全部的值(数组形式返回)
         $all = Input::all();
         var_dump($all);
         
         或者使用下面的方式:
         dd($all); // dump+die 后续的代码不会执行
        
        
        
    • Input::get(); 获取单个的用户输入

    • Input::only([]); 获取指定几个的用户输入

    • Input::has('name'); 判断某个输入的参数是否存在

DB类操作数据库(重点)

laravel中DB类的基本用法:DB::table('tableName') 获取操作tableName表的实例

数据库的配置文件在 项目根目录的.env文件中

  • 使用Navacate创建数据库
  • 在项目根目录下找到数据库的配置文件,将默认的数据库名改为自己创建的数据库的名字
  • 尽量关掉 config/database.php中的严格模式 ==>'strict' => false,
  • 在控制器中引入DB门面
    • 注意:如果想要引入别名,首先需要看config/app.php中是否已经事先定义

增加

主要有两个函数可以实现:insert()insertGetId()

  • insert(数组) 可以同时添加一条或多条,返回的值是布尔值

     // DB数据库的增删改查
        public function add() {
            // 定义操作的表
            // DB::table('laravel_table') -> insert() 链式操作
            $db = DB::table('laravel_table');
    
            $res = $db -> insert([
                [
                    'id' => 1,
                    'name' => '张三',
                    'age' => 20,
                    'email' => '123@163.com'
                ], [
                    'id' => 2,
                    'name' => '李四',
                    'age' => 99,
                    'email' => 'jacqui@163.com'
                ]
            ]);
            dd($res);
        }
    
    • insertGetId(一维数组) 只能添加一条数据,返回自增的id

    •  // DB数据库的增删改查
          public function add() {
              // 定义操作的表
              // DB::table('laravel_table') -> insert() 链式操作
              $db = DB::table('laravel_table');
              $res = $db -> insertGetId([
                  'id' => 3,
                  'name' => '王五',
                  'age' => 20,
                  'email' => '123@163.com'
              ]);
              dd($res);
          }
      

修改

数据修改可以使用update(),increment()和decrement()函数来实现

  • update()可以修改整个记录中的全部字段

    • // DB数据库的修改
          public function update() {
              $db = DB::table('laravel_table');
              // 把id =1的名称改为 aa
              // -> where('参数','运算符''值')  如果第二个参数是等于号,可以省略不写
              $rest = $db -> where('id','1') -> update([
                  'name' => 'aa'
              ]);
              dd($rest); // 返回的结果是受到影响的行数
          }
      
  • incrementdecrement 表示修改数字字段的数值(递增或者递减) 典型的应用,记录登录次数,积分增加

    •  DB::table('数据表名') -> increment('votes'); votes每出现一次 +1
       DB::table('数据表名') -> increment('votes',5); votes每出现一次 +5
        
       DB::table('数据表名') -> decrement('votes'); votes每出现一次 -1  
       DB::table('数据表名') -> decrement('votes',5); votes每出现一次 -5
      

查询

// DB数据库的查询
    public function select() {
        $db = DB::table('laravel_table');
        
        $res = $db -> get();

        foreach ($res as $key => $value) {
            echo "id:{$value -> id},name:{$value -> name}";            
        };

        dd($res);
    }
并的条件
-> where() -> where() .... and语法
-> where() -> orWhere() -> orWhere ... or(或者)的关系

 $res_and = $db -> where('id','>','1') -> where('name','李四') -> get();
获取单行查询(等价于limit = 1)
$res_and = $db -> where('id','>','1') -> first();
dd($res_and);
获取某个具体的值
 // 获取单个值
 $res_and = $db -> where('id','>','1') -> value('name');
 dd($res_and);
排序操作
// 排序操作
$val_order = $db -> orderBy('age','desc') -> get();
dd($val_order);
分页操作
// 分页操作
$val_limit = $db -> limit(3) -> offset(3) -> get();
dd($val_limit);

// limit 表示限制输出的条数
// offset 从什么地方开始输出

删除

// 删除
 $db = DB::table('laravel_table');
 $del_val = $db -> where('id','0') -> delete();
 echo $del_val; // 返回的结果是受到影响的行数

视图操作(重点)

视图所在目录:resource/views,视图在该目录下是可以进行分目录管理的

视图文件的命名和渲染

  • 文件名习惯小写,建议小写
  • 文件名的后缀是.blade.php 因为laravel里面有一套模板引擎就是使用blade,可以直接使用标签语法{{ $title }} 也可以使用原生的php语法显示数据
  • 可以使用.php 结尾,但是这样的话,就不能使用laravel提供的标签语法显示数据,只能使用php原生的语法显示数据 <?php echo ''; ?>
  • 两个视图文件同时存在,则 .blade.php 后缀的优先显示

视图的创建与展示

  1. 首先在routes/web.php 中定义路由 Route::路由请求的方法('路由名称','控制器名称@方法')

     // 展示视图
     Route::get('show_views','TestController@show_views');
    
  2. Controllers/TestController.php 文件中写方法,展示视图

    return view(视图名称)

    // 展示视图
    public function show_views() {
    	return view('home/test'); // view('视图名称')
    }
    
  3. resources/views 下新建目录 home->test.blade.php 文件

变量分配与展示

语法:
  1. view('模板文件名称','数组') 数组就是需要分配的变量集合,是一个键值数组,键的名字尽量与值的名字保持一致

    • 在控制器中传递变量

      $date = date('Y-m-d H:i:s',time());
      $day = '四';
      return view('home/test',['date' => $date,'day' => $day]); // view('视图名称')
      
    • 在视图中,展示传递的变量

       <h1>我是php 日期: {{ $date }} <br /> 今天是周:{{ $day }}</h1>
      
  2. view('模板文件名称') -> with(数组)

compact()的用法
$date = date('Y-m-d H:i:s',time());
$day = '四';    
dd(compact('date','day')); // 返回的是一个键值对形式的数组

模板中使用函数

 $time = strtotime('+1 year'); // 获取上一年的时间戳('+1 year') 上一月 ('+1 month') 上一周 ('+1 week') 相反获取一年前 对应-1
 return view('home/test',compact('time')); 
 
 
 在对应的视图中展示:
 <h3>一年之后的时间戳是:{{ date('Y-m-d H:m:s') , $time }}</h3>

strtotime()的用法

$time = strtotime('+1 year'); // 获取上一年的时间戳('+1 year') 上一月 ('+1 month') 上一周 ('+1 week') 相反获取一年前 对应-1

laravel中循环的写法

  • php中foreach循环

    foreach($var as $key => $val) {
        循环体
    }
    
  • laravel中foreach循环的写法

    @foreach($var as $key => $val)
    	循环体
    @endforeach
    

模板继承/包含

继承语法
子模版中按以下语法书写:
	@extends('需要继承的模板文件名');
通过section标签绑定区块/部件到父级页面,区块名称就是父级页面yield标签的参数名。
 	@section(区块代码)
 		代码
 	@endsection
  1. 新建视图views/home/parent.blade.php

    @extends('home/child') // 引入公共的部分比如页面共同的头部,和尾部
    
    @section('mainbody') // 绑定区块,区块名称就是父级页面yield标签的参数名
    	我是内容 // 代码块
    @endsection
    
    // 文件的包含
    @include('文件路径');// 想要将某一个页面,在本页面中显示
    @include('component.dialog');// views/component/dialog.blade.php
    
  2. 新建视图views/home/child.blade.php

    <h1>我是头部</h1>
    
        @yield('mainbody')    
    
    <h3>我是尾部</h3>
    

CSRF攻击

CSRF是跨站请求伪造(Cross-site request forget)的英文缩写
Laravel框架中避免CSRF攻击很简单,Laravel自动为每个用户Session生成了一个CSRF Token,该Token可用于验证登录用户和发起请求者是否是同一个人,如果不是则请求失败【该原理和验证码的原理是一致的】
Laravel提供了一个全局帮助函数csrf_token来获取该Token值,因此只需在视图提交表单中添加下面的代码

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>" />

csrf_token()和csrf_fileld()的区别

  • csrf_token 只能输出token的值
  • csrf_field 输出了整个的input隐藏域

从CSRF验证中排除例外路由(既是:给路由添加白名单)

并不是所有请求都需要避免CSRF攻击,则需要在 
app/Http/Middleware/VerifyCsrfToken.php


protected $except = [
     // 'home/xxx.php'
];

如果需要排除全部路由使用csrf的话,则可以写成:
	protected $except = [
        '*'
    ];

自动验证(重点)

一般一个框架都会提供自动验证的机制,在TP里面的验证的规则是写在模型里面进行验证的,但是自laravel里面的思想有些不一样,它的验证规则可以在控制器里面,也可以单独的写一个专门的验证文件。并且laravel里买按的验证不通过情况下的提示信息和表单数据是保存在session里面的,并且验证不通过的情况下会跳到上一个页面

在前端页面中可以通过js验证表单的数据有效性,但是如果用户的浏览器版本过低或者直接禁用js,则前端验证则可能会失效,这样就不能保证数据的有效性。所以后端也需要最相应的验证操作,这个操作在Laravel中称之为自动验证