网站配置,就是网站的一些基本信息,话不多说,上图
为了演示,我写了这些信息,其实应该还有其他配置的。
这些信息是要保存的,但是数据库中缺少表,我们需要建立一张数据表,表名叫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 () {//关闭当前framexadmin.close();// 可以对父窗口进行刷新xadmin.father_reload(););return false;});});
当点击“增加”按钮的时候,通过ajax提交数据,要求服务器返回json格式的数据,我们定义服务器返回这样的格式:
{"code": 200,"message": "操作成功","data": []}
code是200代表成功,code是400代表客户端请求有误,code是500代码服务器端出错。你可以定义的更详细,我这里为了方便暂时定义这个三个。
这样的json格式数据,每个接口都要用,我们写一个类来实现它,专门用于处理返回接口数据。
在app目录下,新建一个Services文件夹,在这个文件夹下再新建一个Response类,用户处理我们返回的结果。如下
<?phpnamespace 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文件
可以看到
<?phpnamespace 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是要上传文件的,后边我再讲。
当你把这些工作完成后,就能读出数据了。
结束!
如果觉得《Lumen企业站内容管理实战 - 网站配置》对你有帮助,请点赞、收藏,并留下你的观点哦!