Maison  >  Article  >  développement back-end  >  Comment PHP prend-il en charge le transfert de certificat de chaîne CURL ?

Comment PHP prend-il en charge le transfert de certificat de chaîne CURL ?

藏色散人
藏色散人avant
2019-04-25 09:27:382821parcourir

Contexte

Récemment, lors de la connexion au paiement WeChat, les certificats doivent être utilisés au point de remboursement. Puisque nous sommes une plate-forme SAAS, nous devons prendre en charge les paiements multipartites et multicanaux si tous les certificats. les fichiers sont enregistrés sur le serveur d'applications, cela sera affecté par SLB, les fichiers sur une certaine machine seront désynchronisés et gêneront le processus de remboursement. Cependant, si les fichiers sont stockés dans OSS, le backend doit les télécharger depuis OSS vers le serveur d'applications. serveur d’applications pour garantir la cohérence. Après de longues délibérations, nous avons finalement décidé de sauvegarder le contenu du certificat dans la base de données. Différents clients correspondent à un seul fichier de certificat. Quel que soit le nombre de machines utilisées dans le cluster, la cohérence du fichier peut être garantie et les étapes de téléchargement redondantes peuvent être évitées. .

Problème

Mais j'ai rencontré un problème dès que je l'ai démarré. Le certificat CURL de PHP ne prend pas en charge la transmission de chaînes et ne peut remplir que le chemin du certificat (ce qui suit est la déclaration officielle). )

Client certificates must be specified by a path expression to a certificate store.

Processus de solution

Ma première pensée est de créer un fichier vierge, d'y écrire le contenu du certificat, puis de supprimer le fichier une fois le certificat utilisé. Cependant, l'opération. Créer un fichier d'entité puis le supprimer consomme beaucoup de performances. Existe-t-il un moyen de créer des fichiers temporaires ? Oui, la fonction tmpfile() peut nous aider à créer un fichier temporaire et à obtenir le chemin du fichier, j'ai donc écrit une méthode pour obtenir le chemin du fichier temporaire

<?php
    public function getTmpPathByContent($content)
    {
        $tmpFile = tmpfile();
        fwrite($tmpFile, $content);
        $tempPemPath = stream_get_meta_data($tmpFile);
        return $tempPemPath[&#39;uri&#39;];  ///tmp/phpXZCtAO
    }
?>

Ce qui est triste c'est que le chemin renvoyé par ceci méthode, je n'ai pas pu lire le contenu du tout, et j'ai même pensé que j'avais été trompé

file_get_contents(/tmp/phpyyiOZv): failed to open stream: No such file or directory

J'ai trouvé la raison après avoir lu les documents officiels si le nombre de références de handle renvoyé par tmpfile() est. 0, le fichier temporaire sera recyclé. Le chemin temporaire deviendra naturellement invalide. Évidemment après l'exécution de la méthode getTmpPathByContent(), le cycle de vie de la variable locale $tmpFile se terminera (le document officiel est le suivant)

.
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.

Après avoir confirmé la cause première, nous devons de toute urgence trouver un type de variable dont le cycle de vie se termine à la fin du processus pour enregistrer le handle. Quel type peut remplir les conditions ? variables statiques. La différence entre les variables statiques et les variables locales est que l'espace mémoire leur est alloué au début du cycle de vie PHP et stocké dans la zone des variables globales. Les variables globales sont détruites lors de la phase d'arrêt du module. Dans ce cas, déclarez les variables statiques. peut garder le $tmpFile nombre de références supérieur à 0, alors notre code peut effectuer le traitement suivant

<?php
    public function getTmpPathByContent($content)
    {
        static $tmpFile = null;
        $tmpFile = tmpfile();
        fwrite($tmpFile, $content);
        $tempPemPath = stream_get_meta_data($tmpFile);
        return $tempPemPath[&#39;uri&#39;];
    }
?>

L'exécuter à nouveau et lire avec succès le contenu du fichier temporaire

-----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-----

Vous pouvez maintenant définir l'adresse du fichier temporaire généré sur CURLOPT_SSLCERT

<?php
    $sslCertPath = getTmpPathByContent($content);
    curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
    //......
?>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer