laravel框架的课堂知识点概总

1. MVC

1.1 概念理解

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑

MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式:

  • Model(模型)表示应用程序核心(比如数据库记录列表)。

  • View(视图)显示数据(数据库记录)

  • Controller(控制器)处理输入(写入数据库记录)。

  • MVC 模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制

  • Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。

  • View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。

  • Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

1.2 实践

开发模式

数据库中的一张表对应一个控制器类,对应一个模型类,对应多个视图
对表的多个操作都会封装成控制器类中的方法
所有针对数据库的操作应该放到模型类中
模型类中会定义增删改查等方法
不要试图直接访问html静态文件,而是访问入口文件,然后通过参数指定要访问的控制器和方法名称,控制器中的方法再负责将html文件展示给我们

smarty

将压缩包解压后,将libs 文件夹拷贝到项目的根目录下,并重命名为 smarty,然后在控制器类中引入 Smarty.class.php

创建模型类 NewsModel.php

<?php
class NewsModel
{
    function list() {
        $dns = "mysql:host=localhost;dbname=test";
        $user = 'root';
        $password = 'root';
        $pdo = new PDO($dns, $user, $password);
        $res = $pdo->query("select * from news");
        $news = $res->fetchAll(PDO::FETCH_ASSOC);
        return $news;
    }
}

创建控制器类,NewsController.php

<?php
include 'smarty/Smarty.class.php';
include 'NewsModel.php';
class NewsController
{
    // 显示所有的新闻数据
    public function index()
    {
        // 创建NewsModel类的对象
        $model = new NewsModel();
        $news = $model->list();
        // 创建Smarty 类的对象
        $smarty = new Smarty();
        $smarty->assign("news", $news);
        // 读取news.html文件的源代码,并发送给浏览器
        $smarty->display('news.html');
    }
}

list.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet">
</head>
<body>
  <div class="container">   
  <table class="table">
    <tr>
      <th>编号</th>
      <th>标题</th>
      <th>创建时间</th>
    </tr>
   {foreach $news as $item}
   <tr>
     <td>{$item['id']}</td>
     <td>{$item['title']}</td>
     <td>{$item['create_time']}</td>
   </tr>
   {/foreach}
  </table>
  </div>
</body>
</html>

在浏览中要直接访问控制器,因为控制器是模型与视图的桥梁

  • 控制器负责调用模型中的方法,查询数据
  • 控制器将模型中返回的数据分配给视图
    但是我们无法在浏览器中直接访问某个控制器类中的具体方法

解决方案

在项目的根目录下,新建一个 index.php

在这个文件中,获取用户想要访问的控制器和方法名称,并进行调用

<?php
include 'NewsController.php';
// 获取请求的控制器名称
$c=$_GET['c'];
// 获取请求的方法名称
$a=$_GET['a'];
// 创建控制器类的对象
$ctrl=new $c();
// 调用请求的方法
$ctrl->$a();

说明:这个 index.php 有一个专业的名词:入口文件

地址栏中输入如下地址方法

http://localhost/index.php?c=newscontroller&a=index

2. 下载和安装composer

Laravel 使用 Composer 来管理项目依赖。因此,在使用 Laravel 之前,请确保你的机器已经安装了 Composer

composer 是用来管理php开发过程中用到的一些包的工具,可以叫做包管理工具

在很多语言中都有类似与 composer 的包管理工具

  • maven:java
  • nuget:net
  • npm:node
  • composer:php

2.1 使用安装程序

通过如下地址,下载 composer 的安装包

https://getcomposer.org/download/

然后一路默认安装即可

2.2 命令行安装

按照如下地址给出的方法安装即可

https://pkg.phpcomposer.com/#how-to-install-composer

2.3 安装阿里云镜像

由于众所周知的原因,需要安装阿里云镜像

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

3. 创建laravel项目

两种方式

  • laravel 安装器
  • composer 安装
    除了上面两种方式,还可以来如下网址自己下载 laravel 框架

https://github.com/laravel/laravel

但是这种方式下载的仅仅是一个目录结构,一些依赖包还需要我们使用 composer 去下载,所以更加推荐 composer 安装

3.1 laravel 安装器

首先执行如下命令,安装

composer global require "laravel/installer"

