hualinux 进阶 vue 5.4:用Element实现增删改查(四)后端thinkphp代码编写

目录

一、需要修改的thinkphp目录文件

二、TP数据库的配置

2.1 配置数据库(config/database.php)

2.2 添加php表字段配置(config/vue.php)

三、图片放置(public/pic)

四、路由

4.1 使路径参数名支持横杠(config/route.php)

4.2 配置路由(route/app.php)

五、图片保存配置(config/filesystem.php)

六、控制器(app/controller)

6.1 vue.php控制文件

6.1.1 生成vue.php文件

6.1.2 vue.php控制文件代码

6.2 index.php控制器代码

七、模型(app/model/Vue.php)

八、使用postman测试(可选)

8.1 rest 风格代码

8.2 测试删除功能(delete)

8.3 测试更新功能(put) 

8.4 测试其它 


前篇写的vue后端对应的mysql数据表,这篇继续讲后端thinkphp代码。

需要的知识点:thinkphp,推荐《ThinkPHP6.0完全开发手册

thinkphp使用的是mvc框架,因为前后端分离,我这里只使用了mc,并没有使用它的模板视图v,现在前后端分离是主流,所以后端的话一般不用学v。

一、需要修改的thinkphp目录文件

红色框的需要添加或修改的,其它不动

二、TP数据库的配置

2.1 配置数据库(config/database.php)

