综合演示:MySQL数据库操作

文档概述

本演示文档展示了如何使用轻语言开发一个完整的 Web 应用,包含以下核心功能:

  • 用户注册:前端提交账号密码 → 后端 API 接收 → 存入 MySQL
  • 用户登录:前端提交凭证 → 后端验证 → 返回登录状态(Session)
  • 管理端:查询、模糊查询、修改、删除用户数据
  • 安全性:使用 PDO 参数化查询防止 SQL 注入

涉及组件

  • 标签、按钮、单行输入框、表格、弹性布局、对话框
  • 请求接口、MySQL连接、MySQL查询、MySQL执行、会话凭证

部署要求

  • PHP 环境(本地推荐 PhpStudy)
  • MySQL 数据库(需提前创建 test 数据库和 mytable 表)

数据库建表语句

-- 建表语句
CREATE TABLE `mytable` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `pass` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

接口请求地址

前端通过 请求接口 函数调用后端 API,实际 HTTP 请求格式为:

http://你的域名/User.php?a=注册账号
http://你的域名/Admin.php?a=查询所有用户

💡 参数 a 指定要调用的后端函数名。

网站访问地址

  • 用户端

    • http://域名.com/

    • http://localhost:1996/index.html

    • 子级目录:http://localhost/mywebsite/

  • 管理端

    • http://域名.com/index.html?admin

    • http://localhost:1996/index.html?admin

    • 子级目录:http://localhost/mywebsite/index.html?admin

MySQL相关操作函数

本演示文档使用的 MySQL 操作函数(如 MySQL连接MySQL查询MySQL执行 等)的详细说明和参数列表,请参考专门的文档:服务端(PHP)函数_MYSQL操作.md

以下为完整项目代码:

用户端

用户注册登录页面.spldg

<?xml version="1.0" encoding="utf-8"?>
<页面 标题="用户注册登录" 宽度="440" 高度="270">
  <绝对布局 名称="根布局">
    <标签 名称="标签1" 左边="12" 顶边="12" 高度="40" 宽度="498" 文本="注册/登录账号" 字体大小="24px" />
    <按钮 名称="按钮1" 左边="12" 宽度="128" 顶边="150" 高度="40" 文本="注册账号" 文本颜色="#ff0089" />
    <单行输入框 名称="单行输入框1" 左边="12" 顶边="58" 高度="40" 宽度="288" 提示文本="请输入账号" />
    <单行输入框 名称="单行输入框2" 宽度="288" 高度="40" 左边="12" 顶边="104" 提示文本="请输入密码" />
    <按钮 名称="按钮2" 宽度="128" 高度="40" 左边="172" 顶边="150" 文本="登录账号" />
    <标签 名称="标签2" 左边="14" 顶边="204" 高度="25" 宽度="166" 文本="登录状态?" 背景颜色="#BFE8FB" />
    <标签 名称="标签3" 宽度="99" 高度="25" 左边="201" 顶边="204" 文本="退出" 文本颜色="#FF0000" 光标样式="pointer" 背景颜色="#BFE8FB" />
  </绝对布局>
</页面>

用户注册登录页面.spl

' ****************************************************************************
' 版权说明:Copyright(C) All Rights Reserved VcnStudio
' 程序版本:V1.0
' 文件描述:
' 修改日志:
' ****************************************************************************

' 页面变量,整个页面都能使用
变量 页面变量 = "新页面"

事件 页面加载完毕()
    ' 设置输入框2的类型为:输入密码模式
    单行输入框2.类型 = "password"
    ' 检测登录状态
    刷新登录状态()
结束 事件

