最近、WeChat 決済に接続する場合、返金ポイントで証明書を使用する必要があります。当社は SAAS プラットフォームであるため、マルチパーティおよびマルチチャネル支払いをサポートする必要があります。すべての証明書ファイルをアプリケーション サーバーに保存すると、SLB の影響を受け、特定のマシン上のファイルが同期されなくなり、払い戻しプロセスが妨げられます。ただし、ファイルが OSS に保存されている場合、バックエンドは OSS からファイルをダウンロードする必要があります。アプリケーション サーバーで一貫性を確保します。熟慮の末、最終的に証明書の内容をデータベースに保存することにしました。異なる顧客が 1 つの証明書ファイルに対応します。クラスター内で使用されるマシンの数に関係なく、ファイルの一貫性が確保され、冗長なダウンロード手順を回避できます。 。
しかし、作成直後に問題が発生しました。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
公式ドキュメントを読んで理由が分かりました。 返されたハンドル参照カウントは 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.
$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 文字列証明書の転送をどのようにサポートしていますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。