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

PHP基于PrintIPP类如何获取IPP请求的原始响应字节?

如何获取PrintIPP类的原始响应字节并解析打印机状态

嘿,我刚好有过用PrintIPP类处理打印机状态查询的经历,针对你的问题,给你几个实用的解决方案:

1. 先检查PrintIPP类是否自带原始响应属性

很多IPP客户端类会把原始的HTTP响应字节直接存在某个公共或受保护的属性里,你可以先查看PrintIPP的源码或者类文档,找类似以下命名的属性:

  • $raw_response
  • $response
  • $_raw_response

如果找到的话,直接调用即可,比如:

$rawResponse = $ipp->raw_response;

2. 用PHP反射获取私有/保护的响应属性

如果PrintIPP把原始响应存在私有或保护变量里(比如$_response),可以用PHP的反射机制来读取:

// 初始化反射类
$reflection = new ReflectionClass($ipp);
// 获取存储响应的属性(根据实际类里的变量名调整)
$responseProp = $reflection->getProperty('_response');
// 允许访问私有/保护属性
$responseProp->setAccessible(true);
// 获取原始响应字节
$rawResponseBytes = $responseProp->getValue($ipp);

3. 自定义修改PrintIPP类,添加原始响应存储

如果上面两种方法都不行,你可以直接修改PrintIPP类的请求发送方法(比如sendRequest()或者内部的curl/fsockopen调用逻辑),把原始响应保存到一个公共属性里。举个例子,假设类里用curl发送请求:

// 在PrintIPP类的请求方法里,修改curl执行部分
$ch = curl_init($this->printer_url);
// ... 其他curl设置 ...
$rawResponse = curl_exec($ch);
// 添加一个公共属性存储原始响应
$this->raw_response = $rawResponse;
curl_close($ch);

解析原始响应中的打印机状态

拿到原始响应字节后,你需要按照IPP协议规范解析printer-state-reasons属性,这里给你一个简化的解析思路:

  1. 跳过响应头部的固定字节(前8字节:2字节状态码 + 2字节版本号 + 4字节操作ID)
  2. 遍历后续的属性组,找到属性名为printer-state-reasons的条目(属性ID为0x2b)
  3. 解析该属性的取值,它是一个集合类型,会包含paper-end、paper-near等状态标识

举个简单的代码片段(仅作参考,需根据实际响应调整):

// 跳过头部8字节
$offset = 8;
while ($offset < strlen($rawResponseBytes)) {
    // 读取属性类型和长度
    $attrType = ord($rawResponseBytes[$offset]);
    $attrLen = ord($rawResponseBytes[$offset+1]) << 8 | ord($rawResponseBytes[$offset+2]);
    $offset += 3;
    
    // 读取属性名
    $nameLen = ord($rawResponseBytes[$offset]) << 8 | ord($rawResponseBytes[$offset+1]);
    $name = substr($rawResponseBytes, $offset+2, $nameLen);
    $offset += 2 + $nameLen;
    
    // 检查是否是printer-state-reasons
    if ($name === 'printer-state-reasons') {
        // 读取属性值(集合类型)
        $valueLen = ord($rawResponseBytes[$offset]) << 8 | ord($rawResponseBytes[$offset+1]);
        $valueData = substr($rawResponseBytes, $offset+2, $valueLen);
        // 解析集合里的状态(IPP集合用null分隔)
        $stateReasons = explode("\x00", $valueData);
        // 检查是否包含目标状态
        if (in_array('paper-end', $stateReasons)) {
            echo "打印机缺纸";
        } elseif (in_array('paper-near', $stateReasons)) {
            echo "打印机低纸";
        }
        break;
    }
    
    // 跳过属性值
    $valueLen = ord($rawResponseBytes[$offset]) << 8 | ord($rawResponseBytes[$offset+1]);
    $offset += 2 + $valueLen;
}

注意:不同品牌的打印机对IPP协议的实现可能略有差异,解析时需要根据实际返回的响应字节调整逻辑。

内容的提问来源于stack exchange,提问作者SteMMo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:54:09