事件 按钮1.被单击(源对象,事件源)
    如果(单行输入框1.内容 == "" 或 单行输入框2.内容 == "")
        信息框("账号与密码不能为空!")
        返回
    结束 如果
    变量 待提交数据 = "username=" + 单行输入框1.内容 + "&password=" + 单行输入框2.内容
    ' 调试输出("待提交数据:" + 待提交数据)
    请求接口("User","注册账号",(请求结果,标记)=>{
        ' 这里返回的请求结果为后端我们的接口函数返回的内容
        调试输出(请求结果)
        如果(请求结果 == "")
            信息框("请求失败!")
            返回
        结束 如果
        ' 由于我们后端返回的为 JSON 字符串,这里我们将其转换为 JSON 对象
        变量 jsonObj = JSON解析(请求结果)
        信息框("返回结果:" + jsonObj.msg + ",状态码:" + jsonObj.code)
    },待提交数据)
    '* ==============================================================================
    '* 部分朋友可能会有个疑问:
    '* 为什么这里不能像安卓那样使用直链操作数据库?
    '* 答:
    '*    如果使用直链数据库操作,网页右键查看源代码、您的数据库账号密码就全部暴露了,
    '*    这种方式无异于是告诉任何人您的数据库账号密码,因此任何人都能连接操作。
    '*    使用后端接口操作数据库就可以避免这个问题,因为后端接口代码是运行在服务器上面的
    '*    右键查看网页源码,无法查看到后端代码,因此采用这种方式是比较安全的。
    '* ==============================================================================
结束 事件

事件 按钮2.被单击(源对象,事件源)
    如果(单行输入框1.内容 == "" 或 单行输入框2.内容 == "")
        信息框("账号与密码不能为空!")
        返回
    结束 如果
    变量 待提交数据 = "username=" + 单行输入框1.内容 + "&password=" + 单行输入框2.内容
    请求接口("User","登录账号",(请求结果,标记)=>{
        调试输出(请求结果)
        如果(请求结果 == "")
            信息框("请求失败!")
            返回
        结束 如果
        变量 jsonObj = JSON解析(请求结果)
        如果(jsonObj.code == 100)
            弹出提示("账号登录成功")
            刷新登录状态()
        否则
            弹出提示(jsonObj.msg)
        结束 如果
    },待提交数据)
结束 事件

函数 刷新登录状态()
    请求接口("User","取登录状态",(请求结果,标记)=>{
        如果(请求结果 == "")
            返回
        结束 如果
        调试输出(请求结果)
        变量 jsonObj = JSON解析(请求结果)
        如果(jsonObj.code == 100)
            标签2.文本 = "欢迎回来:" + jsonObj.msg
        否则
            标签2.文本 = jsonObj.msg
        结束 如果
    })
结束 函数

事件 标签3.被单击(源对象,事件源)
    请求接口("User","退出登录",(请求结果,标记)=>{
        刷新登录状态()
    })
结束 事件

用户注册登录页面对应的服务器脚本程序文件:User.sph

' ****************************************************************************
' 版权说明:Copyright(C) All Rights Reserved VcnStudio
' 程序版本:V1.0
' 程序作者:
' 联系信息:
' 文件描述:API 接口文件、运行在服务器中;服务器需安装PHP环境、可用于
'      在服务器端操作数据库、接收前端APP、软件、网站或小程序提交
'      的请求;编译时将输出为标准PHP脚本文件。
'      本文件在前端访问时的地址:
'      http://你的域名/Api.php?a=待调用函数名称
' 注意事项:
'      1、API 文件中的函数都为全局函数;多个API文件中不能存在相同名称的函数,建议命名为:API接口文件名_函数名
'      2、如果服务器目录存在二级目录、域名中也需要带上二级目录,例如:http://你的域名/二级目录/Api.php?a=待调用函数名称
'      3、API 文件运行时需要服务器安装 PHP 环境的支持;本地开发时可以使用 PhpStudy2018
'      4、如果核心库没有相关中文函数,在代码中可以直接使用PHP原始英文函数
' ****************************************************************************
' 开启 Session 记录用户登录状态
启用会话凭证()

' 向客户端发送服务器的响应报头(Response Header),一般保持默认即可
置响应头("Content-Type: text/html; charset=utf-8")
置响应头("Content-Language: zh-CN")

' 引用轻语言封装的PHP核心库,注:如果要删除该引用请确保当前文件中未使用轻语言封装的函数
引用 "library/qing.core.php"

' 连接数据库,参数分别为:地址,数据库名称,数据库账号,数据库密码
MySQL连接("localhost","test","root","root")

' 调用主函数:“文件被访问”、即当在任何前端中访问该文件时,地址中不带任何参数名,都将会先调用该函数
文件被访问()

