前言
泛微OA使用的Laravel
这是其对接数据库的文档
https://laravelacademy.org/post/22012
位置
项目位置
D:e-office_server_11.0www
外部脚本位置
D:e-office_server_11.0wwweofficeserverext
假如我的模块的位置
D:e-office_server_11.0wwweofficeserverextrukuadd_product.php
则访问的地址为
http://60.205.244.163:8010/eoffice/server/ext/ruku/add_product.php
外发地址可以配置为
/eoffice/server/ext/ruku/add_product.php
测试
add_product.php
代码语言:javascript复制<?php
phpinfo();
?>
日志
代码语言:javascript复制// 生成日志文件存放目录的路径,示例: D:e-office_server_11.0wwweoffice10serverstoragelogs
$logDir = base_path('/storage/') . 'logs/';
if(empty($data)) {
// 没有获取到外发数据,在日志 D:e-office_server_11.0wwweoffice10serverstoragelogsruku_log.txt 里记录出错信息
file_put_contents($logDir."ruku_log.txt","数据错误,外发失败。",FILE_APPEND);
exit();
}
打印请求参数到日志
为了方便我们知道参数,我们在log中打印所有的参数
代码语言:javascript复制<?php
require __DIR__ . '/../../bootstrap/app.php';
// 默认用法,引入数据库接口
use IlluminateSupportFacadesDB;
header("Content-Type:text/html;charset=gb2312");
// 通过 $_REQUEST 的方式,获取所有被发送到这个页面的数据。
$data = (isset($_REQUEST) && !empty($_REQUEST)) ? $_REQUEST : [];
$logDir = base_path('/storage/') . 'logs/';
file_put_contents($logDir."ruku_paras_log.txt",json_encode($data));
echo "参数保存成功";
?>
注意
设置请求头编码为utf8,并且转换一下输出的编码。 文件本身编码不要修改为utf8。
输出中文乱码
注意以下两种方式都可以,但是切记不要修改文件本身编码为UTF-8。
代码语言:javascript复制header("Content-Type:text/html;charset=utf8");
echo iconv("GB2312","UTF-8","参数保存成功");
或者
代码语言:javascript复制header("Content-Type:text/html;charset=gb2312");
echo "参数保存成功";
可取参数
JSON解析
流程中的无论表单提交,还是后续节点,外发的时候数据都会包含表单的所有值。
代码语言:javascript复制{
"data_id": "9",
"creator": "admin",
"DATA_6": "6",
"DATA_6_TEXT": "管城区市政基础能力提升工程项目-A包",
"DATA_1": "5",
"DATA_1_TEXT": "方圆项目",
"DATA_3": {
"data_id": [
"11",
"12"
],
"id": [
"11",
"12"
],
"form_data_id": [
"9",
"9"
],
"parent_data_id": [
"9",
"9"
],
"DATA_4": [
"4",
"5"
],
"DATA_4_TEXT": [
"金士顿U盘-128G",
"金士顿U盘-256G"
],
"DATA_5": [
"",
""
],
"DATA_7": [
"10",
"20"
],
"DATA_8": [
"10",
"20"
],
"DATA_9": [
"",
""
]
},
"flow_id": "100",
"run_id": "511",
"form_id": "570",
"outsend_id": "214",
"run_name": "入库单",
"node_id": "387",
"process_name": "发起人",
"userInfo": {
"user_id": "admin",
"user_name": "管理员",
"user_accounts": "admin",
"dept_name": "其他",
"dept_id": "62",
"role_name": "["OA\u7ba1\u7406\u5458","OA\u7ba1\u7406\u5458\u6d41\u7a0b\u8bbe\u7f6e\u7279\u6743"]",
"role_id": "[1,68]"
}
}
其中
- run_id 流程id 对应的表是
flow_run
- node_id 流程当前节点
- form_id 表单ID 那么对应的表就是
form_data_570
子表是form_data_570_data_3
- data_id 表的主键ID
- DATA_6是下拉菜单,就会产生两个值 DATA_6和DATA_6_TEXT
- DATA_3是明细布局 会产生子表 明细的数据都会以数组呈现
子表form_data_570_data_3
的格式类似于
代码示例
代码语言:javascript复制<?php
require __DIR__ . '/../../bootstrap/app.php';
// 默认用法,引入数据库接口
use IlluminateSupportFacadesDB;
// 通过 $_REQUEST 的方式,获取所有被发送到这个页面的数据。
$data = (isset($_REQUEST) && !empty($_REQUEST)) ? $_REQUEST : [];
// 生成日志文件存放目录的路径,示例: D:e-office_server_11.0wwweoffice10serverstoragelogs
$logDir = base_path('/storage/') . 'logs/';
if(empty($data)) {
// 没有获取到外发数据,在日志 D:e-office_server_11.0wwweoffice10serverstoragelogsruku_log.txt 里记录出错信息
file_put_contents($logDir."ruku_log.txt","数据错误,外发失败。",FILE_APPEND);
exit();
}
// 获取外发数据示例:
// 流程id
$run_id = isset($data["run_id"]) ? $data["run_id"] : "";
// 流程当前节点
$node_id = isset($data["node_id"]) ? $data["node_id"] : "";
?>
SQL操作
代码语言:javascript复制<?php
require __DIR__ . '/../../bootstrap/app.php';
use IlluminateSupportFacadesDB;
header('Content-type: application/json');
$list = DB::table('log_customer')->limit(10)->get();
echo json_encode($list);
?>
SQL基本查询
运行 Select 查询
运行一个最基本的查询,可以使用 DB
门面的 select
方法:
$users = DB::select('select * from users where active = ?', [1]);
除了使用 ?
占位符来代表参数绑定外,还可以使用命名绑定来执行查询:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
运行插入语句
使用 DB
门面的 insert
方法执行插入语句。和 select
一样,该方法将原生 SQL 语句作为第一个参数,将参数绑定作为第二个参数:
DB::insert('insert into users (id, name) values (?, ?)', [1, '学院君']);
运行更新语句
update
方法用于更新数据库中已存在的记录,该方法返回受更新语句影响的行数:
$affected = DB::update('update users set votes = 100 where name = ?', ['学院君']);
运行删除语句
delete
方法用于删除数据库中已存在的记录,和 update
一样,该语句返回被删除的行数:
$deleted = DB::delete('delete from users');
使用
delete
和update
语句时,需要非常小心,因为条件设置不慎,导致的后果有可能是无法挽回的,比如不带条件的delete
语句删除的将是数据表的所有记录!这些都是有血淋淋的教训的。
运行一个通用语句
有些数据库语句不返回任何值,比如新增表,修改表,删除表等,对于这种类型的操作,可以使用 DB
门面的 statement
方法:
DB::statement('drop table users');
SQL查询构建器
单条数据
代码语言:javascript复制$user = DB::table('users')->where('name', '学院君')->first();
echo $user->name;
查询列表
代码语言:javascript复制$users = DB::table('users')->select('name', 'email as user_email')->get();
distinct
方法允许你强制查询返回不重复的结果集:
$users = DB::table('users')->distinct()->get();
原生表达式
有时候你希望在查询中使用原生表达式,这些表达式将会以字符串的形式注入到查询中,所以要格外小心避免 SQL 注入。想要创建一个原生表达式,可以使用 DB::raw
方法:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
左连接/右连接
代码语言:javascript复制$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
$users = DB::table('users')
->rightJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
Where 子句
whereBetween/orWhereBetween
whereBetween
方法验证列值是否在给定值之间:
$users = DB::table('users')
->whereBetween('votes', [1, 100])
->get();
whereNotBetween/orWhereNotBetween
whereNotBetween
方法验证列值不在给定值之间:
$users = DB::table('users')
->whereNotBetween('votes', [1, 100])
->get();
whereIn/whereNotIn/orWhereIn/orWhereNotIn
whereIn
方法验证给定列的值是否在给定数组中:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
whereNotIn
方法验证给定列的值不在给定数组中:
$users = DB::table('users')
->whereNotIn('id', [1, 2, 3])
->get();
注:如果要添加非常大的整型数组绑定到查询,可以使用
whereIntegerInRaw
或whereIntegerNotInRaw
方法来降低内存开销。
whereNull/whereNotNull/orWhereNull/orWhereNotNull
whereNull
方法验证给定列的值为 NULL
:
$users = DB::table('users')
->whereNull('updated_at')
->get();
whereNotNull
方法验证给定列的值不是 NULL
:
$users = DB::table('users')
->whereNotNull('updated_at')
->get();
whereDate/whereMonth/whereDay/whereYear/whereTime
whereDate
方法用于比较字段值和日期:
$users = DB::table('users')
->whereDate('created_at', '2019-12-31')
->get();
whereMonth
方法用于比较字段值和一年中的指定月份:
$users = DB::table('users')
->whereMonth('created_at', '12')
->get();
whereDay
方法用于比较字段值和一月中的指定日期:
$users = DB::table('users')
->whereDay('created_at', '31')
->get();
whereYear
方法用于比较字段值和指定年:
$users = DB::table('users')
->whereYear('created_at', '2019')
->get();
whereTime
方法用于比较字段值和指定时间:
$users = DB::table('users')
->whereTime('created_at', '=', '11:20:45')
->get();
whereColumn/orWhereColumn
whereColumn
方法用于验证两个字段是否相等:
$users = DB::table('users')
->whereColumn('first_name', 'last_name')
->get();
还可以传递一个比较运算符到该方法:
代码语言:javascript复制$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
还可以传递多条件数组到 whereColumn
方法,这些条件通过 and
操作符进行连接:
$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at']
])->get();
插入(Insert)
查询构建器还提供了 insert
方法用于插入记录到数据表。insert
方法接收数组形式的字段名和字段值进行插入操作:
DB::table('users')->insert(
['email' => 'john@example.com', 'votes' => 0]
);
你甚至可以一次性通过传入多个数组来插入多条记录,每个数组代表要插入数据表的记录:
代码语言:javascript复制DB::table('users')->insert([
['email' => 'taylor@example.com', 'votes' => 0],
['email' => 'dayle@example.com', 'votes' => 0]
]);
insertOrIgnore
方法会在插入记录到数据库时忽略重复记录错误:
DB::table('users')->insertOrIgnore([
['id' => 1, 'email' => 'taylor@example.com'],
['id' => 2, 'email' => 'dayle@example.com']
]);
自增 ID
如果数据表有自增 ID,使用 insertGetId
方法来插入记录并返回ID值:
$id = DB::table('users')->insertGetId(
['email' => 'john@example.com', 'votes' => 0]
);
注:当使用 PostgresSQL 时
insertGetId
方法默认自增列被命名为 id,如果你想要从其他“序列”获取ID,可以将序列名作为第二个参数传递到insertGetId
方法。
更新(Update)
当然,除了插入记录到数据库,查询构建器还可以通过使用 update
方法更新已有记录。update
方法和 insert
方法一样,接收字段名和字段值的键值对数组,对应字段名就是要更新的列,你可以通过 where
子句来对 update
查询进行约束:
DB::table('users')
->where('id', 1)
->update(['votes' => 1]);
更新或插入
有时候你可能想要更新数据库中已存在的某条记录,如果对应记录不存在的话,则插入这条记录。在这种场景下,可以使用 updateOrInsert
方法。
该方法接收两个参数:用于查询记录的条件数组和用于更新的列值对数组。
updateOrInsert
方法首先会尝试使用第一个参数的列值对匹配对应的数据库记录,如果记录存在,则通过第二个参数来更新它。如果记录不存在,则会合并这两个参数数组然后通过合并后的数组插入一条新纪录:
DB::table('users')
->updateOrInsert(
['email' => 'john@example.com', 'name' => 'John'],
['votes' => '2']
);
SQL技巧
null置0
代码语言:javascript复制select IFNULL((select DATA_5 from form_data_568_data_3 where data_id=10086 limit 1),0) as num;