安装过程如下

mark

然后执行如下命令,创建项目

laravel new demo1

3.2 composer 创建项目

参考资料

https://learnku.com/laravel

说明:创建laravel 项目一定要选择一个英文目录

执行如下命令

composer create-project --prefer-dist laravel/laravel demo1

安装过程如下

mark

3.3 启动项目

进入到刚刚创建的项目下,运行如下命令,会默认在8000端口上开启服务

php artisan serve

可以使用如下命令自定义端口

php artisan serve --port=8888

也可以通过如下方法,改变主机地址

php artisan serv --host=localhost

4. 数据库配置

数据库的配置存储于 database.config 中

但 database.config 中又读取了 .even 中的数据

所以需要修改 .env 中的数据库配置

修改完成后,执行如下命令,在指定的数据库中创建表

php artisan migrate:install

如果创建成功,则表明数据库配置搞定了

5. 路由

laravel 的目的是开发项目,一个项目肯定有很多功能,有很多页面组成

与前面 MVC 中的 index.php 一样,laravel 中有一种机制能够根据用户请求的地址的不同,返回不同的页面(功能),这种机制就是路由

当前我们还是循序渐进的讲-- 首先测试一下,根据不同的请求返回不同的简答内容

laravel 框架的路由文件 routes/web.php

5.1 使用闭包返回简单内容

这种路由形式适合返回简单内容

Route::get('/hello',function(){
    return 'hello';
});

5.2 使用闭包返回视图

这种方式可以返回更多的内容

比如返回一个视图

Route::get('/user', function () {
    return view('user');
});

但是这种方式只能返回静态的html内容

5.3 执行控制器中的方法

事实上,在实际的开发中,我们更加常用的方式是,每个url定位到不同的控制器中的方法

也就是说,当我们请求某个地址时,不会通过view方法直接返回一个视图,而是首先执行某个控制器类中的某个方法,然后这个方法再返回视图

再 app\http\controllers 目录下创建一个控制器文件

输入如下命令

 php artisan make:controller NewsController

然后再web.php 中配置如下路由

Route::get('/news', '\App\Http\Controllers\[email protected]');

说明:先忽略关于命名空间和请求方式的问题

在当前项目目录下,运行如下命令,创建控制器

php artisan make:controller UsersController

编写代码如下

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UsersController extends Controller
{
    public function index(){     
        return view('users/index');
    }
}

6. 向视图传递参数

6.1 传递静态数据

<?php

namespace App\Http\Controllers;

class NewsController extends Controller
{
    public function index()
    {

        // return view('news',['name'=>'onlifes']);

        // $arr=[
        //     'name'=>'李白',
        //     'age'=>18,
        //     'address'=>'四川'
        // ];
        // return view('news',['name'=>$arr]);

        $arr = [
            ['name' => '李白', 'age' => 18],
            ['name' => '杜甫', 'age' => 20],
        ];
        return view('news',['name'=>$arr]);
    }
}

视图代码

 <table>
    @foreach ($name as $item)
    <tr>
      <td>{{$item['name']}}</td>
      <td>{{$item['age']}}</td>
    </tr>
    @endforeach
  </table>

6.2 传递动态参数

6.2.1 执行原生sql语句

6.2.2 eloquent orm

配置数据库连接

在项目根目录下找到 .env 文件

mark

改完后重启服务

运行如下命令,创建一个模型类

mark

然后再NewsController 的index 方法中编写如下代码

$arr=Article::all();
return view('news',['name'=>$arr]);
在 resources/views 目录下创建 news.blade.php,

<body>

  <table>
   @foreach ($name as $item)
<tr>
  <td>{{$item->id}}</td>
  <td>{{$item->title}}</td>
  <td>{{$item->create_time}}</td>
</tr>
   @endforeach
</body>

7. 文章CRUD

创建名为 news 的数据库

创建名为 news 的项目

PS D:\developer\laravel> composer create-project --prefer-dist laravel/larave/ news

7.1 数据库迁移

配置数据库连接

首先在 .env 中配置数据库连接信息

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=news
DB_USERNAME=root
DB_PASSWORD=root

创建数据库迁移文件

运行如下命令,创建数据库迁移文件

 php artisan make:migration create_post_table

