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属性,这里给你一个简化的解析思路:
- 跳过响应头部的固定字节(前8字节:2字节状态码 + 2字节版本号 + 4字节操作ID)
- 遍历后续的属性组,找到属性名为
printer-state-reasons的条目(属性ID为0x2b) - 解析该属性的取值,它是一个集合类型,会包含
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
相关产品推荐
相关产品推荐