' 入口函数,函数名可自定义命名,主要作用:
' 当本文件被访问时,获取其前端传来的请求参数值,根据请求参数值调用当前文件中的函数
函数 文件被访问()
    ' 通过URL中的键参获取要执行的函数,这里我们默认规定键名为“a”,例如:
    ' 前端请求地址为:http://xxx.com/本文件名.php?a=测试输出
    ' 其“a”后面的值“测试输出”即为我们要执行的函数,使用“取请求值”函数将其取出后,然后执行。
    变量 待执行函数名 = 取请求值("a")
    如果(为空(待执行函数名))
        输出 "待执行函数不能为空"
    否则
        ' 增加安全验证,只允许执行我们定义的函数,当然不加也可以,这里仅作标准开发演示
        变量 可被执行的函数列表 = [ "注册账号", "登录账号" ,"取登录状态","退出登录"]
        如果(取成员是否存在(待执行函数名,可被执行的函数列表) == 真)
            输出 执行函数(待执行函数名)
        否则
            输出 "请求执行非法的函数"
        结束 如果
    结束 如果
结束 函数


' 前端请求注册账号
函数 注册账号()
    ' 注意:调用该函数之前,您需要提前在您的数据库中创建一个表,
    ' 表中至少包含2个字段:name,pass
    ' 然后在该函数中接收前端传来的数据值
    变量 userName = 取请求值("username")
    变量 passWord = 取请求值("password")
    ' 检测一下,提交的请求值是否为空值
    如果(为空(userName))
        返回 格式化内容(1,"账号不能为空")
    结束 如果
    如果(为空(passWord))
        返回 格式化内容(1,"密码不能为空")
    结束 如果
    ' 检测一下,添加的目标账号是否已经存在
    如果(MySQL查找("mytable","name = ?",[userName]))
        返回 格式化内容(1,"添加的账号:" + userName + "已经存在")
    结束 如果
    ' 如何符合添加要求,则将这些数据添加到一个数组中
    变量 待添加数据 = [userName,passWord]
    ' 然后构建SQL语句、这里需要注意:由于内置的 MySQL 操作函数采用了PDO方式(防注入)
    ' 因此这里的SQL语句可能和大家平常在网上看到那种不一样,具体格式为:
    变量 SQL命令 = "insert into mytable(name,pass)value(?,?)"
    ' mytable 为数据库中的表名
    ' mytable 后面括号的内容为数据表中的字段
    ' value   后面括号为表中字段对应要添加的占位符
    ' 规定:第一个括号里面有几个字段,value后面就要添加几个 ? 作为占位符
    ' 而我们待添加的数据成员长度(数组个数)也必须与字段数量完全一致
    ' 例如:
    ' 上述我们要添加 2 个值,那么待添加的数据数组长度也必须为 2 个
    ' 上述准备工作做好后,就可以开始向数据库中添加数据了
    ' 如果 MySQL执行 函数执行成功,返回真、否则返回假
    如果(MySQL执行(SQL命令,待添加数据))
        返回 格式化内容(0,"数据添加成功")
    否则
        返回 格式化内容(1,"数据添加失败")
    结束 如果
结束 函数

函数 登录账号()
    ' 登录账号的实现逻辑:
    ' 使用前端提交的请求值查询数据表中是否存在指定记录,如果存在且与提交数据匹配
    ' 则保护登录状态,返回给前端登录成功
    变量 userName = 取请求值("username")
    变量 passWord = 取请求值("password")
    ' 检测一下,提交的请求值是否为空值
    如果(为空(userName) 或 为空(passWord))
        返回 格式化内容(1,"账号或密码不能为空")
    结束 如果
    ' 查询表中是否存在符合请求值的记录
    变量 查询结果 = MySQL取一行("mytable","name=? and pass=?",[userName,passWord])
    如果(为空(查询结果) 或 取数组成员数(查询结果) == 0)
        返回 格式化内容(1,"账号或密码不正确!")
    结束 如果
    ' 否则保存登录状态,并返回登录成功
    置会话凭证("登录账户",userName)
    返回 格式化内容(100,"登录成功!")
结束 函数

函数 取登录状态()
    变量 已登录账户 = 取会话凭证("登录账户")
    如果(已登录账户 != "")
        返回 格式化内容(100,已登录账户)
    否则
        返回 格式化内容(1,"未登录")
    结束 如果
结束 函数

函数 退出登录()
    ' 删除会话凭证中保存的:登录账户 相关数据
    销毁会话凭证()
结束 函数

管理端

管理页面.spldg