编辑数据库迁移文件

 public function up()
    {
        Schema::create('post', function (Blueprint $table) {
            $table->increments('id');
            $table->string("title")->default('');
            $table->string("content")->default('');
            $table->timestamps();
        });
    }

运行数据库迁移文件

运行如下命令,执行数据库迁移文件

 php artisan migrate

可能会出现如下的错误提示

mark

错误原因在于laravel 框架赋予字段你的默认长度超过了mysql数据库允许的字段的最大长度,解决方法是设置 laravel 框架中字段的默认长度不要超过mysql 的长度

在 app\providers 目录下的 AppServiceProvider 文件中的 boot 函数中,加入如下代码

 public function boot()
    {
        // 设置字段默认长度
        Schema::defaultStringLength(200);
    }

重新运行如下的命令

 php artisan migrate

又出现错误如下

SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists

原因在于数据库中已经存在响应的表了,删除这些表,然后重新执行数据库迁移文件

mark

如何添加新的字段

现在想为 Post 表添加一个字段

mark

代码修改好后,重新运行数据库迁移

php artisan migrate

提示没有迁移任何内容

解决方案是在数据库中删除 post 表,并将 migrations 表中的对应数据删除,然后重新运行数据库迁移即可

再创建新的表

创建数据库迁移文件

 php artisan make:migration post_type_table

修改数据库迁移文件

class PostTypeTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_type', function (Blueprint $table) {
            $table->increments('id');
            $table->string("title")->default('');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_type');
    }
}

执行数据库迁移

php artisan migrate

7.2 梳理步骤

创建数据库

news

配置数据库连接信息

.env 中配置

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=news
DB_USERNAME=root
DB_PASSWORD=root

创建数据库迁移文件

 public function up()
    {
        // 创建数据库
        Schema::create('post', function (Blueprint $table) {
            // 创建 id 字段,并设置为主键,且自动增长
            $table->increments('id');
            // 创建title字段,类型为varchar类型,长度100,且默认值为空字符串
            $table->string('title',100)->default('');
            $table->string('content')->default('');
            $table->integer('user_id')->default(0);
            $table->timestamps();
        });
    }

设置默认长度

\App\Providers\AppServiceProvder.php 中设置

 public function boot()
    {
        // 设置字段默认长度
        Schema::defaultStringLength(200);
    }

运行数据库迁移

 php artisan migrate

7.3 展示文章新闻
创建模型

php artisan make:model Post

创建控制器

php artisan make:controller PostController

编写控制器中的 index 方法

// 展示文章列表
public function index()
{
    $posts=Post::all();
    return view('post/index',['posts'=>$posts]);
}

配置路由

use Illuminate\Support\Facades\Route;

Route::get('/posts','\App\HttP\Controllers\[email protected]');

创建视图

在 views 目录下创建 post 目录,然后再post目录下创建 index.blade.php 文件

<div class="container">
<a href="/posts/add">添加文章</a>

<h2>文章列表</h2>
<table class="table">
<tr>
  <th>编号</th>
  <th>标题</th>
  <th>内容</th>
  <th>创建时间</th>
  <th>操作</th>
</tr>
@foreach($posts as $item)
<tr>
  <td>{{$item->id}}</td>
  <td>{{$item->title}}</td>
  <td>{{$item->content}}</td>
  <td>{{$item->created_at}}</td>
  <td>
  <a href="" class="btn btn-info">编辑</a>
  <a href="" class="btn btn-danger">删除</a>
  </td>
</tr>

@endforeach
</table>
</div>

7.4 新增数据
注意:以后新增数据要分两个方法进行,一个方法用于展示新增数据的视图;一个方法用于将表达数据源保存到数据库中

add方法

此 方法用于展示新增数据的视图

// 展示添加文章的界面
public function add(){
    return view('post/add');
}

配置路由

// 展示用于添加文章的界面
Route::get('/posts/add','\App\HttP\Controllers\[email protected]');

创建视图 add

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <style>
  .box{
    margin-top: 100px;
  }
  
  </style>
