PHP如何支持CURL字符串证书传输
背景
最近在对接微信支付的时候,需要在退款处用到证书,由于我们是SAAS平台,要支持多方多渠道支付,如果把所有证书文件保存在应用服务器会受到SLB的影响,会导致某台机器文件不同步而阻碍退款流程,但把文件存在OSS的话,后端又要从OSS下载到应用服务器来保证一致性。思来想去,最终决定将证书内容保存在数据库,不同客户各对应一份证书文件,无论几台机器做集群都能保证文件的一致性,同时也避免了多余的下载步骤。
问题
但是刚做就遇到了问题,PHP的CURL证书并不支持字符串的传输,只能填写证书路径(以下是官方的说法)
Client certificates must be specified by a path expression to a certificate store.
解决过程
我第一个想到的就是创建空白文件,将证书内容写进去,等证书使用完毕后再将文件删除,但是创建实体文件再删除的操作消耗性能不说,还非常麻烦,有没有创建临时文件的方法呢?有,tmpfile()
函数就可以帮我们创建临时文件并拿到文件路径,于是我写了一个获取临时文件路径的方法
<?php
public function getTmpPathByContent($content)
{
$tmpFile = tmpfile();
fwrite($tmpFile, $content);
$tempPemPath = stream_get_meta_data($tmpFile);
return $tempPemPath['uri']; ///tmp/phpXZCtAO
}
?>
比较悲哀的是,通过这个方法返回的路径根本读不到内容,甚至一度以为是不是被骗了
file_get_contents(/tmp/phpyyiOZv): failed to open stream: No such file or directory
看了官方文档才找到原因,如果tmpfile()
返回的句柄引用计数为0的话就会将临时文件回收,临时路径自然也就失效了,显然方法getTmpPathByContent()
执行完后,局部变量$tmpFile
的生命周期就结束了(官方文档如下)
The file is automatically removed when closed (for example, by calling fclose(), or when there are no remaining references to the file handle returned by tmpfile()), or when the script ends.
确认了根源,那我们现在亟需找到一个生命周期随进程结束而终止的变量类型来保存句柄,什么类型能满足条件呢?静态变量。静态变量与局部变量不同的是,在PHP生命周期开始时便会为其分配内存空间,并会把它存储在全局变量区域,而全局变量是在模块关闭阶段销毁的,这样的话,声明静态变量就可以使$tmpFile
引用计数持续保持大于0的状态,那我们的代码就可以做出如下处理
<?php
public function getTmpPathByContent($content)
{
static $tmpFile = null;
$tmpFile = tmpfile();
fwrite($tmpFile, $content);
$tempPemPath = stream_get_meta_data($tmpFile);
return $tempPemPath['uri'];
}
?>
再执行一次就成功读取了临时文件的内容
-----BEGIN CERTIFICATE-----
MIIEbDCCA9WgAwIBAgIEAWJKHDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
Q04xEjAQBgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNV
BAoTB1RlbmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEf
MB0GCSqGSIb3DQEJARYQbW1wYXltY2hAdGVuY2VudDAeFw0xNzA4MDcwOTIxNDda
Fw0yNzA4MDUwOTIxNDdaMIGbMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdk
b25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVuY2VudDEOMAwGA1UE
CxMFTU1QYXkxMDAuBgNVBAMUJ+a3seWcs+W4guaYjua6kOi9r+S7tuiCoeS7veac
iemZkOWFrOWPuDERMA8GA1UEBBMIMTAyNTkyODEwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDg2D3++uOxY/yMGQPBnROvyYimnCsfGE0dnqdGUTCykqBh
yfv82zE1/St/4DQX2QDiIvLif+sMGcYwF4bkzdY+HgitYLI0k5o/5LCNZOMctuio
kdYC2bNdWHq2y9S5UWLQR1Zvq+6QyPBVBVY9yq9xtQhIlUTsZnICAp3iQLfQUR3l
aEdH9IERoRUIkbyb8oX5ONQz4P9jOeE9C5iwx0QrH4s01NFhkhr8JHlugRLpo9vA
xGgi/48fOlONj6wWal5Gt0OvvEbIwgQwya15KBX2YeGnZvYBQa+lQMeXEqZSFie3
G+wGvbtlONczQEtp+JDxLZLUS/FT7U0TQN/t8JDvAgMBAAGjggFGMIIBQjAJBgNV
HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh0iQ0VTLUNBIEdlbmVyYXRlIENlcnRpZmlj
YXRlIjAdBgNVHQ4EFgQUjDJ75bu3Roog7XOH6uFAdZ6kpcIwgb8GA1UdIwSBtzCB
tIAUPgUm9iJitBVbiM1kfrDUYqflhnShgZCkgY0wgYoxCzAJBgNVBAYTAkNOMRIw
EAYDVQQIEwlHdWFuZ2RvbmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQKEwdU
ZW5jZW50MQwwCgYDVQQLEwNXWEcxEzARBgNVBAMTCk1tcGF5bWNoQ0ExHzAdBgkq
hkiG9w0BCQEWEG1tcGF5bWNoQHRlbmNlbnSCCQC7VJcrvADoVzAOBgNVHQ8BAf8E
BAMCBsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEA
ucJLJkkHxlqQCEapZOWmySutqNVZxFbqyG//UXxxpA/1yG4e+KmufKZWv+c+MtYI
8i0KDDCv/UE+kkFIrHYDDKsdLRpxrYOUHGoqq0c7yBJ6Dimgy6m8U8FsEv3HtUR2
8g5xrg2Tc5MPWEp9ncEw575hGk0CXLDGOkI1nU+pGqk=
-----END CERTIFICATE-----
下面就可以把生成的临时文件地址设置到CURLOPT_SSLCERT
了
<?php
$sslCertPath = getTmpPathByContent($content);
curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
//......
?>
PHP如何支持CURL字符串证书传输的更多相关文章
- SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输
SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输 微软高兴地宣布所有主流SQL Server客户端驱动和SQL Server发行版已经支持T ...
- 基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串、list集合(MVC5)<二>
上篇博客给大家介绍了基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串.list集合(MVC5)<一>, 其中的两种方式都显得有些冗余.接着上篇博客继续 ...
- 系统不支持curl
解决安装pinphp时出现的“系统不支持curl!” 今天在本机安装phppin开源程序时,提示“系统不支持curl!”错误. 由于我本机是UBUNTU系统,所以直接通过apt-get进行安装. ...
- atitit.二进制数据无损转字符串网络传输
atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
- ubuntu下PHP支持cURL
公司项目需要,注册需要验证手机号码,其中需要LAMP支持cURL.由于事先安装平台的时候,并没有注意到这一点,所以编译PHP5的时候,并没有使用参数--with-curl.后来需要的时候,查一些参考方 ...
- 将多维数组转换为支持curl提交的一维数组格式
/** * @desc 多维数组转化为支持curl提交数组 * @author lytian 2013-06-29 */ public function toPost(array $params = ...
- curl+个人证书(又叫客户端证书)访问https站点
摘自http://blog.csdn.net/chary8088/article/details/22990741 curl+个人证书(又叫客户端证书)访问https站点 目前,大公司的OA管理系统( ...
- SharePoint 2013 Workflow Manager 1.0 远程服务器返回错误: (400) 错误的请求。 不支持查询字符串中的 api-version
环境: Windows Server 2012 R2 Standard SharePoint Server 2013 with sp1 通过Web 平台安装程序 5.0,已安装 Workflow Ma ...
- WijmoJS 支持模板字符串常量
WijmoJS 支持模板字符串常量 在V2019.0 Update2 的全新版本中,WijmoJS 支持了模板字符串常量. 模板字符串是ES2015 / ES6中引入的一个非常棒的JavaScript ...
随机推荐
- 电子邮件和URL输入控件
HTML5还引入了让用户输入邮箱地址和URL的输入控件.那些不支持这类输入控件的浏览器会把他们当成普通文本框来处理. <!DOCTYPE html> <!-- To change t ...
- 【python图像处理】图像的缩放、旋转与翻转
[python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...
- linux 查看用户上次修改密码的日期【转】
1.找到以下文件: cat /etc/shadow 第三段字符就是最近一次密码修改的天数,此数字是距离1970年1月1日的天数. 2.用以下命令计算: date -u -d "1970- ...
- 整理一下odoo10在windows系统下部署的流程
odoo10环境搭建 所需依赖: Python3.5 odoo10.0 Node.js PostgreSQL 9.5 PyCharm 专业版 1.首先先安装好Python3.5,并设置好环境变量 2. ...
- freeradius 错误: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate
在进行802.1x 测试时遇到如下问题: Waking up in 4.6 seconds.(156) Received Access-Request Id 82 from 192.168.1.126 ...
- vmware下centos克隆功能对网络的设置
centos完成克隆功能后需要对网络进行设置 # cd /etc/udev/rules.d/ vim 70-persistent-net.rules 删除eth0的配置,将eth1该为eth0 编辑网 ...
- Android Studio 超级简单的打包生成apk
为什么要打包: apk文件就是一个包,打包就是要生成apk文件,有了apk别人才能安装使用.打包分debug版和release包,通常所说的打包指生成release版的apk,release版的apk ...
- bert 词典扩充方案
- Java 开发环境配置--eclipse工具进行java开发
Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java Cloud Studio ...
- javascript this详解(转)
在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了,用起来是非常方便和意义确定的.JavaScrip ...