技术标签: lumen教程
网站配置,就是网站的一些基本信息,话不多说,上图
为了演示,我写了这些信息,其实应该还有其他配置的。
这些信息是要保存的,但是数据库中缺少表,我们需要建立一张数据表,表名叫settings,我准备使用数据库迁移方式建表,这个很方便,很好用!
之前我们建立了一个数据库,叫cms-test,并且在.env中配置好了。
现在打开你的命令行工具,切换到项目目录下,执行命令
php artisan make:migration create_settings_table
如果不报错,说明执行命令成功。然后在/database/migrations/目录下,你会看到一个新的文件,这就是命令行生成的,我们打开该文件,你会看到有两个方法,up和down,up方法是新增数据表、字段、索引用的,down方法做的是up的反向操作,或者撤销操作,比如up方法里边是新增表,那么down就是删除表。
我们在up方法里添加如下内容
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name',20)->default('')->comment('网站名称');
$table->string('logo',20)->default('')->comment('LOGO');
$table->string('url',20)->default('')->comment('网址');
$table->string('copyright',20)->default('')->comment('版权信息');
$table->string('hotline',15)->default('')->comment('客服热线');
$table->string('contact',10)->default('')->comment('联系人');
$table->string('mobile',11)->default('')->comment('手机号');
$table->string('email',20)->default('')->comment('邮箱');
$table->string('record_sn',20)->default('')->comment('备案号');
$table->string('address',30)->default('')->comment('公司地址');
$table->string('statistics',300)->default('')->comment('流量统计');
$table->timestamps();
});
}
// 新增id字段,数据类型是bigint,值自增
$table->bigIncrements('id');
// 新增字段name,数据类型是varchar,长度20,默认空字符,注释是网站名称
$table->string('name',20)->default('')->comment('网站名称');
很好阅读,很清晰。
迁移结构我们写好了,那我们运行迁移,让程序给我们在数据库中生成一张表,在命令行工具上执行
php artisan migrate
结果输出
这样就成功了,我去数据库中看看
数据库中生成了两张表,一个是migrations,一个是settings,哦,对了,这个框架要求数据库表名是复数的。migrations表我们不用管它。
然后我们看看生成的数据结构
CREATE TABLE `settings` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '网站名称',
`logo` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'LOGO',
`url` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '网址',
`copyright` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '版权信息',
`hotline` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '客服热线',
`contact` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '联系人',
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '手机号',
`email` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '邮箱',
`record_sn` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备案号',
`address` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备案号',
`statistics` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备案号',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
真是太好用了!!当你拿到我的代码的时候,你也可以直接做迁移,让我们的数据库表都是一样的,在多人开发的时候,就不会出现数据库不一直的情况了,强烈建议你也用迁移。
数据表有了,我们该保存数据了。
我们使用MVC的方式开发,V和C都有了,M还没有。在/app/目录下建立一个Models文件夹,然后我们在这个文件夹下新建一个
Setting模型,和settings表对应。
我们添加一个add()方法,用于保存数据。 代码如下
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
public static function add(array $data)
{
$setting = new Setting();
$setting->name = $data['name'] ?? '';
$setting->logo = $data['logo'] ?? '';
$setting->url = $data['url'] ?? '';
$setting->copyright = $data['copyright'] ?? '';
$setting->hotline = $data['hotline'] ?? '';
$setting->contact = $data['contact'] ?? '';
$setting->mobile = $data['mobile'] ?? '';
$setting->email = $data['email'] ?? '';
$setting->record_sn = $data['record_sn'] ?? '';
$setting->address = $data['address'] ?? '';
$setting->statistics = $data['statistics'] ?? '';
return $setting->save();
}
}
在这里,add()方法使用的是静态方法,调用的时候可以直接使用Settings::edit([]),为什么不使用对象的方式而使用静态方式?他们的区别,你可以百度搜索,去了解下,这里我不多说了。
然后再写个edit()方法,用户编辑数据
public static function edit(Setting $setting, array $data)
{
$setting->name = $data['name'] ?? '';
$setting->logo = $data['logo'] ?? '';
$setting->url = $data['url'] ?? '';
$setting->copyright = $data['copyright'] ?? '';
$setting->hotline = $data['hotline'] ?? '';
$setting->contact = $data['contact'] ?? '';
$setting->mobile = $data['mobile'] ?? '';
$setting->email = $data['email'] ?? '';
$setting->record_sn = $data['record_sn'] ?? '';
$setting->address = $data['address'] ?? '';
$setting->statistics = $data['statistics'] ?? '';
return $setting->update();
}
就像这样
这里我使用了两个问号
$data['name'] ?? ''
是PHP7的新特性,是个语法糖,意思是如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
$username = $_GET['user'] ?? 'nobody';
他们是等价的。
模型完成了,我们回到控制器,在控制器接收、处理数据,然后通过模型保存到数据库。
打开SiteSettingController.php文件,
找到set()方法,我们要通过表单提交数据,POST方式提交,lumen框架怎么接收前端上传的数据呢?我需要在控制上引入Illuminate\Http\Request类,传入的请求实例将会由 服务容器 自动注入。
获取所有输入数据:
$input = $request->all();
获取一个值:
$name = $request->input('name');
详细用法,你还得看官方文档。接下来我就直接干了。
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Setting;
use Illuminate\Http\Request;
class SiteSettingController extends Controller
{
public function set(Request $request)
{
$setting = Setting::fist(); // 获取setting数据表中一条数据
if ($request->isXmlHttpRequest()) { // 只处理ajax提交的,其他不处理
if (!empty($setting->id)) { // 如果数据存在,更新数据
Setting::edit($setting, $request->all());
} else { // 如果数据表中没有任何数据,则添加一条数据
Setting::add($request->all());
}
}
return view('admin.siteSetting');
}
}
没啥可说的,因为要在网站设置页面通过ajax提交表单数据,所以,当是ajax提交的时候,要做个判断,然后就是数据表存在一条数据的话,就更新,没有任何数据的话就新增,控制器先到这里,后边我们还会在回到这里。
我们来到网站设置的视图文件那边
我们找到文件下边的js部分,看到“//发异步,把数据提交给php”那个位置,增加一个ajax,提交表单数据。
为了使用Eloquent,我们需要打开这个两个注释
我们打开siteSetting.blade.php文件,在文件底部的js部分,我们加入以下代码
//监听提交
form.on('submit(add)',
function (data) {
console.log(data.field);
//发异步,把数据提交给php
$.post('/admin/siteSetting/',data.field,function (data) {
console.log(data);
layer.alert(data.msg, {
icon: 6
},
function () {
//关闭当前frame
xadmin.close();
// 可以对父窗口进行刷新
xadmin.father_reload();
);
return false;
});
});
当点击“增加”按钮的时候,通过ajax提交数据,要求服务器返回json格式的数据,我们定义服务器返回这样的格式:
{
"code": 200,
"message": "操作成功",
"data": []
}
code是200代表成功,code是400代表客户端请求有误,code是500代码服务器端出错。你可以定义的更详细,我这里为了方便暂时定义这个三个。
这样的json格式数据,每个接口都要用,我们写一个类来实现它,专门用于处理返回接口数据。
在app目录下,新建一个Services文件夹,在这个文件夹下再新建一个Response类,用户处理我们返回的结果。如下
<?php
namespace App\Services;
class Response
{
private $code = 200;
private $message = '操作成功';
private $data = [];
/**
* 设置返回的信息
* @param int $code 编号
* @param string $message 信息
*/
public function setMsg($code = 200, $message = '')
{
$this->code = $code;
$this->message = $message;
}
/**
* 设置返回的数据
* @param array $data
*/
public function setData($data = [])
{
$this->data = $data;
}
/**
* 返回JSON数据
* @param int $code
* @return $this
*/
public function responseJSON($code = 200)
{
$arrayResult['code'] = $this->code ?? 200;
$arrayResult['msg'] = $this->message;
$arrayResult['data'] = $this->data;
return response()->json($arrayResult, $code)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
// public function responseXML($code = 200)
// {
//
// }
}
很简单,是不是。实际上,Response类应该作为抽象类,包含setMsg()和setData()两个方法,responseJSON()和responseXML()应该继承Resonse抽象类,这样会更好,因为这样符合开闭原则,但是这里为了演示,就简单处理了。
如何使用Response呢?有四种方式
1:在当前控制器中的初始化方法中
private $response;
public function __construct()
{
$this->response = new Response();
}
2:在每个方法中new一个Response
$response = new Response();
$response->setMsg(200,'成功');
return $response->responseJSON();
3:作为参数传入
public function set(Request $request, Response $response)
{
$setting = Setting::first(); // 获取setting数据表中一条数据
if ($request->isXmlHttpRequest()) { // 只处理ajax提交的,其他不处理
if (!empty($setting->id)) { // 如果数据存在,更新数据
Setting::edit($setting, $request->all());
} else { // 如果数据表中没有任何数据,则添加一条数据
Setting::add($request->all());
}
$response->setMsg(200,'成功');
return $response->responseJSON();
}
return view('admin.siteSetting');
}
4:在父类Controller的初始化方法中
class Controller extends BaseController
{
//
protected $response;
public function __construct()
{
$this->response = new Response();
}
}
这四种都可以,前边的是那三种,多多少少都有点麻烦,所以我用了第三种,在父类初始化的时候,生成一个Response对象,这样,继承它的控制器都可以使用。
我们打开/app/Http/Controllers/Admin/SiteSettingController.php文件
可以看到
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Setting;
use Illuminate\Http\Request;
class SiteSettingController extends Controller
{
public function set(Request $request)
{
$setting = Setting::first(); // 获取setting数据表中一条数据
if ($request->isXmlHttpRequest()) { // 只处理ajax提交的,其他不处理
if (!empty($setting->id)) { // 如果数据存在,更新数据
Setting::edit($setting, $request->all());
} else { // 如果数据表中没有任何数据,则添加一条数据
Setting::add($request->all());
}
// 继承父类Controller的response属性
$this->response->setMsg(200,'成功');
return $this->response->responseJSON();
}
return view('admin.siteSetting');
}
}
一定要return结果。
然我们添加一条信息看看
添加成功!!
但是还没有完,当我们点击确定按钮后,页面刷新了,刷新后,数据没有了,我们应该取出数据,展示出来,还有那个“增加”按钮,改成“保存”更好。
因为要从数据库中读取数据,然后把数据传给视图,让视图渲染出来,我们回到SiteSettingController控制器,在set()方法的最后添加一行代码。
public function set(Request $request)
{
$setting = Setting::first(); // 获取setting数据表中一条数据
if ($request->isXmlHttpRequest()) { // 只处理ajax提交的,其他不处理
if (!empty($setting->id)) { // 如果数据存在,更新数据
Setting::edit($setting, $request->all());
} else { // 如果数据表中没有任何数据,则添加一条数据
Setting::add($request->all());
}
// 继承父类Controller的response属性
$this->response->setMsg(200, '成功');
return $this->response->responseJSON();
}
// 把从数据库读出的数据传给视图
$data['data'] = $setting;
return view('admin.siteSetting', $data);
}
视图如何得到控制器传给它的值呢?如果在控制器中你是这样用的
return view('welcome', ['name' => 'Samantha']);
那么在视图中,这样才能显示数据
Hello, {
{ $name }}.
重要的是两个花括号中的变量,这个变量就是控制中['name' => 'Samantha']数组的key。
因为我们的控制器中,把读出的数据,赋值给了$data['data'],那么key是data,值就是数据表中的字段,我要取出网站名称,则使用
{
{ $data['name'] }}
取出网址
{
{ $data['url'] }}
name和url都是数据表中的字段,取其他值也是一样的取法。
然后打开/resources/views/admin/siteSetting.blade.php文件,在每个input的后边,加入value="{ { $data['key'] }"的形式,例如获取网站名称
<input type="text" id="L_name" name="name" required="" lay-verify="name" autocomplete="off"
class="layui-input input_with" value="{
{ $data['name'] }}">
其它也是一样的,除了logo那一项,因为logo是要上传文件的,后边我再讲。
当你把这些工作完成后,就能读出数据了。
结束!
最近在一个项目上遇到需要修改数据库名称、物理文件名和逻辑文件名。如下图所示,数据库ty_cms_lz的物理文件名是ty_cms_lz.mdf和ty_cms_lz_0.ldf,逻辑文件名是lhc_cms和lhc_cms_log。 这样看上去很别扭,而且数据库一多很容易混淆。一般新建一个数据库的话,逻辑文件名和物理文件名是跟数据库名称对应起来的。如下图新建的ty_test数据库。 为了让这...
1.使用JDBC操作Oracle数据库时,使用java.sql.Date类型对应数据库的date类型,此时只能保存和读取日期部分,时间(时分秒)部分不能读取和保存;查询结果集可以直接获取Date类型的数据:java.sql.Date date=resultSet.getDate(“dateTime”);java.sql.Date类型的数据也可以直接保存到数据库或者与数据库中date类型的数据直...
Ok, so i have the following method. Basically I am calling an API backend, posting username and password, and if those pass, in the response, the server sends me a 200 status. What I want to do, is in...
使用DBSCAN 来进行聚类运算DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。 该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。from sklearn import datase...
一 解压压缩命令一览1.1 zip1.2 tar二 usr文件夹解析2.1 /usr/bin/2.2 /usr/include/2.3 /usr/lib2.4 /usr/local2.5 /usr/sbin2.6 /usr/share/2.7 /usr/src/三 源码安装实例如ffmpeg以及Open CV3.1 AutoTools及CMake及qmake3.2 卸载...
【从零开始学习SpirngBoot—常见异常汇总】 事情的起源,无意当中在一个群里看到这么一句描述:”有人么?默默的问一句,现在开发用mybatis还是hibernate还是jpa”?然后大家就进行各种回答,但是没有有质疑这句话描述的合理性,个人觉得需要清楚概念的,在这里mybatis大家肯定是没有什么疑问,我们把上面那句话更改下,方便我们抛出一些点出来,去掉mybatis修改为:
一、点和矢量 (一)坐标系分类笛卡尔坐标系;圆柱坐标系;球坐标系;通常来说笛卡尔坐标系是我们最常用的坐标系,但我们同样要根据不同的情况来选择合适的坐标系,例如我们在做一些环绕动画的时候,采用圆柱坐标系可以更简单。在三维笛卡尔坐标系中又分为左右手坐标系,用左右手来方便做记忆,大拇指指向X轴,食指指向Y轴,中指指向Z轴,3指垂直即可建立模型。左右坐标系的转换只需要把一个轴转换,保留另外两个轴的
前提: 我下载的Python是windows版本的,演示过程是在win10 64位操作系统上安装的。1、下载 进入官网https://www.python.org/,找到Dowdloads,根据所需下载对应版本,如下图所示: 这是我下载的版本: 下载完成之后,双击exe文件,即可开始安装。2、安装
IJKPlayer的库初始化加载流程斜体样式
爱国者u盘驱动是aigo官方为U盘II代提供的驱动程序,安装后可以让电脑正常识别外接usb设备,帮助各位轻松完成对U盘的存取写入操作。爱国者u盘驱动体积小巧,使用方便,兼容win7、win10等主流操作系统,一次安装长期生效,后续只要有u盘插入即可自动唤醒,非常便捷。爱国者u盘驱动主要针对旗下各型号U盘设备,无论是2.0还是3.0全都可以兼容,在各方面的表现还是十分突出和优异的,有需要的朋友赶快下...
自适应阈值化操作:adaptiveThreshold()函数.自适应阈值则,是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值
Python 如何区分一个模块是标准库还是第三方库