laravel框架使用生涯
手工安装laravel
http://laravelacademy.org/resources-download
1、将下载的文件复制到虚拟主机目录
2、在Apache的配置文件配置一个虚拟主机【注意,需要指向 public目录下】
<VirtualHost *:80> DocumentRoot "C:\phpStudy\WWW\laravel.dev\public" ServerName laravel51.dev ServerAlias phpStudy.net <Directory "C:\phpStudy\WWW\laravel.dev\public"> 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错误
如果没有在路由文件里面定义路由规则,直接请求,会提示如下的信息:
- 文章CRUD
创建名为 news 的数据库
创建名为 news 的项目
D:\developer\laravel> composer create-project --prefer-dist laravel/larave/ news
数据库迁移
配置数据库连接
首先在 .env 中配置数据库连接信息
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=newsDB_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
可能会出现如下的错误提示
错误原因在于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
原因在于数据库中已经存在响应的表了,删除这些表,然后重新执行数据库迁移文件
如何添加新的字段
现在想为 Post 表添加一个字段
代码修改好后,重新运行数据库迁移
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=newsDB_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\PostController@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','\App\HttP\Controllers\PostController@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','\App\HttP\Controllers\PostController@stroe'); CSRF
表单中数据如数据,点击保存后,会出现如下错误
解决方案,在新增文章的表单中,加入如下代码
解释:
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\PostController@edite');
更新 index 视图
创建 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\PostController@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','\App\HttP\Controllers\PostController@delete');
修改 index.blade.php 中的 删除 按钮
- 文章类型CRUD
8.1 生成数据库
创建数据库迁移文件
运行数据库迁移
8.2 创建模型
创建模型注意事项
表名为复数形式,模型名称为单数形式
表名如果是多个单词组成,且中间有下划线,如 post_types,则模型名称使用单数形式,且每个单词首字母大写,并去除下划线,如 PostType
8.3 创建控制器
一般一个功能模块对应一个控制器
8.4 配置路由
打开项目根目录下的 routes 目录下的 web.php 文件,配置路由
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'); } }
- 前后端分离开发中的laravel
在实际的开发当中,前端和后端的开发会同步进行
后台人员新建laravel项目,编写控制器和模型(视图),用于向前端同学提供数据,或者收集前端同学提供的数据
前端人员新建web或者android或者ios 等项目,用于获取后台人员提供的数据,渲染界面
前端和后端程序之间使用 ajax 的方式交互数据
9.1 新建项目
新建前端项目 news_client 和 后端laravel项目 news_server
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">×</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','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
上面命令会在 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 属性中,加入如下代码
重新请求即可实现跨域访问
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');
添加例外
运行添加文章后,浏览器控制台中出现如下错误
错误原因是:laravel 开启了 CSRF 防护,也就是说当其前端以 post、delte 或者 Put 方式访问路由的时候,就会收到 CSRF 保护,就是要求提供一个令牌,如果没有令牌,则就会报 419
解决方法:指定某些路由不需要CSRF防护
在 Http\Middleware 目录下的 verifycsrgtoken.php 中的 except 属性中加入想要不受保护的路由
此时重新添加文章即可
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框架数据库CURD操作、连贯操作使用方法
- laravel框架session使用教程
- 总结:关于留学网站使用laravel框架的总结
- laravel框架的使用
- Linux下 php环境安装、配置composer,使用composer安装laravel、zan等框架
- Laravel框架执行原生SQL语句及使用paginate分页的方法
- 使用 Laravel 框架:成为微信公众平台开发者
- 用composer方式安装Laravel框架(使用镜像安装)
- PHP的Laravel框架结合MySQL与Redis数据库的使用部署
- laravel apiato框架使用
- Laravel框架数据库CURD操作、连贯操作使用方法
- PHP最优雅的框架——laravel学习使用入门
- laravel框架的使用
- laravel框架自带验证码使用
- laravel框架使用富文本
- Laravel框架 mysql 数据库 —— 基本使用
- laravel框架session使用教程
- 使用composer 安装 laravel框架的方法图文详解
- composer安装及使用composer安装laravel框架
- laravel框架中使用QueryList插件采集数据