前篇说有mysql数据表的生成,现在使用TP连接mysql,在连接之前需要配置一下,打开config/database.php配置文件,只要填写用户名数据库类型,用户名和密码,数据库名,就行了,如下所示:

 // 数据库连接配置信息
    'connections'     => [
        'mysql' => [
            // 数据库类型
            'type'            => env('database.type', 'mysql'),
            // 服务器地址
            'hostname'        => env('database.hostname', '127.0.0.1'),
            // 数据库名
            'database'        => env('database.database', 'hua'),
            // 用户名
            'username'        => env('database.username', 'root'),
            // 密码
            'password'        => env('database.password', 'root'),
            // 端口
            'hostport'        => env('database.hostport', '3306'),
...

2.2 添加php表字段配置(config/vue.php)

上篇我们说了,mysql的vue表和vue的字段并不是一一对应的,而是添加工拼接的,如

SELECT picid, CONCAT('http://192.168.3.200/pic/',savename) AS picurl,lable,`describe`,0 AS isSet FROM vue;

picurl是由'http://192.168.3.200/pic/'加表的“savename”字段拼成的,isSet是直接添加的,如果我们在php写SQL是可以这样直接写,但是如果图片的服务器地址变了,在生产环境中,那你不是要修改源码,php还好,默认源码是可以看到的,但是如果是java、go之类,源码是不可变的。所以一般做法就是把它抽出来放在独立的配置文件中。

我这里建立一个自定义的数据表的php配置就是放vue中没有的字段的。操作如下:

创建config/vue.php代码如下:

<?php
return [
    "picpath" => 'http://192.168.3.200/pic/',
    'isSet'=> 0
];

这样我用thinkphp就可以这样写了(这字段我写在model/Vue.php中)下面会给全代码。

        $vueConf=Config::get('vue');
        // 相当于 SELECT picid, CONCAT('http://192.168.3.200/pic/',savename) AS picurl,lable,`describe`,0 AS isSet FROM vue;
        $filedStr='picid, concat(\''.$vueConf['picpath'].'\',savename) as picurl,lable,`describe`,'.$vueConf['isSet'].' as isSet';

三、图片放置(public/pic)

我在public/pic放了一些默认的图片,作为例子,随便一些都行,不影响的,只是测试使用。

四、路由

这里的路由与vue路由是一样的,不同的是绑定的不是组件,而是函数。

4.1 使路径参数名支持横杠(config/route.php)

thinkphp默认参数是不支持横杠的,要修改config/route.php使它支持

    // 默认的路由变量规则 '[\w\.]+',
    'default_route_pattern' => '[\w\.\-]+',

4.2 配置路由(route/app.php)

我添加了一个名为vue的控制器,还有批量删除、上传等功能,是不同路径的,需要得添加一下。打开route/app.php,修改后的代码如下:

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
use think\facade\Route;

// Route::get('think', function () {
//     return 'hello,ThinkPHP6!';
// });


Route::rule('/','index','GET|POST|DELETE|PUT|')->allowCrossDomain();

Route::get('hello/:name', 'index/hello');

Route::post('index/upload','index/upload')->allowCrossDomain();
Route::delete('index/dels','index/dels')->allowCrossDomain();
Route::resource('vue','Vue')->vars(['vue' => 'picid']);

ps:其中 resource 是资源路由,可以直接生成rest api的填写后执行 php think make:controller Vue就可以自动生成控制器了

五、图片保存配置(config/filesystem.php)

我在文件系统配置config/filesystem.php中,添加了2个配置,一个是 uploads是生产环境保存的图片位置,一个是temp是临时图片保存位置(定时删除就行了,比如这个月2号删除上个月之前所有的临时文件)

config/filesystem.php配置代码如下:

<?php

return [
    // 默认磁盘
    'default' => env('filesystem.driver', 'local'),
    // 磁盘列表
    'disks'   => [
        'local'  => [
            'type' => 'local',
            //'root' => app()->getRuntimePath() . 'pic',
            //'root' => 'pic',
            'root' => 'pic',
        ],
        'public' => [
            // 磁盘类型
            'type'       => 'local',
            // 磁盘路径
            // 'root'       => app()->getRootPath() . 'public/pic',
            'root'       => 'pic',
            // 磁盘路径对应的外部URL路径
            'url'        => '/pic',
            // 可见性
            'visibility' => 'public',
        ],
        // 更多的磁盘配置信息
        'uploads' => [
            // 磁盘类型
            'type'       => 'local',
            // 磁盘路径
            // 'root'       => app()->getRootPath() . 'public/pic',
            'root'       => 'pic',
            // 磁盘路径对应的外部URL路径
            'url'        => '/pic',
            // 可见性
            'visibility' => 'public',
        ],
        'temp' => [
            // 磁盘类型
            'type'       => 'local',
            // 磁盘路径
            // 'root'       => app()->getRootPath() . 'public/pic',
            'root'       => 'temp',
            // 磁盘路径对应的外部URL路径
            'url'        => '/temp',
            // 可见性
            'visibility' => 'public',
        ],
    ],
];

六、控制器(app/controller)

这里的控制器有2个,一个是app/controller/Index.php和app/controller/Vue.php,主要是处理

Index.php:主要是处理上传,批量删除 

Vue.php:主要是查询所有数据、某行的操作保存、删除、增加行等

6.1 vue.php控制文件

6.1.1 生成vue.php文件

vue.php配置文件是直接使用 “php think make:controller Vue”命令生成的 。执行此命令有2种方式

方法一:使用命令提示符创建,操作如下:

  1. 打开命令提示符:开始菜单->运行->输入 cmd 回车
  2. 进入vueapi项目的根目录,我的为D:\phpstudy_pro\WWW\vueapi,相关命令是
    d:
    cd D:\phpstudy_pro\WWW\vueapi
    
  3. 执行  php think make:controller Vue 命令

方法二:直接使用phpStorm的终端命令

6.1.2 vue.php控制文件代码

生成的Vue.php文件是id的,我修改一个变成picid这样方便记忆,代码如下:

<?php
declare (strict_types = 1);

namespace app\controller;

use app\model\Vue as ModelVue;
use Symfony\Component\VarDumper\Cloner\Data;
use think\File;
use think\Request;

class Vue
{
    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index(Request $request)
    {
        // pageSize 每页多少条记录
        $pageSize=$request['pageSize'];
        $db = new ModelVue();
        $res=$db->selAll($pageSize);
        return json($res);
    }

    //图片移动,把从临时目录移动到public/pic目录下,以月为单位。
    public function picFileMove(Request $request){
        $picrow=$request['picrow'];
        $fileNew ='';
        $savename=$picrow['savename'];
        // 如果图片修改了,则移动一下图片
        if($savename != '0'){
            $savename = date('Ym').'/'.basename($savename);
            $fileOrig = '../public/pic/'.$picrow['savename'];
            //按月分
            $fileNewPath='../public/pic/'.date('Ym').'/';
            $fileNew = $fileNewPath.basename($savename);
            if(!file_exists($fileNewPath)){
                mkdir($fileNewPath);
            }
            rename($fileOrig,$fileNew);
        }else{
            $savename='0';
        }
        return $savename;
    }

    /**
     * 保存新建的资源
     *
     * @param  \think\Request  $request
     * @return \think\Response
     */
    public function save(Request $request)
    {
        $savename = $this->picFileMove($request);
        $picrow=$request['picrow'];

        //这里不需要picid,因为前端没有给出后端生成
        $queryArray=[
            // 因为文件不是很多,是按月来分
            'savename'=> $savename,
            'lable'=>$picrow['lable'],
            'describe'=>$picrow['describe']
        ];

        $db = new ModelVue();

        return $db->saveOne($queryArray);
    }

    /**
     * 显示指定的资源
     *
     * @param  int  $picid
     * @return \think\Response
     */
    public function read($picid)
    {
        //
        $db= new ModelVue();
        return $db->selOne($picid);
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request  $request
     * @param  int  $picid
     * @return \think\Response
     */
    public function update(Request $request, $picid)
    {
        $savename = $this->picFileMove($request);
        $picrow=$request['picrow'];
        $queryArray=[
            'picid'=>$picid,
            // 因为文件不是很多,是按月来分别保存。如果不修改则为字符串'0'
            'savename'=> $savename,
            'lable'=>$picrow['lable'],
            'describe'=>$picrow['describe']
        ];

        $db = new ModelVue();

        return $db->updateByPicid($queryArray);
        
        
    }

    /**
     * 删除指定资源
     *
     * @param  String  $picid
     * @return \think\Response
     */
    public function delete($picid)
    {
        $db = new ModelVue();
        $savename=$db->findSavename($picid);
        if(file_exists('../public/pic/'.$savename)){
            unlink('../public/pic/'.$savename);
        }
        return $db->delOne($picid);
    }
}

6.2 index.php控制器代码

index.php控制器代码如下:

<?php
namespace app\controller;

use app\BaseController;
use app\model\Vue as ModelVue;
use app\Request;
use think\console\command\Clear;
use think\db\Query;
use think\facade\Config;
use think\response\Json;

use function PHPSTORM_META\type;

class Index extends BaseController
{
    public function index()
    {
        return 'welcome thinkphp';
        
    }

     /*
      * 主要是上传文件,主要是图片,我这里是先保存在临时目录中,当vue中点保存,才会
      * 把临时目录中的文件移动到public/pic目录下
      * */
    public function upload(){

        //上传先放在临时目录下,定时清空,点保存,如果文件大则按日,很小则按月,我这里很小的,所以不按
        $file = request() -> file('file');
        
        // 上传到本地服务器 putFile( 'topic', $file);
        // temp/20210330\8c1b99851c3d3ad1f89868ef270a81cf.jpg
        $savename = \think\facade\Filesystem::putFile('temp',$file);

      //下面代码是调试,可以看效果。如savename值为:“uploads/20210324\9a0cc05f75c6dd4b6ada9326f7ddd937.jpg”
      /*   $fp = fopen('log.txt','w');
        //file_put_contents('log.txt','');
        fwrite($fp,'picid值为:'.request()->post('picid').'n');
        fwrite($fp,'savename值为:'.$savename);
        fclose($fp);  */

        return json($savename);
        
    }

   //批量删除功能,tp支持以数组方式删除,这里是picid数组
    public function dels(Request $request)
    {
        // 还有涉及这些图片的保存也要删除,这里我就不写了
        $picids_json=$request['picids'];
        // var_dump($picids)知道是数组类型 [ "021", "022" ] 
        $picids=json_decode($picids_json);
        $db=new ModelVue();
        $res=$db->delBypicids($picids);
        return $res;
    }

    // 这个是测试删除功能,可以不写
    public function tsetDel(){
        $fileOrig = '../public/pic/temp/20210328/a.jpg';
        $filePath = '../public/pic/a.jpg';

        if(!file_exists($fileOrig)){
            return "文件或目录不存在!";
        }
        //以重命名方式移动,目标不能写路径,会报错:拒绝访问,code 5
        rename($fileOrig,$filePath);
        return "ok";
    }
    
}

七、模型(app/model/Vue.php)

模型文件Vue.php是我手工创建的,目录也是。所有数据库操作都写在这里,代码如下:

<?php
namespace app\model;

use think\facade\Config;
use think\Model;

class Vue extends Model{

    /*生成唯一标志
    *标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
    */
    public static function uuid(){
        $chars = md5(uniqid(mt_rand(), true));
        $uuid = substr ( $chars, 0, 8 ) . '-'
            . substr ( $chars, 8, 4 ) . '-'
            . substr ( $chars, 12, 4 ) . '-'
            . substr ( $chars, 16, 4 ) . '-'
            . substr ( $chars, 20, 12 );
        return ''.$uuid ;
    }

    // 这是要查询的字段,因为多次使用,我直接把变它成字符串了
    public static function vueSQLField(){
        $vueConf=Config::get('vue');
        // 相当于 SELECT picid, CONCAT('http://192.168.3.200/pic/',savename) AS picurl,lable,`describe`,0 AS isSet FROM vue;
        $filedStr='picid, concat(\''.$vueConf['picpath'].'\',savename) as picurl,lable,`describe`,'.$vueConf['isSet'].' as isSet';
        return $filedStr;
    }

    // 带分页功能的查询
    public function selAll($pageSize){
        // isSet是布尔值,不能用双引号
        //$result = Vue::field("picid, concat('http://192.168.3.200/pic/',savename) as picurl,lable,`describe`, 0 as isSet")->select();
        //$result = Vue::field(self::vueSQLField())->select();

        // 带分页功能
        $list = Vue::field(self::vueSQLField())->order('id', 'ASC')->paginate($pageSize);
        return ['list' => $list];
    }

    //通过pic查询一条记录
    public function selOne($picid){
        return vue::where('picid',$picid)->field(self::vueSQLField())->select();
    }

    //通过picid查数据库的savename
    public function findSavename($picid){
        return vue::where('picid',$picid)->value('savename');
    }

    // 通过picid删除一条记录
    public function delOne($picid){
        return vue::where('picid',$picid)->delete();
    }

    //通过picid更新一条记录,是直接传数组的方式
    public function updateByPicid($arry_row){
        // 如果为空则说明,文件交没有修改
        if($arry_row['savename']=='0'){
            return vue::where('picid',$arry_row['picid'])->update([
                'lable' => $arry_row['lable'],
                'describe' => $arry_row['describe']
            ]);
        }else{
            return vue::where('picid',$arry_row['picid'])->update([
                'savename' => $arry_row['savename'],
                'lable' => $arry_row['lable'],
                'describe' => $arry_row['describe']
            ]);
        }

    }

    // 保存一条记录,主要是vue增加一条记录,然后点保存
    public function saveOne($arry_row){
        $picid = self::uuid();
        $arry_row['picid']=$picid;
        //去掉savename的值
        if($arry_row['savename']=='0'){
            unset($arry_row['savename']);
        }
        vue::strict(false)->insert($arry_row);
    }

    // 批量删除功能,tp支持以数组方式删除,通过图片id数组进行删除
    public function delBypicids($picids){
        return vue::where('picid','in',$picids)->delete();
    }
    // 通过picid,更新savename,即更新图片只在路径名。
    public function updatepic($picid,$savename){
        return vue::where('picid',$picid)->update(['name'=>$savename]);
    }

}

八、使用postman测试(可选)

如果要测试上面是否写的正确,可以不使用vue代码,直接用postman实现put、post、delete提交,比如我提交一个删除,看一下是否成功

8.1 rest 风格代码

TP路由部分的资源例子对rest风格代码做了说明

Route::resource('blog', 'Blog');

表示注册了一个名称为blog的资源路由到Blog控制器,系统会自动注册7个路由规则,如下:

标识请求类型生成路由规则对应操作方法(默认)
indexGETblogindex
createGETblog/createcreate
savePOSTblogsave
readGETblog/:idread
editGETblog/:id/editedit
updatePUTblog/:idupdate
deleteDELETEblog/:iddelete

具体指向的控制器由路由地址决定,你只需要为Blog控制器创建以上对应的操作方法就可以支持下面的URL访问:

http://serverName/blog/
http://serverName/blog/128
http://serverName/blog/28/edit

 

8.2 测试删除功能(delete)

比如我要删除picid为100的postman写法如下图所示:

PS:192.168.3.200/index.php/vue/100,index.php是入口文件,vue表示 vue控制器

8.3 测试更新功能(put) 

因为我放在vue中是格式为:IP/index.php/vue/<picid值>

更新是更新某行的信息。这里我就不修改图片了,怎样提交更新主要是看PHP代码决定的。涉及更新部分代码为

  public function update(Request $request, $picid)
    {
        $savename = $this->picFileMove($request);
        $picrow=$request['picrow'];
        $queryArray=[
            'picid'=>$picid,
            // 因为文件不是很多,是按月来分,如果不修改则为字符串'0'
            'savename'=> $savename,
            'lable'=>$picrow['lable'],
            'describe'=>$picrow['describe']
        ];
...
}

从上面知道,使用的键值对方式,而且有嵌套,猜json做前后端交互比较适合,而且主流的语言一般都支持json。上面php数组方式写成json为并值赋值

{
    "picrow":{
        "savename":"0",
        "lable":"111",
        "describe":"111"
    }
}

PS:上面是图片没有修改,把lable和describe修改为111

我要修改picid为001中的lable和 describe,可以是这样

ps:请求提交并不是一成不变的,是要根据代码写的,结合对应的参数。

可以执行sql查询一下 SELECT * FROM vue WHERE picid=001,发现被修改了,图片并没有修改。

8.4 测试其它 

其它get查询、post更新、批量删除我不一一测试了,差不多的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值