eloquent 中如何动态建立一个临时 connection 或者临时改变 charset?

前提条件

  1. Sql Server 数据库,table.column1 存储了 gbk 编码的经过位移操作后的数据。数据有中文,英文,数字,中英数混合等,字段类型为 char 。
  2. 前提1中的数据库表属性不能变动,位移操作可能是当时做为加密用的。
  3. eloquent 连接属性 charset=utf8 。

产生的问题

使用 utf8 读取 table.column1 数据会转换为 utf8 字符串,无法使用算法转回正常字符,如果使用 iconv 转回 GBK ,由于原存储数据是经过位移后的二进制数据,不是标准 GBK,转换后会丢失很多字符。

尝试的解决方法

  • 使用 DB::connection()->getConfig() 获取数据库配置信息,修改 charset=gbk 然后使用 new \Illuminate\Database\Connectors\ConnectionFactory() 新建一个 connection 专用于这个表的查询,但是不知道 ConnectionFactory() 需要的参数 container 怎么获取。
  • 查阅 php 文档使用原生 PDO 的
    PDOStatement::setAttribute , PDO::prepare , PDOStatement::bindColumn , PDOStatement::bindParam
    方法时,附加参数 PDO::SQLSRV_ENCODING_BINARY 可以忽略字符串编码使用二进制读写数据。简单搜索了 eloquent 源码,似乎并没有设定参数的实现,做为最后方案备用。

请教

  1. 如何不提前设定数据库配置,建立一个临时的 connection ,或者临时更改 connection 的 charset 设置。
  2. eloquent 中是否有方法读取某列数据时,能忽略字符编码,读取char类型中原始编码数据。

谢谢。

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 2

说说我的方法,首先我的需求是动态修改数据库连接,并没有更改过 charset
第一种方法:新建个 PDO 然后用 DB::setPdo($pdo), 下面就正常查询就好了。
第二种方法:因为 laravel 启动的时候,将 config/database.php 文件读入 config 变量中了,因此用

config('database.connections.mysql.host' => 'xxx.xxx.xxx.xxx')

然后下面正常查询。
(我两种方法都用过,都成功了 [5.1. | 5.5.] 版本)

4年前 评论
rockft (楼主) 4年前

今天有时间又试着解决了一下这个问题,发现我需要的不是临时改变 connection ,而且查询时指定的列使用二进制查询忽略字符编码,所以 sql server 中查询时用 cast 将列转为 binary 类型就可以了。

table1::on($this->connection)->get(DB::RAW('cast(column1 as binary(32)) as column1'));

完美解决。

有时间再试一下动态改变 connection 。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!