本文目录导读:

在PHP项目中实现电子合同功能,通常需要结合前端签名、后端逻辑、存储与存证几个环节,以下是完整的实现思路和关键步骤:
功能需求分析
一个基本的电子合同系统需要:
- 合同模板管理:生成固定格式(如PDF)的合同
- 在线签署:支持手写签名、印章或确认勾选
- 签署验证:时间戳、哈希校验、第三方存证(可选)
- 合同存储:PDF/DOC文件储存并绑定签署记录
- 司法认可:符合《电子签名法》要求(可靠电子签名)
技术选型建议
| 模块 | 推荐技术/库 |
|---|---|
| PDF处理 | TCPDF / FPDI(免费)、PDFlib(付费) |
| 手写签名 | Signature Pad(前端JS库) |
| 电子印章 | Seal SVG / 后端生成印章图片 |
| 文件存储 | 阿里云OSS / 腾讯COS / 本地文件系统 |
| 时间戳 | 对接国家授时中心API或第三方时间戳服务 |
| 签署验证 | 计算文件SHA-256 / 对接第三方存证平台(如法大大、e签宝) |
| 前后端通信 | RESTful API + JWT认证 |
核心实现流程
1 合同创建与模板
// 使用TCPDF生成PDF合同
require_once('tcpdf/tcpdf.php');
$pdf = new TCPDF();
$pdf->AddPage();
$html = '<h1>租赁合同</h1><p>甲方:'.$partyA.',乙方:'.$partyB.'</p>';
$pdf->writeHTML($html);
$pdf->Output('contract_draft.pdf', 'F');
2 签署流程(前端)
<!-- 使用Signature Pad -->
<canvas id="signaturePad"></canvas>
<button onclick="saveSignature()">确认签署</button>
<script src="signature_pad.min.js"></script>
<script>
const canvas = document.getElementById('signaturePad');
const pad = new SignaturePad(canvas);
function saveSignature() {
const dataUrl = pad.toDataURL(); // 获取base64签名数据
fetch('save_signature.php', {
method: 'POST',
body: JSON.stringify({ signature: dataUrl, contractId: 123 })
});
}
</script>
3 后端签名处理与PDF合成
// save_signature.php
$data = json_decode(file_get_contents('php://input'), true);
$base64 = $data['signature'];
$contractId = $data['contractId'];
// 1. 保存签名图片
$img = base64_decode(explode(',', $base64)[1]);
file_put_contents("signatures/{$contractId}.png", $img);
// 2. 叠加签名到PDF(使用FPDI)
$pdf = new \setasign\Fpdi\Fpdi();
$pageCount = $pdf->setSourceFile("contracts/draft_{$contractId}.pdf");
for ($i=1; $i<=$pageCount; $i++) {
$tplIdx = $pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($tplIdx);
}
// 在最后一页添加签名图片
$pdf->Image("signatures/{$contractId}.png", 100, 200, 40, 20);
$pdf->Output("contracts/final_{$contractId}.pdf", 'F');
// 3. 写入签署记录
$db->insert('sign_log', [
'contract_id' => $contractId,
'signer' => $_SESSION['user_id'],
'sign_time' => date('Y-m-d H:i:s'),
'file_hash' => hash_file('sha256', "contracts/final_{$contractId}.pdf")
]);
增强司法效力(可选但推荐)
1 数字证书签名(使用开放X.509)
# 安装phpseclib composer require phpseclib/phpseclib
use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\PublicKeyLoader;
$privateKey = file_get_contents('path/to/private.pem');
$rsa = PublicKeyLoader::load($privateKey);
$pdfContent = file_get_contents('contract.pdf');
$signature = $rsa->sign($pdfContent);
file_put_contents('contract_signed.pdf', $pdfContent . "\n" . base64_encode($signature));
2 对接第三方CA(简化版)
- e签宝 / 法大大 / 契约锁:提供完整API,PHP SDK示例
// 以e签宝为例(伪代码) $tsingClient = new TsingClient($appId, $appSecret); $response = $tsingClient->createSignFlow([ 'docs' => ['templateId' => 'xxx'], 'signers' => [ ['name' => '张三', 'mobile' => '138xxxx'] ] ]);
3 法院认可的存证(区块链/哈希上链)
- 将最终PDF的SHA-256值提交到区块链存证平台(如蚂蚁链、百度超级链)
- 或使用时间戳服务(中国金融认证中心CFCA)
完整项目目录结构建议
project/
├── public/
│ ├── index.php // 合同列表
│ └── sign.php // 签署页面(含Signature Pad)
├── src/
│ ├── Controller/
│ │ └── ContractController.php
│ ├── Service/
│ │ ├── PdfService.php
│ │ └── SignService.php
│ └── Model/
│ └── Contract.php
├── templates/
│ └── contract_template.html // 合同模板
├── storage/
│ ├── drafts/ // 未签署合同
│ ├── signed/ // 已签署合同
│ └── signatures/ // 签名图片
└── vendor/ // Composer依赖
注意事项(避坑指南)
- 签名与合同内容的绑定:必须将签名图片嵌入PDF,而非单独存储,防止篡改。
- 用户身份认证:签署前强制完成实名认证(身份证/银行卡四要素/人脸识别)。
- 不可篡改性:最终PDF计算SHA-256并保存到数据库,定期比对。
- 法律风险:若需求严格司法效力,建议直接集成第三方电子签约平台(成本低、合规性高)。
- 前端签名兼容性:所有主流浏览器均支持Canvas,但移动端建议使用touch事件替代鼠标事件。
第三方集成方案(简化开发)
| 服务商 | PHP SDK | 特点 |
|---|---|---|
| 法大大 | 成熟 | 支持合同模板、自动签署 |
| e签宝 | 完善 | 支持小程序、H5签署 |
| 契约锁 | 企业级 | 本地化部署可选 |
如果预算有限且非强司法场景,用 TCPDF + Signature Pad + SHA-256 完全够用;如果需要法律认可的完整电子签约,推荐直接使用 e签宝 / 法大大 等成熟服务,PHP集成也只需调用几个HTTP接口。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播