</head>
<body>
<div class="container box">
<form action="/posts" method="post" class="form-horizontal">
  <div class="form-group">
    <label for="title" class="col-sm-2 control-label">标题</label>
    <div class="col-sm-10">
      <input type="text" name="title" id="title" class="form-control">
    </div>
  </div>
  <div class="form-group">
    <label for="content" class="col-sm-2 control-label">内容</label>
    <div class="col-sm-10">
    <textarea class="form-control" name="content" id="content" rows="3"></textarea>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-default">保 存</button>
    </div>
  </div>
</form>
</div>

</body>
</html>

store方法

此方法用于新增数据

 // 新增文章
    public function store(){
        return 'store';
    }

配置路由

// 新增文章数据
Route::post('/posts','\App\HttP\Controllers\[email protected]');

CSRF

表单中数据如数据,点击保存后,会出现如下错误

mark

解决方案,在新增文章的表单中,加入如下代码

mark

解释:

CSRF:跨站请求伪造,是一种利用服务器对客户端的信任,发起攻击方式

然后修改 store 方法代码,实现新增数据

 public function store()
    {
        $model = new Post();
        $model->title = request('title');
        $model->content = request('content');
        $res = $model->save();
        if ($res) {
            return redirect('/posts');
        } else {
            return redirect('/posts/add');
        }
    }

7.5 编辑文章

两个方法

  • 展示待编辑ide数据
  • 更新数据
    展示待编辑数据

创建 edite 方法

  // 展示待编辑的数据
    public function edite(Post $post){
        return view('post/edite',['post'=>$post]);
    }

配置路由

// 展示待编辑数据
Route::get('/posts/{post}/edite','\App\HttP\Controllers\[email protected]');

更新 index 视图

mark

创建 edite 视图

直接将 add 视图拷贝过来,为表单控件设置 value 属性即可

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <style>
  .box{
    margin-top: 100px;
  }
  
  </style>
</head>
<body>
<div class="container box">
<form action="/posts" method="post" class="form-horizontal">
{{csrf_field()}}
  <div class="form-group">
    <label for="title" class="col-sm-2 control-label">标题</label>
    <div class="col-sm-10">
      <input type="text" name="title" id="title" class="form-control" value="{{$post->title}}">
    </div>
  </div>
  <div class="form-group">
    <label for="content" class="col-sm-2 control-label">内容</label>
    <div class="col-sm-10">
    <textarea class="form-control" name="content" id="content" rows="3">
{{$post->content}}
    </textarea>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-default">保 存</button>
    </div>
  </div>
</form>
</div>

</body>
</html>

更新数据

请求方式:

  • get:获取数据
  • post:新增数据
  • put:更新数据
  • delete:删除数据
    通过form 的 method 属性只能设置 get 和 post 请求,如果设置 put 和 delete 请求

如果确实想发送 put 或者 delete 请求,需要使用表单伪造的方式

mark

创建 update 方法

// 更新数据
    public function update(){
        $id=request('id');
        $model=Post::find($id);
        $model->title=request('title');
        $model->content=request('content');
        $res=$model->save();
        if ($res) {
            return redirect('/posts');
        } else {
            return redirect('/posts/'.$id.'/edite');
        }

    }

配置路由

// 更新文章数据
Route::put('/posts','\App\HttP\Controllers\[email protected]');

7.6 删除文章信息

创建方法

 // 删除文章数据
    public function delete(Post $post)
    {
        $res = $post->delete();
        return redirect('/posts');

        // $model=Post::find($post);
        // $model->delete();
    }

配置路由

// 删除数据
Route::get('/posts/{post}/delete','\App\HttP\Controllers\[email protected]');

修改 index.blade.php 中的 删除 按钮

mark

8. 文章类型CRUD

8.1 生成数据库

创建数据库迁移文件

mark

运行数据库迁移

mark

8.2 创建模型
mark

创建模型注意事项

  • 表名为复数形式,模型名称为单数形式
  • 表名如果是多个单词组成,且中间有下划线,如 post_types,则模型名称使用单数形式,且每个单词首字母大写,并去除下划线,如 PostType

8.3 创建控制器

一般一个功能模块对应一个控制器

mark

8.4 配置路由

打开项目根目录下的 routes 目录下的 web.php 文件,配置路由

mark

8.5 展示列表信息

