laravel框架使用生涯

摘要:
开始使用larravel 1.路由介绍,因为larravel是一个重新路由框架。

手工安装laravel

http://laravelacademy.org/resources-download

1、将下载的文件复制到虚拟主机目录
在这里插入图片描述
2、在Apache的配置文件配置一个虚拟主机【注意,需要指向 public目录下】

<VirtualHost *:80>
    DocumentRoot "C:phpStudyWWWlaravel.devpublic"
    ServerName laravel51.dev
    ServerAlias phpStudy.net
  <Directory "C:phpStudyWWWlaravel.devpublic">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
      Require all granted
  </Directory>
</VirtualHost>

3、配置hosts文件

127.0.0.1 laravel51.dev

4、浏览器访问效果
在这里插入图片描述

laravel目录结构分析

整体目录

在这里插入图片描述

app目录

在这里插入图片描述

http目录

在这里插入图片描述

config目录

config目录:主要是存放配置文件信息,laravel的配置信息是分文件保存的。
在这里插入图片描述

database目录

database目录:数据迁移和种子文件。
在这里插入图片描述
例如某个数据迁移文件:在项目开发和测试阶段使用的较多,上线之后基本不用。
在这里插入图片描述

public目录

public目录:单入口和系统的静态资源(css、img、js、uploads)
在这里插入图片描述

resource目录

resources目录:存放视图文件。
在这里插入图片描述

storage目录

storage目录:主要是存放缓存文件和日志文件,需要注意:如果是在Linux环境下,该目录需要有可写的权限
在这里插入图片描述

vendor目录

vendor目录:主要是存放第三方的类库文件,laravel思想主要是共同的开发,不要重复的造轮子(例如:里面可能存在验证码类、上传类、邮件类),还需要注意该目录还存放laravel框架的源码。注意:如果使用的composer软件管理的,composer下载的类库都是存放在该目录下的。

在这里插入图片描述

.env文件

.env文件:主要是设置一些系统相关的环境配置文件信息。config目录里面的文件配置内容一般都是读取该文件里面的配置信息(config里面的配置项的值基本都是来自.env文件)。
在这里插入图片描述

laravel入门使用

1、路由简介

因为laravel是一个重路由的框架。

什么是路由?
答:路由就是用户在地址栏里面输入一个url地址后,交给后端的那个控制器下的那个方法进行处理的规则。一般我们需要在专门的路由文件里面,进行定义好。

为什么要使用路由?
答:laravel里面路由。最新的 TP5里面也是存在路由。
好处:

1、url地址变得非常的美观。(以前没有路由都是通过伪静态处理)
2、隐藏网站的目录结构(t.cn/goods/index.php ?)(index.php?m=Home&c=User&a=lst)
3、防范网络攻击…

路由文件在哪里,以及规则如何编写?

在这里插入图片描述

2、路由入门使用

// laravel内置了一个Route类,提供了很多方法 一般是根据http的请求来命名 
// 例如: 1. get 2. post 3. any 4. match .....
// get方法是处理 get请求 第一个参数:代表是请求的url地址的uri部分 
// 第二个参数:1. 匿名函数 2. 字符串(控制器下的某个方法)

// 1. 匿名函数 返回值作为http的响应返回给浏览器
// 2. 控制器里面的方法执行作为响应

// url:http://local.laravel51.com/
Route::get('/', function () {
  return 'hello';
    // return view('welcome');
});

// url:http://local.laravel51.com/about
Route::get('/about', function () {
  return 'about';
    // return view('welcome');
});

3、视图使用

视图载入
学习:

1、视图写在哪里?
2、视图文件如何命名?
3、视图里面的内容和编写?
4、视图是否可以分目录管理?
5、视图如何被载入?
6、如何视图赋值?
在这里插入图片描述

效果:

在这里插入图片描述

4、blade模板引擎

1、在routes.php里面定义一个/user/login路由
在这里插入图片描述
2、建立 login.blade.php视图文件
在这里插入图片描述
3、在routes.php里面定义一个/blade路由
在这里插入图片描述
4、建立 show.blade.php视图文件
在这里插入图片描述
5、注意:laravel模板引擎和 vuejs的冲突解决

代码
routes.php路由文件

<?php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
// laravel内置了一个Route类,提供了很多方法 一般是根据http的请求来命名 例如: 1. get 2. post 3. any 4. match .....
// get方法是处理 get请求 第一个参数:代表是请求的url地址的uri部分 第二个参数: 1. 匿名函数 2. 字符串(控制器下的某个方法)
// url:http://local.laravel51.com/
// 1. 匿名函数 返回值作为http的响应返回给浏览器
// 2. 控制器里面的方法执行
Route::get('/', function () {
  return 'hello';
    // return view('welcome');
});

// url:http://local.laravel51.com/about
Route::get('/about', function () {
  return 'about';
    // return view('welcome');
});

