You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP读取库存扫描器日文全角字符字段截取异常求助

解决方案:按字节截取原始数据流,再转码处理

问题核心是混淆了字节长度和字符长度:库存扫描器输出的是固定128字节的二进制流,而日文全角字符在不同编码下字节数不同(比如SJIS中是2字节,UTF-8中是3字节)。如果先转码再用mb_substr按字符截取,会破坏原始固定字节边界,导致后续字段错位。

正确流程是:先按字节截取原始二进制数据,再将截取后的字节串转换为目标编码。

步骤1:确认扫描器的输出编码

日文设备(如库存扫描器)常用编码为SJIS(Shift-JIS),优先查看设备手册确认;若无法获取手册,可通过mb_detect_encoding初步检测(注意:检测结果可能有误差,需验证):

$rawRecord = fread($handle, 128);
$detectedEncoding = mb_detect_encoding($rawRecord, ['SJIS', 'EUC-JP', 'UTF-8']);

步骤2:按字节截取字段(用substr而非mb_substr)

substr是PHP中按字节处理字符串的函数,完全匹配扫描器输出的固定字节结构。假设记录结构示例:

  • 商品名称:前30字节
  • 库存数量:接下来4字节
  • 其他字段:剩余字节

示例代码:

// 读取完整128字节原始记录
$rawRecord = fread($handle, 128);

// 按字节截取商品名称的原始字节串,再转码为UTF-8
$rawNameBytes = substr($rawRecord, 0, 30);
$productName = mb_convert_encoding($rawNameBytes, 'UTF-8', 'SJIS');

// 按字节截取库存数量(ASCII编码数字),去除填充空格
$rawStockBytes = substr($rawRecord, 30, 4);
$stockQuantity = trim($rawStockBytes);

// 后续字段按相同逻辑处理
$rawOtherField = substr($rawRecord, 34, 94);
$otherField = mb_convert_encoding($rawOtherField, 'UTF-8', 'SJIS');

关键注意事项

  • 禁止先对整个128字节记录转码再截取:转码后字节数会变化(如SJIS转UTF-8时,全角字符从2字节变3字节),直接破坏原始固定字节结构。
  • 若字段含全角空格,转码后可用mb_trim处理(需指定编码):
    $productName = mb_trim($productName, 'UTF-8');
    
  • 若检测编码与实际不符会出现乱码,此时必须优先确认设备官方编码说明。

内容的提问来源于stack exchange,提问作者K a r L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:37:27