// 展示文章类型列表信息
    public function index()
    {
        $types=PostType::all();
        return view('posttype/index',['$types'=>$types]);
    }

在 resouces/views 目录下,创建 posttype 目录,然后在其中创建 index.blade.php

index.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<a href="/post_types/add">添加类型</a>

<h2>文章列表</h2>
<table class="table">
<tr>
  <th>类型编号</th>
  <th>类型名称</th>
  <th>创建时间</th>
  <th>操作</th>
</tr>
@foreach($types as $item)
<tr>
  <td>{{$item->id}}</td>
  <td>{{$item->title}}</td>
  <td>{{$item->created_at}}</td>
  <td>
  <a href="/post_types/{{$item->id}}/edite" class="btn btn-info">编辑</a>
  <a href="/post_types/{{$item->id}}/delete" class="btn btn-danger">删除</a>
  </td>
</tr>

@endforeach
</table>
</div>

</body>
</html>

8.6 增加

展示增加页面

add.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <style>
  .box{
    margin-top: 100px;
  }
  
  </style>
</head>
<body>
<div class="container box">
<form action="/post_types" method="post" class="form-horizontal">
{{csrf_field()}}
  <div class="form-group">
    <label for="title" class="col-sm-2 control-label">类型名称</label>
    <div class="col-sm-10">
      <input type="text" name="title" id="title" class="form-control">
    </div>
  </div>
  
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-default">保 存</button>
    </div>
  </div>
</form>
</div>

</body>
</html>

PostTypeController 控制器中加入 store 方法

//新增数据
public function store(){
    // dd(request()->all());
    $model=new PostType();
    $model->title=request('title');
    $res=$model->save();
    if($res){
        return redirect('/post_types');
    }else{
        return redirect('/post_types/add');
    }
}

9. 前后端分离开发中的laravel

在实际的开发当中,前端和后端的开发会同步进行

后台人员新建laravel项目,编写控制器和模型(视图),用于向前端同学提供数据,或者收集前端同学提供的数据

前端人员新建web或者android或者ios 等项目,用于获取后台人员提供的数据,渲染界面

前端和后端程序之间使用 ajax 的方式交互数据

9.1 新建项目

新建前端项目 news_client 和 后端laravel项目 news_server

mark

9.2 文章列表展示

9.2.1 前端代码编写

在 news_client 项目中,新建 index.html

html 代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>
  <div class="container">
    <button class="btn btn-primary" data-toggle="modal" data-target="#myModal">添加文章</button>
    <table class="table">
      <thead>
        <tr>
          <th>编号</th>
          <th>标题</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>

      </tbody>
    </table>

  </div>

  <!-- 添加文章模态框 -->
  <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
              aria-hidden="true">&times;</span></button>
          <h4 class="modal-title" id="myModalLabel">添加文章</h4>
        </div>
        <div class="modal-body">
          <form id="form1" class="form-horizontal">

            <div class="form-group">
              <label for="inputEmail3" class="col-sm-2 control-label">标题</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" name="title" id="title" placeholder="请输入文章标题">
              </div>
            </div>
            <div class="form-group">
              <label for="content" class="col-sm-2 control-label">内容</label>
              <div class="col-sm-10">
                <textarea name="content" class="form-control" id="content" cols="30" rows="10"></textarea>
              </div>
            </div>

          </form>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
          <button type="button" class="btn btn-primary" id="btn-save">保 存</button>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

说明:

html 代码中已经加入了用于添加文章的模态框
为“添加文章”按钮,添加了如下两个属性,作用是点击此按钮能够显示和隐藏模态框

data-toggle="modal" data-target="#myModal"

js 代码

loadData();
  function loadData() {
    // 清除tbody 中的数据
    $('tbody tr').remove()
    $.ajax({
      url: 'http://127.0.0.1:8000/posts',
      type: 'get',
      dataType: 'json',
      success: function (res) {
        $(res).each(function (index, domEle) {
          // console.log(domEle)
          var tr = `
          <tr>
            <td>${domEle.id}</td>
            <td><a href="#">${domEle.title}</a></td>
            <td>
              <button class="btn btn-primary edite">编辑</button>
              <button class="btn btn-danger del" data-id="${domEle.id}">删除</button>
            </td>
          </tr>
          `;
          $('tbody').append(tr)
        })
      }
    })
  }