<?xml version="1.0" encoding="utf-8"?>
<页面 标题="后台管理" 宽度="819" 高度="478">
  <绝对布局 名称="根布局">
    <按钮 名称="按钮1" 左边="329" 宽度="78" 顶边="18" 高度="31" 文本="查询" />
    <表格 名称="表格1" 左边="21" 顶边="55" 高度="346" 宽度="582" />
    <单行输入框 名称="单行输入框1" 左边="21" 顶边="18" 高度="31" 宽度="302" 提示文本="请输入待查询用户" />
    <按钮 名称="按钮2" 宽度="77" 高度="31" 左边="413" 顶边="18" 文本="模糊查询" />
    <按钮 名称="按钮3" 宽度="107" 高度="31" 左边="496" 顶边="18" 文本="获取全部数据" />
    <弹性布局 名称="弹性布局1" 左边="628" 顶边="75" 高度="171" 宽度="184">
      <单行输入框 名称="单行输入框2" 提示文本="请输入新用户名" />
      <单行输入框 名称="单行输入框3" 提示文本="请输入新密码" />
      <按钮 名称="按钮_修改" 文本="修改" />
      <按钮 名称="按钮_取消修改" 文本="取消" />
    </弹性布局>
  </绝对布局>
</页面>

管理页面.spl

' ****************************************************************************
' 版权说明:Copyright(C) All Rights Reserved VcnStudio
' 程序版本:V1.0
' 修改日志:
' ****************************************************************************

' 定义当点击编辑标签时显示的弹窗
变量 程_编辑弹窗 = 创建 对话框()

事件 页面加载完毕()
    初始化编辑面板弹窗()
    ' 初始化表头及加载数据
    表格1.置表头("ID","账号","密码","操作")
    查询所有用户数据()
结束 事件

函数 初始化编辑面板弹窗()
    ' 弹性布局1 作为对话框面板内容,添加到弹窗
    弹性布局1.方向 = "column"
    弹性布局1.定位 = ""
    程_编辑弹窗.标题 = "编辑信息"
    ' 调整一下弹性布局中子组件
    变量循环(i = 0,弹性布局1.取子组件数(),1)
        变量 子对象 = 弹性布局1.取子组件(i)
        子对象.外边距 = "5px 0px"
        子对象.内边距 = "5px 0px"
    结束循环
    ' 添加给弹窗
    程_编辑弹窗.置视图(弹性布局1)
结束 函数

事件 按钮1.被单击(源对象,事件源)
    如果(单行输入框1.内容 == "")
        弹出提示("请输入待查询用户名称")
        返回
    结束 如果
    变量 待提交数据 = "name=" + 单行输入框1.内容
    请求接口("Admin","查询指定用户",(请求结果,标记)=>{
        调试输出(请求结果)
        如果(请求结果 == "")
            弹出提示("查询失败")
            返回
        结束 如果
        表格1.清空()
        ' 解析并判断是否查询到数据
        变量 jsonObj = JSON解析(请求结果)
        如果(jsonObj.code == 1)
            弹出提示(jsonObj.msg)
            返回
        结束 如果
        ' 取出查询到的用户列表
        变量 用户列表 = jsonObj.msg
        变量循环(i = 0,取数组成员数(用户列表),1)
            ' 取出列表中每一个用户对象
            变量 用户 = 用户列表[i]
            ' 使用自定义函数创建每一行后面的编辑,删除按钮
            变量 局_操作标签 = 创建操作标签(i)
            ' 然后将用户ID,名称、密码、及操作布局添加到表中
            表格1.添加一行(用户.id,用户.name,用户.pass,局_操作标签)
        结束循环
    },待提交数据)
结束 事件

事件 按钮2.被单击(源对象,事件源)
    ' 模糊查询与精确查询的代码几乎一样,只是后端的SQL语句不同
    如果(单行输入框1.内容 == "")
        弹出提示("请输入待查询用户名称")
        返回
    结束 如果
    变量 待提交数据 = "name=" + 单行输入框1.内容
    请求接口("Admin","模糊查询指定用户",(请求结果,标记)=>{
        调试输出(请求结果)
        如果(请求结果 == "")
            弹出提示("查询失败")
            返回
        结束 如果
        表格1.清空()
        ' 解析并判断是否查询到数据
        变量 jsonObj = JSON解析(请求结果)
        如果(jsonObj.code == 1)
            弹出提示(jsonObj.msg)
            返回
        结束 如果
        ' 取出查询到的用户列表
        变量 用户列表 = jsonObj.msg
        变量循环(i = 0,取数组成员数(用户列表),1)
            ' 取出列表中每一个用户对象
            变量 用户 = 用户列表[i]
            ' 使用自定义函数创建每一行后面的编辑,删除按钮
            变量 局_操作标签 = 创建操作标签(i)
            ' 然后将用户ID,名称、密码、及操作布局添加到表中
            表格1.添加一行(用户.id,用户.name,用户.pass,局_操作标签)
        结束循环
    },待提交数据)
