Laravel 10从SQL Server读取二进制数据转正常字符串问题
解决Laravel 10读取SQL Server binary(13)字段的异常问题
问题原因
SQL Server的binary(13)是固定长度二进制类型,存储时会用0x00补全至13字节。Laravel默认读取二进制字段时,会按字节流转换为字符串,但遇到0x00会触发截断(比如你的id字段对应的二进制可能在有效字符后出现0x00,导致仅返回7);而password字段因无提前截断,会保留后续补全的空字符。
解决方案
方案1:查询时显式转换字段
直接在查询中使用SQL Server的CONVERT函数转换为字符串,配合RTRIM剔除末尾的0x00空字符:
$user = DB::table('loginEx') ->selectRaw('CONVERT(varchar(13), id) AS id, RTRIM(CONVERT(varchar(13), password)) AS password') ->where(...) ->first();
此方式查询得到的id和password均为正常字符串,无截断或多余空字符。
方案2:模型访问器自动处理
若使用Eloquent模型,给LoginEx模型添加字段访问器,自动处理二进制字段转换:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class LoginEx extends Model { protected $table = 'loginEx'; // 处理id字段 public function getIdAttribute($value) { return rtrim(iconv('UTF-8', 'UTF-8//IGNORE', $value), "\0"); } // 处理password字段 public function getPasswordAttribute($value) { return rtrim(iconv('UTF-8', 'UTF-8//IGNORE', $value), "\0"); } }
之后直接查询模型即可获取处理后的正常字符串:
$user = LoginEx::find($id); echo $user->id; // 输出007kmy echo $user->password; // 输出x77kmy
方案3:修改数据库连接配置
在config/database.php的SQL Server连接配置中,添加编码与PDO选项,强制处理二进制字符串:
'sqlsrv' => [ 'driver' => 'sqlsrv', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', '1433'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, 'options' => [ PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8, PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => false, ], ],
修改后需清除配置缓存:
php artisan config:clear
此方式全局生效,若有其他需保留原始值的二进制字段,需谨慎使用。
内容的提问来源于stack exchange,提问作者blackhoLe
相关产品推荐
相关产品推荐