说明:

使用a标记将标题包含起来,点击文章标题可以跳转到文章详情展示页面,这里使用超链接跳转即可,不需要使用 ajax 方式

9.2.2 后端代码编写

创建路由

use Illuminate\Support\Facades\Route;
// 获取所有的文章信息
Route::get('/posts','[email protected]');

创建模型

 php artisan make:model Post

创建控制器

 php artisan make:controller PostController

编写 index 方法代码

// 获取所有文章信息
public function index()
{
    $res = Post::all();

    return response()->json($res);
}

此时请求,会产生跨域问题

跨域解决方案

利用 CORS 跨域资源共享

简单的说就是在被请求数据的网站中设置允许其他网站请求数据

创建中间件 CORS

 php artisan make:middleware Cors

上面命令会在 App\Http\Middleware 目录下创建 Cors.php 文件,在 handle 方法中编写如下代码

 public function handle($request, Closure $next)
    {
        $response = $next($request);
        // 允许任何网站访问本网站的数据
        $response->header('Access-Control-Allow-Origin', '*');
        $response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept');
        $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
        $response->header('Access-Control-Allow-Credentials', 'false');
        return $response;
    }

注册中间件

在 app\http 的 kernel.php 文件中 的 $middleware 属性中,加入如下代码

mark

重新请求即可实现跨域访问

9.2 新增数据

9.2.1 前端代码

添加文章模态框已经在上一节编写完毕

这里只列出相关js代码即可

js 代码

$('#btn-save').on('click', function () {
    var data = { title: $('#title').val(), content: $('#content').val() }
    $.ajax({
      url: 'http://127.0.0.1:8000/posts',
      type: "post",
      data: data,
      dataType: 'json',
      success: function (res) {
        if (res.error == 0) {
          // 重新加载数据
          loadData();
          // 关闭模态框
          $('#myModal').modal('hide')
        }
      }
    })
  })

9.2.2 后端代码

添加方法 在 PostController 控制器中编写方法

public function store()
{
    $title = request('title');
    $content = request('content');
    $model = new Post();
    $model->title = $title;
    $model->content = $content;
    $res = $model->save();
    if ($res) {
        return response()->json([
            'error' => 0,
            'msg' => 'success',
            'data' => null,
        ]);
    } else {
        return response()->json([
            'error' => 201,
            'msg' => 'error',
            'data' => null,
        ]);
    }
}

配置路由

// 新增数据
Route::post('/posts','[email protected]');

添加例外

运行添加文章后,浏览器控制台中出现如下错误

mark

错误原因是:laravel 开启了 CSRF 防护,也就是说当其前端以 post、delte 或者 Put 方式访问路由的时候,就会收到 CSRF 保护,就是要求提供一个令牌,如果没有令牌,则就会报 419

解决方法:指定某些路由不需要CSRF防护

在 Http\Middleware 目录下的 verifycsrgtoken.php 中的 except 属性中加入想要不受保护的路由

mark

此时重新添加文章即可

9.3 删除文章

9.3.1 前端代码

这里只列出 js 代码,html 代码参考 第一节

// 使用委派的方式添加单击事件
  $('tbody').on('click','.del', function () {
    var id = $(this).data('id');
    $.ajax({
      url:`http://127.0.0.1:8000/posts/${id}`,
      type:'post',
      data:{_method:"DELETE"},
      dataType:"json",
      success:function(res){
        if (res.error == 0) {
          // 重新加载数据
          loadData();
        }
      }
    })
  })

代码的解释参见 9.3.3 请求方法详解

9.3.2 后台代码
删除方法

在 PostController 控制器中添加如下方法

public function delete(Post $post)
{
    $res = $post->delete();
    if ($res) {
        return response()->json([
            'error' => 0,
            'msg' => 'success',
            'data' => null,
        ]);
    } else {
        return response()->json([
            'error' => 201,
            'msg' => 'error',
            'data' => null,
        ]);
    }
}

配置路由

Route::delete('/posts/{post}','[email protected]');

CSRF忽略

在 VerifyCsrfToken.php 文件中进行如下配置

protected $except = [
    //        
    '/posts/*',
    '/posts',
];