结束 事件

事件 按钮3.被单击(源对象,事件源)
    查询所有用户数据()
结束 事件

函数 查询所有用户数据()
    表格1.清空()
    请求接口("Admin","查询所有用户",(请求结果,标记)=>{
        调试输出(请求结果)
        如果(请求结果 == "")
            返回
        结束 如果
        变量 jsonObj = JSON解析(请求结果)
        ' 注意:这里返回的请求结果里面的 msg 值为一个 JSON 数组
        变量 用户列表 = jsonObj.msg
        变量循环(i = 0,取数组成员数(用户列表),1)
            ' 取出列表中每一个用户对象
            变量 用户 = 用户列表[i]
            ' 使用自定义函数创建每一行后面的编辑,删除按钮
            变量 局_操作标签 = 创建操作标签(i)
            ' 然后将用户ID,名称、密码、及操作布局添加到表中
            表格1.添加一行(用户.id,用户.name,用户.pass,局_操作标签)
        结束循环
    })
结束 函数

' 将创建操作标签的代码单独封装成一个函数调用
函数 创建操作标签(索引)
    ' 创建表格中操作栏的 编辑|删除 标签
    变量 局_操作布局 = 创建 弹性布局()
    局_操作布局.定位 = ""
    变量 局_编辑标签 = 创建 标签()
    局_编辑标签.定位 = ""
    局_编辑标签.文本 = "编辑"
    局_编辑标签.文本颜色 = "#006cd7"
    局_编辑标签.光标样式 = "pointer"
    局_编辑标签.外边距右 = "10px"
    局_编辑标签.置被单击回调(()=>{
        ' 弹出提示("表项:" + 索引 + "编辑")
        ' 弹出自定义对话框弹窗,编辑内容
        编辑指定用户(索引)
    })
    变量 局_删除标签 = 创建 标签()
    局_删除标签.定位 = ""
    局_删除标签.文本 = "删除"
    局_删除标签.文本颜色 = "#ff0000"
    局_删除标签.光标样式 = "pointer"
    局_删除标签.置被单击回调(()=>{
        ' 根据索引取出表中当前行的数据,再根据列索引取出用户名
        变量 目标行 = 表格1.取一行(索引)
        调试输出(目标行)
        变量 待删除用户名 = 目标行[1]
        删除数据表用户(待删除用户名)
    })
    ' 将编辑、删除标签添加到操作布局中
    局_操作布局.添加组件(局_编辑标签)
    局_操作布局.添加组件(局_删除标签)
    ' 返回整个操作布局
    返回 局_操作布局
结束 函数

函数 删除数据表用户(用户名)
    如果(确认框("确定要删除“" + 用户名 + "”吗?") == 真)
        ' 发送删除请求
        请求接口("Admin","删除用户",(请求结果,标记)=>{
            如果(请求结果 == "")
                信息框("发送删除请求失败")
                返回
            结束 如果
            变量 jsonObj = JSON解析(请求结果)
            弹出提示(jsonObj.msg)
            如果(jsonObj.code == 100)
                ' 刷新数据表、查询所有数据
                查询所有用户数据()
            结束 如果
        },"name=" + 用户名)
    结束 如果
结束 函数

函数 编辑指定用户(索引)
    变量 行数据 = 表格1.取一行(索引)
    单行输入框2.内容 = 行数据[1]
    单行输入框3.内容 = 行数据[2]
    ' 注册面板中的按钮事件
    按钮_修改.置被单击回调(()=>{
        变量 待提交数据 = "id=" + 行数据[0] + "&name=" + 单行输入框2.内容 + "&pass=" + 单行输入框3.内容
        '调试输出(待提交数据)
        请求接口("Admin","编辑用户",(请求结果,标记)=>{
            变量 jRes = JSON解析(请求结果)
            弹出提示(jRes.msg)
            ' 根据后端返回的状态码,判断是否修改成功
            如果(jRes.code == 100)
                ' 刷新数据
                查询所有用户数据()
                ' 关闭弹窗
                程_编辑弹窗.关闭()
            结束 如果
        },待提交数据)
    })
    按钮_取消修改.置被单击回调(()=>{
        程_编辑弹窗.关闭()
    })
    程_编辑弹窗.显示()
