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

基于CodeIgniter/PHP实现跨网络IP打印机打印任务的技术求助

跨公网PHP+CodeIgniter打印到指定IP打印机解决方案

核心前提确认

  • 目标打印机必须拥有公网可访问的IP地址,且默认打印端口9100已在路由器/防火墙处完成端口映射,确保公网能连通该端口
  • 若打印机仅处于局域网内,必须在其所在网络部署中转代理,否则公网服务无法直接访问

优化版Socket打印方案(适配CodeIgniter)

之前的Socket代码存在未处理二进制打印数据、错误捕获不完善的问题,以下是封装成CodeIgniter库的优化版本:

1. 创建CodeIgniter打印库(application/libraries/Printer.php)

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Printer {
    private $socket;
    private $printer_ip;
    private $port = 9100;

    public function __construct($printer_ip) {
        $this->printer_ip = $printer_ip;
        $this->create_socket();
    }

    private function create_socket() {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!$this->socket) {
            throw new Exception("Socket创建失败: " . socket_strerror(socket_last_error()));
        }
    }

    public function print_data($print_content) {
        $connection = socket_connect($this->socket, $this->printer_ip, $this->port);
        if (!$connection) {
            throw new Exception("连接打印机失败: " . socket_strerror(socket_last_error($this->socket)));
        }

        $bytes_written = socket_write($this->socket, $print_content, strlen($print_content));
        if ($bytes_written === false) {
            throw new Exception("发送数据失败: " . socket_strerror(socket_last_error($this->socket)));
        }

        usleep(500000);
        $this->close_socket();
        return true;
    }

    private function close_socket() {
        if ($this->socket) {
            socket_close($this->socket);
        }
    }

    public function print_file($file_path) {
        if (!file_exists($file_path)) {
            throw new Exception("文件不存在");
        }
        $file_content = file_get_contents($file_path);
        return $this->print_data($file_content);
    }
}

2. 在控制器中调用

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Print_controller extends CI_Controller {
    public function index() {
        $this->load->library('printer', array('printer_ip' => 'xxx.xxx.xxx.xxx')); // 替换为打印机公网IP

        try {
            // 示例:热敏打印机ESC/POS指令
            $print_content = "\x1B\x40"; // 初始化打印机
            $print_content .= "测试打印内容\n";
            $print_content .= "\x1B\x64\x02"; // 走纸2行
            $print_content .= "\x1D\x56\x41\x00"; // 切纸

            $this->printer->print_data($print_content);
            echo "打印任务提交成功";
        } catch (Exception $e) {
            echo "错误: " . $e->getMessage();
        }
    }
}

基于IPP协议的打印方案

若打印机支持Internet Printing Protocol(IPP),可使用PHP的IPP客户端实现,无需直接操作Socket:

1. 安装IPP客户端库(Composer)

在CodeIgniter项目根目录执行:

composer require xerias/ipp

2. 控制器调用示例

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

require_once APPPATH . '../vendor/autoload.php';

class Ipp_print extends CI_Controller {
    public function index() {
        $printer_ip = 'xxx.xxx.xxx.xxx';
        $ipp_client = new \Xerias\Ipp\IppClient($printer_ip, 631); // IPP默认端口631

        $job = new \Xerias\Ipp\Job();
        $job->setJobName('PHP打印任务');
        $job->addDocument(file_get_contents('path/to/your/file.pdf'), 'application/pdf');

        try {
            $response = $ipp_client->printJob($job);
            if ($response->getStatusCode() == 0x0000) {
                echo "打印任务提交成功";
            } else {
                echo "提交失败: " . $response->getStatusMessage();
            }
        } catch (\Exception $e) {
            echo "错误: " . $e->getMessage();
        }
    }
}

中转代理方案(打印机无公网IP时)

若打印机仅在局域网内,需在其所在网络部署中转服务:

1. 局域网内部署PHP中转脚本

<?php
// proxy_printer.php
$printer_ip = '192.168.1.100'; // 局域网内打印机IP
$port = 9100;

$print_content = file_get_contents('php://input');

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $printer_ip, $port);

if ($result) {
    socket_write($socket, $print_content, strlen($print_content));
    socket_close($socket);
    echo "转发成功";
} else {
    echo "转发失败";
}

2. 公网CodeIgniter端调用中转脚本

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Proxy_print extends CI_Controller {
    public function index() {
        $proxy_url = 'http://xxx.xxx.xxx.xxx/proxy_printer.php'; // 中转脚本公网地址
        $print_content = "测试打印内容";

        $this->load->library('curl');
        $response = $this->curl->simple_post($proxy_url, $print_content, array('Content-Type: application/octet-stream'));

        echo $response;
    }
}

关键注意事项

  • 打印内容必须匹配打印机支持的格式:热敏打印机用ESC/POS指令,激光打印机用PCL/PS/PDF格式
  • Socket方案需确保服务器PHP已启用sockets扩展(在php.ini中开启extension=sockets)
  • 公网访问打印机时,需限制访问IP或使用VPN/加密传输,避免安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:27:06