9.3.3 请求方法详解

在以前的课程中,我们的原则是如果从服务器获取数据,就使用 get 方法,如果向服务器发送数据,就使用 post 方式。但是按照现在流行的方式来看,同样是向服务器发送数据,也分几种情况

  • 增加数据,使用 post
  • 更新数据,使用 put
  • 删除数据,使用 delete
    这三种方式与 get 方式一样,也都是http协议支持的请求方式

但是,不能直接将 type 的值设置为 delete,这样并不能访问到服务器端配置的如下路由

Route::delete('/posts/{post}','[email protected]');

需要如下的方式才能发送 delete 请求

设置 type 的值为 post
在 data 中设置 _method 为 delete
关于发送 put 请求 也是使用上面的方式

版权声明:本文为JHXL_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/JHXL_/article/details/103494831

智能推荐

Springboot整合rabbitMQ

依赖: 配置文件application.yml RabbitConfig 消息生产者RabbitProducer 消息消费者RabbitCustomer 通过Controller进行调用 启动项目后调用接口: 结果:...

Thread.join()方法的使用

如果一个线程A执行了thread.join()语句,代表当前线程A等待thread线程终止后才从thread.join()方法返回 并且这个方法具有超时特性,可以添加参数设置 输出结果: jdk中Thread.join()方法的源码(进行了部门调整)   每个线程终止的条件是前驱线程的终止,每个线程等待前驱线程终止后,才从join()方法返回,  当线程终止时,会调用自身的no...

linux服务器部署jenkins笔记

安装jenkins参考文档:https://blog.csdn.net/tomatocc/article/details/83930714 1. 打开jenkins官网:https://jenkins.io/download/ 将war包下载到本地 **ps:**这里要注意的是要下载左边下方的war包,不要下载右边下面的war包。左边是稳定版本,右边是最新版本,建议大家使用稳定版本(我刚开始下载的...

k8s部署elasticsearch集群

百度营销大学     环境准备 我们使用的k8s和ceph环境见: https://blog.51cto.com/leejia/2495558 https://blog.51cto.com/leejia/2499684 ECK简介 Elastic Cloud on Kubernetes,这是一款基于 Kubernetes Operator 模式的新型编排产品,用户可使用该产品在...

saas-export项目-AdminLTE介绍与入门

AdminLTE介绍 (1)AdminLTE是什么? AdminLTE是一款建立在bootstrap和jquery之上的开源的模板主题工具 (2)AdminLTE有什么特点? 提供一系列响应的、可重复使用的组件, 并内置了多个模板页面 自适应多种屏幕分辨率,兼容PC和移动端 快速的创建一个响应式的Html5网站 AdminLTE 不但美观, 而且可以免去写很大CSS与JS的工作量 AdminLTE...

猜你喜欢

MyBatis中ResultMap结果集映射

用于解决属性名和字段名不一致的情况: resultMap 元素是 MyBatis 中最重要最强大的元素。...

编写一个shell

编写shell的过程: 1.从标准输入中读入一个字符串。 2.解析字符串 3.创建一个子进程的执行程序。 4.子进程程序替换。 5.父进程等待子进程退出。...

WEB自动化测试中Xpath定位方法

前言: Xpath是在XML文档中查找信息的一种语言,使用路径表达式来选取XML文档中的节点或节点集,由于XML与HTML结构类似(前者用于传输数据,后者用于显示数据),所以Xpath也常用于查找HTML文档中的节点或节点集。 一  路径表达式: 路径以“/”开始     表示找到满足该绝对路径的元素; 路径以//”开始  ...

力扣困难难度 第4题 寻找两个正序数组的中位数

先看一眼题 我的思路: 设置下标i,j分别用于遍历两个数组,初始值均为0,直到找到两个数组中从小到大的第第length/2个数为止结束循环,length为两个数组长度之和。 ·每次比较nums[i]nums[j],如果前者小则i++,否则j++ ·循环结束时,如果count已经达到length/2,则说明已经找到了中位数,[注意:此时有可能正好其中一个数组遍历完了!所以...

[国家集训队]小Z的袜子(莫队)

[国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这NN只袜子从1到NN编号,然后从编号LL到RR(LL 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同...