结束 函数

管理页面对应的服务器脚本程序文件:Admin.sph

' ****************************************************************************
' 版权说明:Copyright(C) All Rights Reserved VcnStudio
' 程序版本:V1.0
' 文件描述:管理端接口文件、用于管理,查询、修改、删除表中的数据。
' 修改日志:
' ****************************************************************************
' 开启 Session 记录用户登录状态
启用会话凭证()

' 向客户端发送服务器的响应报头(Response Header)
置响应头("Content-Type: text/html; charset=utf-8")
置响应头("Content-Language: zh-CN")

' 引用轻语言封装的PHP核心库,注:如果要删除该引用请确保当前文件中未使用轻语言封装的函数
引用 "library/qing.core.php"

' 连接数据库,参数分别为:地址,数据库名称,数据库账号,数据库密码;注意:连接数据库操作必须放在引用核心库之后
MySQL连接("localhost","test","root","root")

' 调用主函数:“文件被访问”、即当在任何前端中访问该文件时,地址中不带任何参数名,都将会先调用该函数
文件被访问()

' 入口函数,函数名可自定义命名,主要作用:
' 当本文件被访问时,获取其前端传来的请求参数值,根据请求参数值调用当前文件中的函数
函数 文件被访问()
    ' 通过URL中的键参获取要执行的函数,这里我们默认规定键名为“a”,例如:
    ' 前端请求地址为:http://xxx.com/本文件名.php?a=测试输出
    ' 其“a”后面的值“测试输出”即为我们要执行的函数,使用“取请求值”函数将其取出后,然后执行。
    变量 待执行函数名 = 取请求值("a")
    如果(为空(待执行函数名))
        输出 "待执行函数不能为空"
    否则
        输出 执行函数(待执行函数名)
    结束 如果
结束 函数

函数 查询所有用户()
    ' 查询表中所有用户数据,返回给前端
    变量 查询结果 = MySQL查询("select * from mytable",[])
    如果(为空(查询结果))
        返回 格式化内容(1,"数据查询失败")
    结束 如果
    ' 查询结果不为空、则将查询结果格式化为JSON数据格式值返回给前端
    返回 格式化内容(0,查询结果)
结束 函数

函数 查询指定用户()
    变量 name = 取请求值("name")
    如果(为空(name))
        返回 格式化内容(1,"待查询用户名不能为空")
    结束 如果
    变量 查询结果 = MySQL查询("select * from mytable where name=?",[name])
    如果(为空(查询结果))
        返回 格式化内容(1,"未查询到用户名为:" + name + " 的用户")
    结束 如果
    返回 格式化内容(0,查询结果)
结束 函数

函数 模糊查询指定用户()
    变量 name = 取请求值("name")
    如果(为空(name))
        返回 格式化内容(1,"待查询用户名不能为空")
    结束 如果
    ' 模糊查询核心改动:
    ' name = ? 修改为 like ?
    ' 且待查询的关键字两边必须加上 % %
    变量 待查询账号 = "%" + name + "%"
    变量 查询结果 = MySQL查询("select * from mytable where name like ?",[待查询账号])
    如果(为空(查询结果))
        返回 格式化内容(1,"未查询到用户名为:" + name + " 的用户")
    结束 如果
    返回 格式化内容(0,查询结果)
结束 函数

函数 删除用户()
    ' 根据前端传来的条件值删除用户,这里我们仍然根据用户名进行删除
    变量 name = 取请求值("name")
    如果(为空(name))
        返回 格式化内容(1,"待删除用户名不能为空")
    结束 如果
    变量 SQL命令 = "delete from mytable where name = ?"
    如果(MySQL执行(SQL命令,[name]))
        返回 格式化内容(100,"用户删除成功")
    否则
        返回 格式化内容(1,"用户删除失败")
    结束 如果
结束 函数