// 1. 视图写哪里? 2. 视图文件名如何命名  3. 视图里面内容 4. 视图是否可以分目录管理 5. 视图如何被载入 6. 如何视图赋值
// url:http://local.laravel51.com/user/login
Route::get('/user/login', function () {
  // view() 函数是用于载入视图的 视图写在哪里? 如何命名?
  // /resources/views/视图文件名称.blade.php  文件的后缀 .blade.php必须这样,因为laravel内部使用的一个模板:blade
  $info = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod consequatur nisi excepturi debitis mollitia autem quis dolores error nulla, ea cumque vero quas beatae eveniet molestias expedita cupiditate. Itaque, culpa!'; // 赋值
  $title = 'Lorem ipsum dolor sit amet, consectetur.';
  // 两种方式:
  // with 第一个参数是视图调用名称 第二个参数变量信息
  // 第二种: 直接给view函数传递第二个参数,关联数组,key视图调用名称 value变量信息
  $key = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis alias assumenda dolorum vel animi quo mollitia possimus neque quod illum!';
  $age = 12;
  // 复合数据类型 [] 数组 php5.4语法
  $userData = [
    ['id' => 1, 'username' => 'Lorem ipsum dolor sit amet, consectetur adipisicing.'],
    ['id' => 2, 'username' => 'Lorem ipsum dolor sit.'],
    ['id' => 3, 'username' => 'ruby'],
  ];

  // 通过赋值操作可以在视图里面显示数据信息,但是通过第二种方式写起来还是很麻烦。 key value key value
/*    return view('home.user.login', ['key' => $key, 'age' => $age, 'userData' => $userData])
      ->with('info', $info)
      ->with('title', $title); 
*/    // 文件夹的分隔符使用的 /  laravel建议使用 .

    // 赋值简化操作
    // compact('info', 'title', 'key', 'age', 'userData') 可以将数据转换为 关键数组 参数:是变量名
    return view('home.user.login', compact('info', 'title', 'key', 'age', 'userData'));

});


// 视图里面的模板引擎 blade 1. 基本数据输出 2. 复合数据类型输出 3. 逻辑判断

Route::get('/blade', function ()
{
  $title = '模板引擎';

  $userData = [
    ['id' => 1, 'username' => 'Lorem ipsum dolor sit amet, consectetur adipisicing.'],
    ['id' => 2, 'username' => 'Lorem ipsum dolor sit.'],
    ['id' => 3, 'username' => 'ruby'],
  ];
  $isBoolean = false;
  $info = '这个是真的!';


  return view('show', compact('title', 'userData', 'info', 'isBoolean'));

});

show.blade.php视图文件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
  <script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>  
  <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  
  <title>blade模板引擎</title>
</head>
<body>
  <div class="container">
    <h2>原生PHP</h2>
    <hr>
    <p><?php echo $title;?></p>
    <hr>
    {{-- 短标记语法PHP --}}
    <p><?= $title;?></p>
    <hr>
    <h2>blade模板引擎</h2>
    {{-- 这两个大括号被叫做 插值表达式,计算内部的表达式,最终的结果放置在这里 --}}
    {{-- vuejs 也是使用的插值表达式 --}}
    <p>{{ $title }}</p>
    <p>{{  1 + 1 }}</p>
    <p>{{  3 * 8 }}</p>
    <h2>逻辑运算</h2>
    <p>{{ !false }}</p>
    {{-- 三目运算 --}}
    <p>{{ 1 > 2 ? '假的' : '真的' }}</p>
    <hr>
    <h1>复合数据类型输出</h1>
    @foreach ($userData as $v)
      <li>序号: {{  $v['id'] }} 姓名: {{ $v['username'] }}</li>
      <hr>
    @endforeach
    <hr>
    @if ( $isBoolean )
      {{  $info }}
    @endif
    <hr>
    @if ( $isBoolean )
      这个是真的...........
    @else
      假的的...........
    @endif
  </div>
  {{-- 问题: laravel和 vue 相遇了  --}}
  <div class="container">
    <div id="box">
      {{-- 不想让 laravel进行解析,前端vuejs 在浏览器里面解析 --}}
      {{-- vuejs 前端MVVM框架 --}}
      <p>@{{  msg }}</p>
    </div>
  </div>
</body>
<script src="https://cdn.bootcss.com/vue/1.0.23/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#box',
    data: {
      'msg' : 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint, distinctio doloremque assumenda dicta veritatis repellendus maxime ut commodi ipsum necessitatibus ullam nihil! Saepe ab labore aliquam facilis placeat id incidunt.'
    }

  });
</script>
</html>

login.blade.php视图文件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
  <script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>  
  <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  <title>user-login页面</title>
</head>
<body>
  <div class="container">
    <h1 class="page-header">user-login页面</h1>
    <hr>
    <h2>原生PHP</h2>
    <?php echo date('Y-m-d H:i:s');?>
    <hr>
    <h2>blade模板引擎</h2>
    <p>{{ time() }}</p>
    <hr>
    <p><?php echo $info;?></p>
    <hr>
    <p class="well"><?php echo $title;?></p>
    <hr>
    <p class="well"><?php echo $key;?></p>
    <hr>
    <p><?php echo $age;?></p>
    <hr>
    <h2>复合数据类型: 数据遍历操作</h2>
    <ul>
      <?php foreach ($userData as $v): ?>
        <li>序号: <?php echo $v['id'];?> 姓名: <?php echo $v['username'];?></li>
        <hr>
      <?php endforeach ?>
    </ul>
  </div>
  
  
  <div class="container">
    <form action="" method="POST">
      <div class="form-group">
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" class="form-control" value="">
      </div>
      <div class="form-group">
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" class="form-control" value="">
      </div>
      <div class="form-group">
        <input type="submit" value="提交" class="btn btn-success">
        <input type="reset" value="清空" class="btn btn-danger">
      </div>
    </form>
  </div>
