laravel总结
1.1 启动服务
php artisan serve
1.2 数据库操作
ORM框架
1.2.1 配置文件
'default' => env(' DB_ CONNECTION', ' mysq1'),
使用env函数从.env文件中读取DB_ CONNECION,如果没有则将’mysql"赋值给变量default
所以数据库的配置信息实在.env中
将配置信息修改为自己的实际数据库配置
DB_ CONNECTION=mysq 1
DB_ HOST=127 .0.0.1
DB_ PORT=3306
DB_ DATABASE=db1
DB_ _USE RNAME=root
DB_ PASSWORD=root
1.2.2 数据库迁移
php artisan migrate: install
1.3 路由
1.3.1 闭包函数注册路由
get和post方法:
Route::get('浏览器访问地址','控制器所在目录地址@控制器方法名');
Route::post('浏览器访问地址','控制器所在目录地址@控制器方法名');
get 方法:说明注册的是一个 get 方式访问的路由,不能以 post 等其他方式访问
/:路由地址
function:回调函数,当访问 / 时,就会执行这个回调函数。在这个函数中,调用 view 方法渲染
了一个叫做 welcome 的模板视图
Route::get('/',function(){
return view('welcome');
})
在闭包函数中可以直接向用户返回简单数据
Route::get('/article',function(){
// return 'hello';
return json_encode([
"name"=>'yhb',
"age"=>20
]);
});
1.3.2 返回数据库中数据
- 创建数据库迁移文件
- 编写数据库迁移文件
- 运行数据库迁移文件
- 创建模型
- 使用模型
创建模型:通过模型操作数据库
php artisan make:model Post
模型会创建在 models 目录中
关于约定:
模型使用单数形式,数据表使用复数形式,这样会自动创建 Post 模型到 posts 数据表的对应,也
就是操作 Post 模型,就是在操作 posts 表
模型名称使用驼峰写法
通过模型查询数据
修改 web.php 路由文件
Route::get('/article',function(){
$posts=Post::orderBy('created_at','desc')->get();
return json_encode($posts);
});
1.3.3 使用模板
一般的页面都比较复杂,不可能向上面那样在页面中返回点数据
所以 Laravel 框架提供了模板,用于构建前端页面,并在其中显示分配的数据
- Laravel 使用 blade 模板
- 模板文件置于 resources/views 目录下
- 模板文件以 .blade.php 作后缀名
具体操作如下
在resources/views 目录下 创建 post 目录
在此目录下创建 index.blade.php 文件
修改路由文件中代码为
Route::get('/article',function(){
$posts=Post::orderBy('created_at','desc')->get();
return json_encode($posts);
});
修改模板文件
<ul>
@foreach($posts as $post)
<li>
{{$post->title}}
</li>
@endforeach
</ul>
1.4 控制器
Route::get('/article',function(){
// 利用模型查询数据
$posts=Post::orderBy('created_at','desc')->get();
// 指定模板展示数据,并传递参数
return view('post/index',['posts'=>$posts]);
});
这两行代码做的事情,都不是路由应该做的
路由应该是接受某个请求地址,然后中专一下即可,不应该处理业务逻辑等
所以在开发中,上面闭包函数的方式注册路由的方式并不是主流,而是将请求转到某个控制器中的某个
方法
修改路由中代码如下
- 创建控制器
- 编写方法
- 在路由中指定控制器和方法
创建控制器
php artisan make:controller PostController
编写代码
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index(){
$posts=Post::orderBy('created_at','desc')->get();
return view('post/index',['posts'=>$posts]);
}
}
修改路由代码
Route::get('/article','\App\Http\Controllers\PostController@index');
1.5 请求方式
- get:获取资源
- post:新增资源
- put:更新资源
- delete:删除资源
- path:增量
- option:查询都支持哪些方式
1.6 文章列表
1.6.1 编写路由
Route::get('/posts','\App\Http\Controllers\PostController@index');
1.6.2 编写控制器
class PostController extends Controller
{
public function index(){
$posts=Post::orderBy('created_at','desc')->get();
return view('post.index',['posts'=>$posts]);
}
}
1.6.3 编写模板
resources/views 目录下新建 post 目录
新建 index.blade.php(好像已经建好了)
将准备好的 html 代码拷贝到此文件
代码中引用了一些css和js资源,将这几个文件夹拷贝到 public 目录下,然后修改代码中资源路径为绝对路径即可(也就是在前面加上 /)
<link href="/css/blog.css" rel="stylesheet">
对一些暂时用不到的如 wangEditor 等资源可以先删除
然后修改文章列表部分代码如下
<!-- 文章列表和分页展示 -->
<div>
@foreach($posts as $post)
<div class="blog-post">
<h2 class="blog-post-title"><a href="/posts/{{$post->id}}">{{$post-
\>title}}</a></h2>
<p class="blog-post-meta">{{$post->created_at}} <a
href="/user/5">Kassandra Ankunding2</a></p>
<p>{{$post->content}}
<p class="blog-post-meta">赞 0 | 评论 0</p>
</div>
@endforeach
1.6.4 数据填充
项目需要大量的数据做功能测试,如分页
使用 Laravel 提供的数据填充功能,可以方便的获取大量数据
先按照如下步骤操作,然后再解释
创建工厂文件
database 目录下有一个 factories 目录
运行下面命令,会在此目录下创建文件 PostFactory
php artisan make:factory PostFactory
编写代码
在此文件中编写代码
public function definition()
{
return [
'title' => $this->faker->sentence(6),
'content' => $this->faker->paragraph(10),
];
}
faker 是一个php函数库,主要用于生成一下假数据,填充到数据库中
- sentence 用于生成6个单词,填充到 title 字段中
- paragraph 用于生成10个句子,填充到 content 字段中
注意:
- app.php 中已经有了默认设置,这里修改即可
- 虽然设置为中文,但是上面的sentence和paragraph方法只能生成英文
- 如果向测试中文,可以将 sentence 改成 name 试试
'title' => $this->faker->name,
运行文件
首先修改 database 目录下的 seenders 目录下的 DatabaseSeeder.php ,将 run 方法中代码的注释去
除,然后终端运行如下命令
php artisan db:seed
数据已经填充到数据库了
1.7 文章详情
1.7.1 编写路由
Route::get('/posts/{id}','\App\Http\Controllers\PostController@show');
1.7.2 编写控制器
public function show($id){
$post=Post::find($id);
return view('post.show',['post'=>$post]);
}
1.7.3 编写模板
resouces/views/post 目录下新建 show.blade.php
1.7.3 路由模型绑定
参考 “路由模型绑定”一节,可以将路由修改如下
Route::get('/posts/{post}','\App\Http\Controllers\PostController@show');
修改控制器方法如下
public function show(Post $post){
return view('post.show',['post'=>$post]);
}
1.8 添加文章
1.8.1 编写路由
// 显示添加博客页面
Route::get('/posts/create','\App\Http\Controllers\PostController@create');
// 实现添加博客
Route::post('/posts','\App\Http\Controllers\PostController@store');
1.8.2 编写控制器
public function create(){
return view('post.create');
}
// 添加博客
public function store(){
// 获取所有通过表单方式提交的数据
dd(request()->all());
}
1.8.3 编写模板
resources/views/post 目录下创建 create.blade.php
- 拷贝静态文件代码到文件内
- 修改表单内元素 name 属性的值与数据库保持一致,语义上清晰,而且后期验证和入库更简单
- 将表单中的 csrf 代码先删除
此时,访问 create 路由
http://127.0.0.1:8000/posts/create
在显示出来的页面上录入标题和内容,提交表单
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3497eMF2-1606720795519)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126081702109.png)]
这是由于 CSRF 保护引起的
1.8.4 CSRF保护
跨站请求伪造(CSRF)攻击
https://learnku.com/docs/laravel/8.x/csrf/9367
简单点说:
-
Laravel 会自动为每个活跃的用户的会话生成一个 CSRF「令牌」
-
这个令牌服务器保存一份,客户端也会带过去一份
-
当客户端通过表单或者ajax向服务器提交数据时,会将令牌一起带过去
-
Laravel 比较两个令牌,如果一致,则认为安全
-
从别的站点提交的数据(跨站攻击),虽然也可以提交一个令牌过去,但因为不是 Laravel 颁发
的,所以是无法通过验证的
如果是通过表单提交数据,只需要在 form 标记中加入如下代码
@csrf
可以查看生成的html代码,看看这个令牌是什么
现在再次提交表单,就没有问题了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l20Axs4d-1606720795522)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126081854044.png)]
1.8.5 保存博客
修改 store 方法
参考 Eloquent ORM 中的“插入及更新模型”一节,编写如下代码,新增数据
// 添加博客
public function store(){
// 获取所有通过表单方式提交的数据
$title=request('title');
$content=request('content');
$post=new Post();
$post->title=$title;
$post->content=$content;
$post->save();
}
1.8.6 批量赋值
上面代码是每个属性挨个赋值,也可以调用静态方法 create,其接受一个数组,可以批量为赋值
Post::create(request()->all());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P6wMEG4N-1606720795523)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126082043993.png)]
原因:在批量赋值的时候,create 数组的参数是个数组,这个数组直接使用了 request()->all() 方法获取
表单提交的数据,表单提交哪些数据,这里面就会有哪几个元素,如果恶意用户在其中伪造了恶意数
据,比如 isAmin=>1,在新增这个用户的时候,就可能将其设置为管理员
所以,这是存在风险的
为什么使用 save 方法,就没事呢?因为我们是单个属性挨个赋值,即使用户传递了恶意数据,我们页不
会为 isAdmin 字段赋值
这就是批量赋值漏洞
上面的 request()->>all() 方法获取的数组中,有一个 token,这个不是 Post 模型的标准属性,所以
laravel 认为你在钻漏洞,就不会直接新增数据,而是提示错误
解决方案
根本的解决方案,还是要规定哪些属性可以赋值,哪些不能赋值,在当前情况下,可以在模型中进行设
置
参考:https://learnku.com/docs/laravel/8.x/eloquent/9406#other-creation-methods 其中的“批量赋
值”部分
- $fillable :设置哪些属性能够被赋值
- $guarded:哪些属性不能被赋值
class Post extends Model
{
use HasFactory;
protected $fillable = ['title','content'];
}
明确告诉 token 不能被赋值,这样, laravel 就知道改怎们做了
此时就可以新增成功了
1.8.7 文件上传
文件上传方式
两种方式
- 传统表单方式:刷新页面
- ajax 方式:不刷新页面
实际开发中,使用第二种方式上传文件
wangEditor 内置了一个文件上传功能
配置wangEdtior
- 页面中引入 wanEditor.js (或者 wangEditor.min.js)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6wmxDukU-1606720795525)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126082358858.png)]
- 页面中合适的位置放一个 div 元素,并设置id,作为 wangEditor 的容器
- 编写 js 代码,初始化 wangEditor
var E = window.wangEditor
var editor = new E('#content')
editor.create()
- 配置上传文件请求的url和上传文件的名称
// 配置 server 接口地址
editor.config.uploadImgServer = '/posts/upload/image'
editor.config.uploadFileName = 'file'
- 配置csrf 选项,否则 laravel 框架验证不通过,会返回 419 错误
editor.config.uploadImgHeaders = {
Accept: 'text/x-json',
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
所以 完成代码如下
var E = window.wangEditor
var editor = new E('#content')
// 配置 server 接口地址
editor.config.uploadImgServer = '/posts/upload/image'
editor.config.uploadFileName = 'file'
editor.config.uploadImgHeaders = {
Accept: 'text/x-json',
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
editor.create()
//模板中加如下代码
<meta name="csrf-token" content="{{ csrf_token() }}">
表单的变化
因为内容的容器是一个 div,不是表单控件,添加提交按钮,无法将内容提交到 form 的 action 属性指
定的路由所以将提交按钮的 type 类型变成 button,这样点击按钮就不会提交表单
然后为这个按钮添加单击事件,在单击事件中 使用 js 代码提交表单
form.submit()
总结:无论是通过点击按钮还是通过js提交表单,提交的地址都是 form 的 action 属性指定的值
提交表单
在提交按钮的单击事件中,通过如下代码,向表单中添加内容,然后提交表单
document.querySelector('#btn_save').addEventListener('click',function(){
// 根据id获取表单
var form=document.querySelector('#form_post')
// 创建一个 input
var input=document.createElement('input')
input.type="text"
input.name='content'
// 获取的是 编辑器中用户输入的内容
input.value=editor.txt.html()
form.appendChild(input)
console.log(form);
// 调用表单的 submit 方法提交表单
form.submit()
})
laravel 处理上传文件
- 创建盘符链接
在 laravel 框架中,public 目录是公共目录,也就是说此目录是可以通过 url 访问其中的文件的,如
果访问其他目录,都会提示没有权限
但是处于某种考虑,laravel 建议将上传的文件保存到 storage/app 目录下的 public 目录下,但如
果文件放到此目录下,会导致文件无法通过 url 访问
解决方案就是,创建这两个目录之间的连接
php artisan storage:link
此命令会在 public 目录下创建名为 storage 的目录,并创建 public/storage 目录到
storage/app/public 目录的符号链接,然后通过 storage/文件名称实际访问的就是
storage/app/public 下的同名文件
- 创建用于上传图片 的路由
// 用于上传图片
Route::post('/posts/upload/image','\App\Http\Controllers\PostController@upload')
;
- 创建uoload 方法,用于处理上传的文件
// 上传图片
public function upload(){
// 获取上传的图片,并将其保存到一个叫做 upload 的文件夹下
// 如果没有这个文件夹,会自动创建
// laravel 会为这个图片生成一个随机的名称
request()->file('file')->store('upload');
}
- 修改upload文件夹创建的位置
默认情况下,upload 文件夹会创建在 storage/app 目录下
修改 config/filestystems.php 的文件
'local' => [
'driver' => 'local',
'root' => storage_path('app/public'),
],
- 编写 upload 方法
uplpoad 方法
// 上传图片
public function upload() {
$file = request()->file( 'file' )->store( 'upload' );
// 必须姚返回 wangEditor 要求的格式
return [
'errno'=>0,
'data'=>[
asset( 'storage/'.$file )
]
];
}
filesystem.php 修改配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BPZ0E9g8-1606720795527)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126084302459.png)]
- 修改返回值
此时,图片可以正常的存储到了 storage/app/public/upload 目录下
但是仍然提示上传错误,原因在于服务器端返回的数据不符合 wangEditor 要求的格式
1.8.8 wangEditor提交表单
因为使用 div 作为富文本编辑器控件,其不是表单控件,所以无法通过表单提交
建议通过JS提交表单
首先将表单中的提交按钮的 type 改成 button
然后为此按钮添加单击事件
document.querySelector('#btn_save').addEventListener('click',function(){
// 将编辑器中的数据取出来
var content=editor.txt.html()
var form=document.querySelector('#form_posts')
// 创建一个一个 input 元素
var input=document.createElement('input')
input.name='content'
input.type='text'
input.value=content
form.appendChild(input)
// 提交表单
form.submit()
})
1.8.9 关于简介问题
关于文章简介的生成,有如下两种方式
- 为用户提供简介的输入区域,让用户自己填写文章简介
- 自动从内容中提取部分内容作为简介
首先数据库中添加简介字段(des)
修改 提交按钮的单击事件,在此事件中,动态向表单中添加 简介内容
document.querySelector('#btn_save').addEventListener('click',function(){
// 将编辑器中的数据取出来
var content=editor.txt.html()
// 获取村文本
var txt=editor.txt.text()
// 提取出文本的前200个字符作为简介
var des=txt.substr(0,200)
var form=document.querySelector('#form_posts')
// 创建一个一个 input 元素,用于存储内容
var input=document.createElement('input')
input.name='content'
input.type='text'
input.value=content
form.appendChild(input)
// 创建一个一个 input 元素,用于存储简介
var input=document.createElement('input')
input.name='des'
input.type='text'
input.value=des
form.appendChild(input)
form.submit()
})
1.8.10 关于资源
html 页面中引用的 css 文件、js 文件、图片、视频、音频等文件都叫做资源,当浏览器看到这些资源
后,会从指定的地址下载,每一个资源的下载都会单独发送一个网络请求
1.8.11 laravel验证
程序一定要验证
验证分成两种形式
使用js在前端验证
后台验证
两种验证方式应该并存
前端验证
验证速度块,用户体验好
在 ylaravel.js 中创建验证函数
function validate() {
// 验证用户的输入
var content = editor.txt.html()
var title = document.querySelector('#title').value
if (title == '') {
alert('标题不能为空')
return false
}
if (content == '') {
alert('内容不能为空')
return false
}
return true
}
然后在 按钮的单击事件中调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XhlVu4OY-1606720795530)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126085817833.png)]
服务器验证
永远不要相信前端验证,服务端验证是安全的最后一道门了
在 PostController.php 中的 store 方法中加入如下代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YqGjMrV-1606720795531)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126085836541.png)]
如果服务器端验证没有通过,则会重定向到原来页面,并且将验证的错误信息绑定到视图中,
所以可以在视图中直接输出错误信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-257z4sll-1606720795533)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126085851636.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RppD9erq-1606720795534)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126085858049.png)]
默认的错误信息是英文,可以进行本地化
- 在 resources/lang 目录下新建 zh 文件夹
- 在 zh 文件夹中新建 validation.php
- 将 en目录下的 validation.php 代码拷贝到当前文件中
- 修改错误信息为中文
- 修改 config 目录下的 app.php 中的 local 键的值为 zh
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hFHo8qCb-1606720795535)(C:\Users\李嘉慧\AppData\Roaming\Typora\typora-user-images\image-20201126085922131.png)]
1.9 MVC
1.9.1 概念
M: model 模型
V:view 视图
C:controller 控制器
MVC 是一种编程思想
核心:将程序当中的跟页面展现相关的代码放到一个文件中,将业务逻辑处理相关的代码放到一个文件
中,将数据库交互的代码放到一个文件中
这三个文件就分别负责页面呈现(view)、业务逻辑(controller)和数据交互(模型)
1.9.2 新闻列表展示
创建表并插入数据
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`content` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of news
-- ----------------------------
INSERT INTO `news` VALUES ('1', '李白', '朝辞白帝彩云间\r\n千里江陵一日还\r\n两岸猿声啼
不住');
INSERT INTO `news` VALUES ('2', 'bbbb', 'bbbbbb');
INSERT INTO `news` VALUES ('3', 'ccccc', 'ccccccc');
INSERT INTO `news` VALUES ('4', 'aaa', 'aaaa');
创建 NewsController.php
<?php
class NewsController {
public function index() {
include './NewsModel.php';
$model = new NewsModel();
$news = $model->getNewsList();
// 读取 index.html 文件的内容
$content = file_get_contents( 'index.html' );
// 遍历数组,生成 tr
$str = '';foreach ( $news as $v ) {
$str .= "<tr>
<td>{$v['id']}</td>
<td>{$v['title']}</td>
<td>{$v['content']}</td>
</tr>";
}
$txt = str_replace( '{{tr}}', $str, $content );
// file_put_contents( '1.txt', $txt );
echo $txt;
// echo '<pre>';
// print_r( $news );
// echo '</pre>';
}
}
创建 NewsModel.php
<?php
class NewsModel{
public function getNewsList(){
$link = mysqli_connect( 'localhost', 'root', 'root', 'db1118' ) or die(
'连接失败' );
// 设置编码
mysqli_set_charset( $link, 'utf8' );
$sql = 'select * from news';
$res = mysqli_query( $link, $sql );
$news = mysqli_fetch_all( $res, MYSQLI_ASSOC );
return $news;
}
}
创建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./bootstrap/css/bootstrap.css">
</head>
<body>
<table class="table">
<thead>
<tr>
<th>编号</th>
<th>标题</th>
<th>内容</th>
</tr>
</thead>
<tbody>
{{tr}}
</tbody>
</table>
</body>
</html>
创建 index.php
<?php
include './NewsController.php';
$crl = new NewsController();
$crl->index();
浏览器中访问 index.php ,而不是访问其他php文件或者html文件
总结:
- 不再直接访问 html 页面了,也不直接其他的php页面,而是访问 index.php
- php 页面实例化控制器类,然后调用其中的方法
1.9.3 添加新闻
修改 index.html 中的 添加新闻 超链接
<a href="index.php?action=show">添加新闻</a>
点击 添加新闻 时,也是请求 index.php 这个文件
此时,无论时访问新闻列表还是访问添加新闻,都是请求 Index.php
为了能够区分用户当前到底请求哪个页面,可以在请求的时候,使用问号传值的方式传递要请求的方法
名称
修改 index.php 页面代码
<?php
include './NewsController.php';
// 获取请求的方法名称
$action=$_GET['action'];
echo $action;
$crl = new NewsController();
// 如果请求的是首页(新闻列表页面),则不传递任何数据
if($action==''){
$crl->index();
}else if($action=='show'){
$crl->show();
}
show 方法代码
// 展示一个用于添加新闻的页面
public function show(){
// 读取 add.html
$content=file_get_contents('./add.html');
echo $content;
}
add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./bootstrap/css/bootstrap.css">
</head>
<body>
<div class="container">
<form class="form-horizontal" method="post" action="index.php?
action=store">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">新闻标题</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="title"
placeholder="输入新闻标题">
</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" rows="20">
</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(){
// echo '<pre>';
// print_r($_POST);
// echo "</pre>";
$title=$_POST['title'];
$content=$_POST['content'];
/**
\* 使用 new 关键字创建一个 NewsModel 类的实例,默认会从当前文件中寻找这个
\* 叫做 NewsModel 的类,而当前文件中没有这个类,所以要告诉代码,应该从哪个
\* php文件中,找这个类
\* 如何告诉呢?使用 include 引入对应的文件即可
*/
include './NewsModel.php';
$model=new NewsModel();
$res=$model->addNews($title,$content);
if($res){
header('location:index.php');
}else{
}
}
在 NewsModel.php 中新增一个方法
// 新增一条新闻
public function addNews($title,$content){
$link = mysqli_connect( 'localhost', 'root', 'root', 'db1118' ) or die(
'连接失败' );
// 设置编码
mysqli_set_charset( $link, 'utf8' );
$sql = "insert into news values(null,'$title','$content')";
$res=mysqli_query($link,$sql);
return $res;
}
总结:
无论超链接的地址还是表单提交,还是 php 中的header 方法跳转,都是直接请求 index.php
我们将 index.php 叫做 入口文件