如何使用 phpseclib 验证证书是否由公共 CA 签名?

2024-03-12

我需要确保 SMTP 服务器证书由公共证书颁发机构签名。我想使用 phpseclib 或其他一些受信任的库。我相信我可以使用根证书 https://curl.haxx.se/docs/caextract.html从火狐浏览器中提取。

有一些自制方法在这里 https://stackoverflow.com/questions/13402866/how-do-i-verify-a-tls-smtp-certificate-is-valid-in-php检查证书日期和其他元数据,但看起来并没有进行任何签名检查(除了确保 OpenSSL 执行此操作之外)。无论如何,我想使用一个库 - 我想编写尽可能少的证书处理代码,因为我不是密码学家。

也就是说,上面链接上的答案仍然非常有用,因为它帮助我获得了一些代码来从 TLS 对话中获取证书:

$url = "tcp://{$domain}:{$port}";
$connection_context_option = [
    'ssl' => [
        'capture_peer_cert' => true,
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true,
    ]
];
$connection_context = stream_context_create($connection_context_option);
$connection_client = stream_socket_client($url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $connection_context);
stream_set_timeout($connection_client, 2);
fread($connection_client, 10240);
fwrite($connection_client,"HELO alice\r\n");
fread($connection_client, 10240);
fwrite($connection_client, "STARTTLS\r\n");
fread($connection_client, 10240);
$ok = stream_socket_enable_crypto($connection_client, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
if ($ok === false)
{
    return false;
}
$connection_info = stream_context_get_params($connection_client);

openssl_x509_export($info["options"]["ssl"]["peer_certificate"], $pem_encoded);

(请注意,我在这里故意关闭了证书验证。这是因为我无法控制它运行在哪些主机上,并且它们的证书可能是旧的或配置错误的。因此,无论连接上的验证如何,我都希望获取证书我正在使用,然后自己使用a进行验证cacert.pem我将提供。)

这会给我一个这样的证书。该服务器适用于 Microsoft 的 Live.com 电子邮件服务器,网址为smtp.live.com:587:

-----BEGIN CERTIFICATE-----
MIIG3TCCBcWgAwIBAgIQAtB7LVsRCmgbyWiiw7Sf5jANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTcwOTEzMDAwMDAwWhcN
MTkwOTEzMTIwMDAwWjBqMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
aW9uMRQwEgYDVQQDEwtvdXRsb29rLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAIz2tovvgBmK4sOHgpyzCdtXrI0XOujctf6LHMj16wzUnMEatioS
tH0Pz0dKkCr/0yd9qtXbGhD1o6WhFsd7k651K9MZ98+uQ29SzTIAl6y1gkaBbp4h
MFXcE5EpRNHHmK8t2OR7hzmrvvNr6OTYv7BhVCw9pSrQqEFNno0K2TQRhAD9uzrL
OY+rBBVedCXWXH7uhZoZ6joUU7CEA5pPMzKPL1ro+Eorc8vt5FYOC+oAT587+b1M
z+jbZVQlq0qaMkBKRtUIII78MYY0n8DopGqHyzwqWoGySHJNC8256q+MwsZQvvQ3
vmy/rf61h2sg1tU0s7O88Yufxp0LSaMMzZcCAwEAAaOCA5owggOWMB8GA1UdIwQY
MBaAFA+AYRyCMWHVLyjnjUY4tCzhxtniMB0GA1UdDgQWBBT7hLoZ/03rqwcslIc2
0k0z2R+vNTCCAdwGA1UdEQSCAdMwggHPggtvdXRsb29rLmNvbYIWKi5jbG8uZm9v
dHByaW50ZG5zLmNvbYIWKi5ucmIuZm9vdHByaW50ZG5zLmNvbYIgYXR0YWNobWVu
dC5vdXRsb29rLm9mZmljZXBwZS5uZXSCG2F0dGFjaG1lbnQub3V0bG9vay5saXZl
Lm5ldIIdYXR0YWNobWVudC5vdXRsb29rLm9mZmljZS5uZXSCHWNjcy5sb2dpbi5t
aWNyb3NvZnRvbmxpbmUuY29tgiFjY3Mtc2RmLmxvZ2luLm1pY3Jvc29mdG9ubGlu
ZS5jb22CC2hvdG1haWwuY29tgg0qLmhvdG1haWwuY29tggoqLmxpdmUuY29tghZt
YWlsLnNlcnZpY2VzLmxpdmUuY29tgg1vZmZpY2UzNjUuY29tgg8qLm9mZmljZTM2
NS5jb22CFyoub3V0bG9vay5vZmZpY2UzNjUuY29tgg0qLm91dGxvb2suY29tghYq
LmludGVybmFsLm91dGxvb2suY29tggwqLm9mZmljZS5jb22CEm91dGxvb2sub2Zm
aWNlLmNvbYIUc3Vic3RyYXRlLm9mZmljZS5jb22CGHN1YnN0cmF0ZS1zZGYub2Zm
aWNlLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
AQUFBwMCMGsGA1UdHwRkMGIwL6AtoCuGKWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
bS9zc2NhLXNoYTItZzEuY3JsMC+gLaArhilodHRwOi8vY3JsNC5kaWdpY2VydC5j
b20vc3NjYS1zaGEyLWcxLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgG
CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAEC
AjB8BggrBgEFBQcBAQRwMG4wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj
ZXJ0LmNvbTBGBggrBgEFBQcwAoY6aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t
L0RpZ2lDZXJ0U0hBMlNlY3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0G
CSqGSIb3DQEBCwUAA4IBAQA3zjN7I6jTeL+08nhG5eAY0q4pLY40bCQHqONBLSI3
uRmQFUfrQOPYBqLC1QU+J2Z2HcX7YiqE3WAR3ODS9g2BAVXkKOQKNBnr2hKwueOz
qPwyvTyzcIQYUw+SrTX+bfJwYMTmZvtP9S7/pB1jPhrV7YGsD55AI9bGa9cmH7VQ
OiL1p5Qovg5KRsldoZeC04OF/UQIR1fv47VGptsHHGypvSo1JinJFQMXylqLIrUW
lV66p3Ui7pFABGc/Lv7nOyANXfLugBO8MyzydGA4NRGiS2MbGpswPCg154pWausU
M0qaEPsM2o3CSTfxSJQQIyEe+izV3UQqYSyWkNqCCFPN
-----END CERTIFICATE-----

太好了。所以我想针对任何公共 CA 来验证这一点。我相信这是一个有效的证书,并且该链已使用正确验证这项检查服务 https://www.checktls.com/live/index.html:

Array
(
    [name] => /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=outlook.com
    [subject] => Array
        (
            [C] => US
            [ST] => Washington
            [L] => Redmond
            [O] => Microsoft Corporation
            [CN] => outlook.com
        )

    [hash] => a3c08ece
    [issuer] => Array
        (
            [C] => US
            [O] => DigiCert Inc
            [CN] => DigiCert SHA2 Secure Server CA
        )

    [version] => 2
    [serialNumber] => 3740952067977374966703603448215281638
    [serialNumberHex] => 02D07B2D5B110A681BC968A2C3B49FE6
    [validFrom] => 170913000000Z
    [validTo] => 190913120000Z
    [validFrom_time_t] => 1505260800
    [validTo_time_t] => 1568376000
    [signatureTypeSN] => RSA-SHA256
    [signatureTypeLN] => sha256WithRSAEncryption
    [signatureTypeNID] => 668
    [purposes] => Array
        (
            [1] => Array
                (
                    [0] => 1
                    [1] => 
                    [2] => sslclient
                )

            [2] => Array
                (
                    [0] => 1
                    [1] => 
                    [2] => sslserver
                )

            [3] => Array
                (
                    [0] => 1
                    [1] => 
                    [2] => nssslserver
                )

            [4] => Array
                (
                    [0] => 
                    [1] => 
                    [2] => smimesign
                )

            [5] => Array
                (
                    [0] => 
                    [1] => 
                    [2] => smimeencrypt
                )

            [6] => Array
                (
                    [0] => 
                    [1] => 
                    [2] => crlsign
                )

            [7] => Array
                (
                    [0] => 1
                    [1] => 1
                    [2] => any
                )

            [8] => Array
                (
                    [0] => 1
                    [1] => 
                    [2] => ocsphelper
                )

            [9] => Array
                (
                    [0] => 
                    [1] => 
                    [2] => timestampsign
                )

        )

    [extensions] => Array
        (
            [authorityKeyIdentifier] => keyid:0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2

            [subjectKeyIdentifier] => FB:84:BA:19:FF:4D:EB:AB:07:2C:94:87:36:D2:4D:33:D9:1F:AF:35
            [subjectAltName] => DNS:outlook.com, DNS:*.clo.footprintdns.com, DNS:*.nrb.footprintdns.com, DNS:attachment.outlook.officeppe.net, DNS:attachment.outlook.live.net, DNS:attachment.outlook.office.net, DNS:ccs.login.microsoftonline.com, DNS:ccs-sdf.login.microsoftonline.com, DNS:hotmail.com, DNS:*.hotmail.com, DNS:*.live.com, DNS:mail.services.live.com, DNS:office365.com, DNS:*.office365.com, DNS:*.outlook.office365.com, DNS:*.outlook.com, DNS:*.internal.outlook.com, DNS:*.office.com, DNS:outlook.office.com, DNS:substrate.office.com, DNS:substrate-sdf.office.com
            [keyUsage] => Digital Signature, Key Encipherment
            [extendedKeyUsage] => TLS Web Server Authentication, TLS Web Client Authentication
            [crlDistributionPoints] => 
Full Name:
  URI:http://crl3.digicert.com/ssca-sha2-g1.crl

Full Name:
  URI:http://crl4.digicert.com/ssca-sha2-g1.crl

            [certificatePolicies] => Policy: 2.16.840.1.114412.1.1
  CPS: https://www.digicert.com/CPS
Policy: 2.23.140.1.2.2

            [authorityInfoAccess] => OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt

            [basicConstraints] => CA:FALSE
        )

)

以下是我尝试验证 phpseclib 中的 sig 的方法:

$x509 = new \phpseclib\File\X509();

// From the Mozilla bundle (getPublicCaCerts splits them with a regex)
$splitCerts = getPublicCaCerts(file_get_contents('cacert.pem'));

// Load the certs separately
$caStatus = true;
foreach ($splitCerts as $caCert)
{
    $caStatus = $caStatus && $x509->loadCA($caCert);
}
// $caStatus is now true, so all good here

$certData = $x509->loadX509($pem_encoded); // From the TLS server
$valid = $x509->validateSignature();
// $valid is now false

这返回false,这不是我所期望的。我想知道我的输入格式是否正确? CA 的加载和测试中的证书似乎返回了良好的值。不幸的是,phpseclib 文档中的示例有点少,我在网络上的其他地方没有找到太多内容。

旁白:我有一个模糊的怀疑这个图书馆 https://github.com/paragonie/certainty可以帮助我,假设它具有验证证书的功能。然而,我认为它试图为我的情况做很多事情 - 我希望我的软件在共享主机上运行,​​而自动下载感觉就像另一个可能失败的移动部分。我宁愿部署自己的包,提供公共 CA 信息作为(大)参数,然后运行验证测试in situ。 phpseclib 可能是完美的选择,只要我能弄清楚输入格式!

可能原因:phpseclib找不到匹配的证书来测试

我已将问题范围缩小到搜索循环 https://github.com/phpseclib/phpseclib/blob/2.0/phpseclib/File/X509.php#L2151在 phpseclib 的验证器中。在 L2156 上,我们有以下代码:

case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']:

该常量确实是未定义的,因此测试实际上是 CA 是否可以匹配正确的证书详细信息。该证书具有以下元数据:

id-at-countryName = US
id-at-organizationName = DigiCert Inc
id-at-organizationalUnitName = www.digicert.com
id-at-commonName = DigiCert SHA2 High Assurance Server CA

对于所有当前会匹配的证书,我在最新的证书包中只有这些值(即,如果不是通用名称,则以下所有内容都会匹配DigiCert SHA2 High Assurance Server CA没有被发现):

id-at-commonName = DigiCert Assured ID Root CA

id-at-commonName = DigiCert High Assurance EV Root CA

id-at-commonName = DigiCert Assured ID Root G2

id-at-commonName = DigiCert Assured ID Root G3

id-at-commonName = DigiCert Global Root G2

id-at-commonName = DigiCert Global Root G3

id-at-commonName = DigiCert Trusted Root G4

因此,系统甚至无法进行数字签名检查,因为它无法找到与该证书对应的 CA。我缺少什么?这个简单的任务应该比这容易得多!

可能的原因:Mozilla 捆绑包仅包含 Web 服务器证书

我推测邮件服务器证书不在 Mozilla 捆绑包中,因为 Web 浏览器不需要它们。我认为我的 GNU/Linux Mint 安装上的证书是最新的并且适合该目的,因为操作系统应该能够验证邮件服务器中使用的证书。

因此,我尝试了这段代码,它将所有系统证书加载到 phpseclib 中:

$certLocations = openssl_get_cert_locations();
$dir = $certLocations['default_cert_dir'];
$glob = $dir . '/*';
echo "Finding certs: " . $dir . "\n";

$x509 = new \phpseclib\File\X509();

foreach (glob($glob) as $certPath)
{
    // Change this so it is recursive?
    if (is_file($certPath))
    {
        $ok = $x509->loadCA(file_get_contents($certPath));
        if (!$ok)
        {
            echo sprintf("CA cert `%s` is invalid\n", $certPath);
        }
    }
}

// The 'getCertToTest' func just gets the live.com cert as a string
$data = $x509->loadX509(getCertToTest());
if (!$data)
{
    echo "Cert is invalid\n";
    exit();
}

$valid = $x509->validateSignature();
echo sprintf("Validation: %s\n", $valid ? 'Yes' : 'No');

不幸的是,这也失败了。

使用 openssl 确认我的系统证书正常

我已在我的系统上发出此命令,并且远程 TLS 证书已验证正常。我不太了解 phpseclib 代码,但它看起来并没有进行任何链接,这显然是必要的。

openssl s_client -connect smtp.live.com:25 -starttls smtp
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Cloud Services CA-1
verify return:1
depth=0 C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = outlook.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=outlook.com
   i:/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
 1 s:/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIG/jCCBeagAwIBAgIQDs2Q7J6KkeHe1d6ecU8P9DANBgkqhkiG9w0BAQsFADBL
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSUwIwYDVQQDExxE
aWdpQ2VydCBDbG91ZCBTZXJ2aWNlcyBDQS0xMB4XDTE3MDkxMzAwMDAwMFoXDTE4
MDkxMzEyMDAwMFowajELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
(snipped, see other code block)
nGhseM2tJfwa2HMwUpuuo5029u4Dd40qvD0cMz33cOvBLRGkTPbXCFw24ZBdQrkt
SC5TAWzHFyT2tLC17LeSb7d0g+fuj41L6y4a9och8cPiv9IAP4sftzYupO99h4qg
7UXP7o3AOOGqrPS3INhO4068Z63indstanIHYM0IUHa3A2xrcz7ZbEuw1HiGH/Ba
HMz/gTSd2c0BXNiPeM7gdOK3
-----END CERTIFICATE-----
subject=/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=outlook.com
issuer=/C=US/O=DigiCert Inc/CN=DigiCert Cloud Services CA-1
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1:RSA+SHA512:ECDSA+SHA512
Shared Requested Signature Algorithms: RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1:RSA+SHA512:ECDSA+SHA512
Peer signing digest: SHA1
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3831 bytes and written 478 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: C11A0000050CD144CB5C49DD873D2C911F7CDDECFE18001F70FE0427C88B52F7
    Session-ID-ctx: 
    Master-Key: 5F4EC0B1198CF0A16D19F758E6A0961ED227FCEBD7EF96D4D6A7470E3F9B0453A2A06AC0C1691C31A1CA4B73209B38DE
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1519322480
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
250 SMTPUTF8

我可能会放弃 phpseclib 而转而使用二进制命令,但我会依赖system/exec等,这可能不可用。尽管如此,有时工作总比总是不工作好!

Summary

尽管做了大量的工作,我仍然在这方面陷入了死胡同。我将在这里总结我想做的事情。

我想使用 PHP 来根据已知的公共 CA 验证邮件服务器 SSL 证书。我不知道 Mozilla 证书是否适合用于此目的,或者我是否需要从其他地方获取它们。我发现我的 Linux Mint 开发机器具有可以验证上面示例邮件服务器的证书。

这里的简单策略是使用 PHP 5.6+ 并确保在流上下文中启用所有验证选项(尽管理想情况下,我也希望支持 5.5)。但是,我想自己证明,要么使用openssl_函数或库(例如 phpseclib),因此我可以了解为什么给定的证书有效(或无效)。这opensslbinary 就是这样做的(如上所示),并且它可能使用与 PHP 的 openssl 调用非常相似的东西来这样做,但我不知道它是如何做到的。例如,openssl 二进制文件是否使用证书链信息来执行此操作?

另一种方法是从有效的 SSL 会话中读取一些信息,但我在手册中也找不到任何可以执行此操作的内容。


该证书由中间人签署,在本例中为DigiCert SHA2 安全服务器 CA。中间证书不存在于根证书列表中。无论您使用什么库,我相信您都必须为验证过程明确提供有效的中间证书。

这是一个使用的示例sop/x509 https://github.com/sop/x509图书馆。

// certificate from smtp.live.com
$cert = Certificate::fromPEM(PEM::fromString($certdata));
// list of trust anchors from https://curl.haxx.se/ca/cacert.pem
$trusted = CertificateBundle::fromPEMBundle(PEMBundle::fromFile('cacert.pem'));
// intermediate certificate from
// https://www.digicert.com/CACerts/DigiCertSHA2SecureServerCA.crt
$intermediates = new CertificateBundle(
    Certificate::fromDER(file_get_contents('DigiCertSHA2SecureServerCA.crt')));
// build certification path
$path_builder = new CertificationPathBuilder($trusted);
$certification_path = $path_builder->shortestPathToTarget($cert, $intermediates);
// validate certification path
$result = $certification_path->validate(PathValidationConfig::defaultConfig());
// failure would throw an exception
echo "Validation successful\n";

这会进行签名验证和一些基本检查RFC 5280 https://www.rfc-editor.org/rfc/rfc5280#section-6。它不验证 CN 或 SAN 是否与目标域匹配。

免责声明!我是该库的作者。它没有经过实战验证,因此我担心它不会属于您的“其他一些值得信赖的库”类别。不过,请随意尝试一下:)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 phpseclib 验证证书是否由公共 CA 签名? 的相关文章

  • 如何复制 ArrayIterator 以保留其当前迭代位置?

    因为这似乎是我必须做的才能达到这种效果 arr a gt first b gt second iter new ArrayIterator arr Do a bunch of iterations iter gt next new iter
  • 如何在 Laravel 查询中使用多个 OR,AND 条件

    我需要 Laravel 查询帮助 我的自定义查询 返回正确结果 Select FROM events WHERE status 0 AND type public or type private 如何写这个查询Laravel Event w
  • WooCommerce 使用 AJAX 设置购物车数量?

    我已经为此绞尽脑汁好几天了 需要一些指导 我正在为 WooCommerce 网站完全从头开始制作自定义主题 现在我正在尝试让购物车功能正常工作 我一直试图使用按钮 来更新购物车中产品的数量 对我来说问题似乎是WC 我在functions p
  • 如何将 HTML 转换为 Markdown?

    我有一个类似 stackoverflow 的网站 有一个文本区域 人们可以在其中写答案 我用这个 PHP 库 http parsedown org 转换降价 我的意思是我使用该函数来转换 italic to i italic i inclu
  • Android 2.3.4 SSL问题

    升级到 Android 2 3 4 后 出现以下异常 javax net ssl SSLException Read error ssl 0x I O error during system call Connection timed ou
  • 负载平衡集群中的 PHP 会话 - 如何?

    好的 我得到了这个完全罕见的负载平衡 PHP 网站的独特场景 令人遗憾的是 它过去没有进行负载平衡 现在我们开始遇到问题 目前唯一的问题是 PHP 会话 当然 一开始没有人想到这个问题 因此 PHP 会话配置保留为默认值 因此 两台服务器都
  • 如何通过php的require()或include()函数传递变量?

    当我使用这个时 require diggstyle code php page page no 警告是 无法打开流 第 198 行 C xampp htdocs 4ajax gallery core php 中没有错误 错误是 Failed
  • 为什么验证不起作用并跳转到另一个页面?

    我写了一个customer display php来验证数据 到目前为止只有名字 但无论名字字段是否为空 网页都会跳转到customer search php并且没有更改数据库中的信息 为什么
  • 在 Symfony 序列化中更改序列化属性名称

    我正在使用 Symfony 序列化器 效果很好 use Symfony Component Serializer Annotation Groups Groups default notification public function g
  • 使用先前的反向引用作为命名捕获组的名称

    有没有办法使用对先前捕获组的反向引用作为捕获组的名称命名捕获组 这可能不可能 如果不可能 那么这就是一个有效的答案 下列 data description some description preg match data matches p
  • 如何使用 Twig 的属性函数访问嵌套对象属性

    我试图使用一个树枝变量来访问另一个树枝变量的属性 直到我找到 属性 函数为止 该变量才起作用 除了需要访问嵌套属性的情况外 效果很好 当包含属性的变量实际上是对象 属性时 它不起作用 例如 attribute object1 variabl
  • PHP Solr PECL 扩展安装

    我已经使用命令安装了 pecl solr pecl install solr 和梨使用 wget http pear php net go pear phar php go pear phar 重启Apache后 我仍然收到错误 Fatal
  • 如何在 yii2 中使用两个不同的模型登录或切换身份类别?

    我想允许用户从两个不同的模型登录 配置文件 user gt identityClass gt app models User one more class here enableAutoLogin gt false authTimeout
  • WordPress 分页自定义帖子类型

    我有一个名为 新闻 的页面 使用页面模板page newslist php 它应该显示来自自定义帖子类型 也称为新闻 的帖子 我意识到两者具有相同的名称会导致问题 因此在注册自定义帖子类型时 我进行了重写以将其与页面区分开来 rewrite
  • phpunit测试调用其他需要mock的类方法的方法

    我正在尝试创建一个非常标准的单元测试 在其中调用一个方法并断言它的响应 但是我正在测试的方法调用同一类中的另一个方法 该方法做了一些繁重的工作 我想模拟该方法 但仍按原样执行我正在测试的方法 仅使用从调用另一种方法返回的模拟值 我简化了示例
  • Apache、PHP 和 MySQL 可移植吗?

    我可以在外部硬盘上运行 Apache PHP 和 MySQL 吗 我需要这个 因为我在不同的地方工作 计算机 有时我没有安装和配置所有使用的应用程序 当然可以 XAMPP http www apachefriends org en xamp
  • Sonata DateTimePickerType 类默认日期显示错误的日期时间格式

    我陷入困境 我不知道如何使用 sonata DateTimePickerType 类正确设置默认日期和时间 我尝试了不同的方法 但到目前为止 没有一种方法没有帮助 在下面的截图中 help 键显示正确的日期和时间 但是当我使用 dp 默认日
  • 将 SSLSetEnabledCiphers 与 AFNetworking 结合使用来禁用弱密码

    我正在尝试禁用一些密码 弱 例如单个 DES 单个 DES 40 位等 我尝试过使用这段代码在 Cocoa 中使用 CFSocket CFStream 时如何设置 SSL 密码 https stackoverflow com questio
  • 如何在 Zend Framework 3 中注册自定义表单视图助手

    我正在将继承的 Zend Framework 2 应用程序迁移到 Zend Framework 3 并且在注册自定义表单视图助手时遇到了一些困难 这些助手在应用程序使用版本 2 时起作用 主要用于添加标签属性以实现可访问性 例如 这是一个自
  • 为什么我的会话仍然存在?

    我一定很愚蠢 因为似乎一件相当明显的事情现在让我完全困惑 我有一个会议 ie SESSION handbag id 在某个时刻 我需要彻底终止这个会话 ie at the start of the page session start el

随机推荐