</body>
</html>

4、控制器使用

通过上面的操作,我们发现基本将代码都写在routes.php路由文件,这样不利于后期的开发和维护。一般会将用户的请求交给控制器下的某个方法来处理。在方法里面完成业务逻辑。

思考:
1、控制器写在哪里?
2、控制器文件名如何命名?
3、控制器里面的内容如何编写?
4、控制器里面如何载入视图?
5、控制器里面如何赋值?
6、控制器里面的方法如何被调用?
7、如何在控制器里面实例化模型?
8、如何通过模型获取数据?

5、artisan命令-控制器

使用 artisan 命令生成控制器的默认行为

在这里插入图片描述

效果:

在这里插入图片描述

代码内容:

在这里插入图片描述

使用 artisan 命令生成控制器的不要带方法

在这里插入图片描述

代码内容:

在这里插入图片描述

使用 artisan 命令生成控制器的分目录管理

在这里插入图片描述

代码内容:

在这里插入图片描述

常见错误

加密密钥生成

在这里插入图片描述

解决:

在这里插入图片描述

404错误

如果没有在路由文件里面定义路由规则,直接请求,会提示如下的信息:
在这里插入图片描述

  1. 文章CRUD
    创建名为 news 的数据库

创建名为 news 的项目

 D:developerlaravel> composer create-project --prefer-dist laravel/larave/ news

数据库迁移

配置数据库连接

首先在 .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 的长度

在 appproviders 目录下的 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();
        });
    }

设置默认长度

AppProvidersAppServiceProvder.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 IlluminateSupportFacadesRoute;

Route::get('/posts','AppHttPControllersPostController@index');

创建视图

在 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','AppHttPControllersPostController@add');

创建视图 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','AppHttPControllersPostController@stroe');
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','AppHttPControllersPostController@edite');

更新 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','AppHttPControllersPostController@update');

7.6 删除文章信息
创建方法

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

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

配置路由

// 删除数据

Route::get('/posts/{post}/delete','AppHttPControllersPostController@delete');

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

mark

  1. 文章类型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');
    }
}
  1. 前后端分离开发中的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 IlluminateSupportFacadesRoute;

// 获取所有的文章信息

Route::get('/posts','PostController@index');

创建模型

 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

上面命令会在 AppHttpMiddleware 目录下创建 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;
    }

注册中间件

在 apphttp 的 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','PostController@store');

添加例外

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

mark

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

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

在 HttpMiddleware 目录下的 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}','PostController@delete');

CSRF忽略

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

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

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

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

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

Route::delete('/posts/{post}','PostController@delete');

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

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

待更新。。。。。。

免责声明:文章转载自《laravel框架使用生涯》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇博科 SAN交换机配置文件备份和恢复(华为SNS系列交换机为例OEM博科)双网卡双ip设置(转载)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#: 通过html调用WinForm 。。。。。

完整测试代码:Form1.cs 代码 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;n...

Python的Django框架

一、Django简介 Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。 Django 是一个开放源代码的 Web 应用框架,由 Python 写成。 Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0...

oracle数据库常见案例_oracle

oracle体系结构:      一、数据库系统性能相关 案例一: 由于业务停机维修,需提前关闭数据库,待维修完成之后再次把数据库启动,关注日志宝成,保证成功启动   步骤:     1、停止监听:lsnrctl stop     2、数据库关闭:>shutdown immediate;     3、业务维修完成之后重启打开监听:lsnrctl st...

Django-rest-framework --- 总结

目录 drf回顾总结 drf基础知识点 1.drf框架安装 安装 drf框架规矩的封装风格 drf请求生命周期 2.接口 3.restful接口规范 4.基于restful规范的原生Django接口 主路由:url.py api组件的子路由:api/url.py 模型层:model.py 后台层:admin.py 数据库迁移 视图层:vi...

Linux 和Windows之间命令行实现目录或文件互传

Linux 和Windows之间命令行实现目录或文件互传 在linux中,我们常用scp命令传输文件: 如以下实例,我们想把当前服务器文件abc.sql传输到192.168.1.1服务器上 我们可以执行以下命令: scp /home/person/hww/abc.sql root@192.168.1.1:/home/person/hww  回车后输入...

[C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释

新版本—— http://www.cnblogs.com/zyl910/p/zlstdint_v100.html[C] zlstdint(让VC、TC等编译器自动兼容C99的整数类型)V1.0。支持Turbo C++ 3等DOS下的编译器 作者:zyl910 一、改动简介   V1.02版的改动如下—— 将源码上传到github. 调整目录结构. 添加C...