函数 编辑用户()
    变量 id = 取请求值("id")
    变量 name = 取请求值("name")
    变量 pass = 取请求值("pass")
    如果(为空(id) 或 为空(name) 或 为空(pass))
        返回 格式化内容(1,"待修改内容不能为空数据")
    结束 如果
    变量 SQL命令 = "update mytable set name=?,pass=? where id=?"
    如果(MySQL执行(SQL命令,[name,pass,id]))
        返回 格式化内容(100,"用户数据修改成功")
    否则
        返回 格式化内容(1,"用户数据修改失败")
    结束 如果
结束 函数

学习要点

通过本综合演示,你可以学习到以下轻语言全栈开发技术:

知识点代码位置说明
MySQL连接初始化MySQL连接("localhost","test","root","root").sph 文件中初始化数据库连接,必须放在 引用 "library/qing.core.php" 之后
PDO 参数化查询MySQL执行(SQL命令,[userName,passWord])使用 ? 占位符 + 数组传参,从根本上防止 SQL 注入
模糊查询"select * from mytable where name like ?"SQL 中将 = 改为 like,并在参数两侧拼接 % 实现模糊搜索
会话凭证管理启用会话凭证置会话凭证取会话凭证销毁会话凭证通过 Session 实现"登录状态"在前后端之间的传递与保持
接口函数白名单可被执行的函数列表 = [ "注册账号", "登录账号" , ...]防止前端通过 URL 任意调用任意函数,提升 API 安全性
前端请求接口请求接口("User","注册账号",回调,待提交数据)前端通过接口名调用后端函数,由框架自动转换为 HTTP 请求并解析响应
JSON 数据交换格式化内容(状态码,数据)JSON解析(请求结果)后端统一返回 {code,msg} 结构,前端解析后按 code 分支处理
动态表格渲染表格1.添加一行(用户.id,用户.name,用户.pass,局_操作标签)在循环中将每行数据 + 操作按钮布局一同塞入表格
自定义组件创建创建 弹性布局创建 标签置被单击回调在普通函数中动态创建组件并绑定事件回调
对话框弹窗创建 对话框置视图(弹性布局1)显示关闭将布局作为对话框内容视图,实现自定义编辑面板

安全最佳实践

本演示遵循了以下安全开发规范,请在实际项目中同样遵守:

  1. 永远不要在前端代码中直连数据库:网页右键查看源代码会暴露数据库账号密码。所有数据库操作必须通过后端 .sph 接口完成。
  2. 永远使用 PDO 参数化查询:禁止使用字符串拼接构造 SQL,必须使用 ? 占位符 + 数组传参的形式(如 MySQL执行(SQL命令,[name,pass]))。
  3. API 函数白名单:在 文件被访问 入口函数中限制可调用的函数名,拒绝前端传入未定义的函数名。
  4. 空值校验:在接口函数开头使用 为空() 检测必填字段,返回明确的错误信息。
  5. 唯一性校验:注册前使用 MySQL查找 检测账号是否已存在,避免重复注册。
  6. 会话过期处理:使用 销毁会话凭证() 实现安全退出,避免长期持有失效登录态。

扩展方向

你可以基于本演示继续扩展以下功能:

  • 密码加密:使用 md5() 或更安全的 password_hash()(PHP 原生函数)对密码进行加密存储
  • 权限分级:在 mytable 表中新增 role 字段,区分普通用户和管理员,在 .sph 中根据 role 限制可调用的接口
  • 分页查询:使用 SQL 的 LIMIT 子句实现分页,前端通过表格的"上一页 / 下一页"按钮请求不同页
  • 数据导出:将查询结果通过 JSON编码 或 CSV 格式导出,提供"下载用户列表"功能
  • 登录验证码:集成第三方滑动验证码或图形验证码,防止暴力破解
  • 操作日志:在每次 CRUD 操作时,将操作人、操作时间、操作内容写入 log 表,实现审计

💡 相关文档:本演示中使用的 MySQL 操作函数(MySQL连接MySQL查询MySQL执行 等)详细参数说明请参考文档服务端(PHP)函数_MYSQL操作;前端 请求接口 函数用法请参考文档轻语言网站:发送网络请求与接口请求.sph 接口文件结构请参考文档轻语言网站:服务端脚本程序API接口;界面 XML 标签和属性定义请参考文档轻语言网站:界面XML定义规范