繁体   English   中英

PHP 内部 Web 服务器提供意外字符的原因可能是什么?

[英]What could be the cause of unexpected characters served by the PHP internal web server?

我在基于 Alpine 3.8 的 Docker 容器中运行 PHP 内部 Web 服务器。

这是一个简单的页面,它是:

<!DOCTYPE html>
<html>
    <head>
        <title>Test page</title>
    </head>
    <body>
        <div>
            This is a 'hello world' for my CD container.
        </div>
        <p>
            Version: <?php echo getenv('CD_DEMO_VERSION') ?>
        </p>
        <p>
            GUID: <?php echo file_get_contents(__DIR__ . '/guid.txt') ?>
        </p>
    </body>
</html>

我在 CircleCI 构建过程中有这个,PHPUnit 使用simplexml_load_string()读取 HTML 以检查它是否正常工作。 大多数情况下它没问题,但偶尔会在 HTML 的开头或结尾添加控制字符,导致 HTML 解析失败。 我会说这种情况发生的概率为 10%,因此很难复制。 它似乎不会发生在本地。

在这个构建过程中,我正在等待 Web 服务器启动,所以我认为这里不会发生竞争条件。

如果 cruft 出现在开始时,它看起来像这样(我的输出交换回车到符号,这不会被 XML 处理器看到):

^@^@<html>⏎    <head>⏎        <title>Test page</title>⏎    </head>⏎    <body>⏎        <div>⏎            This is a 'hello world' for my CD container.⏎        </div>⏎        <p>⏎            Version:         </p>⏎        <p>⏎            GUID: 47294362a6154e9a5397a9f9b72cefe1d349ec2e31de12e6084746a084e4e4ef        </p>⏎    </body>⏎</html>

如果 cruft 出现在最后,它看起来像这样:

<!DOCTYPE html>⏎<html>⏎    <head>⏎        <title>Test page</title>⏎    </head>⏎    <body>⏎        <div>⏎            This is a 'hello world' for my CD container.⏎        </div>⏎        <p>⏎            Version:         </p>⏎        <p>⏎            GUID: a721f44d05e93debb593eef135fc664fb6b0d3aa6a04d50af7f17339d0d75399        </p>⏎    </body>⏎</html>⏎^@^@

我不知道这些是否是实际的抑扬符和符号,或者这是否只是随机内容呈现到我的屏幕上的方式。

看起来 Web 服务器正在提供 UTF-8 字符集标头。

我认为我的 PHPUnit 测试是相关的,所以我会在这里添加它。 由于 CircleCI 的工作方式,我无法在容器外部发布 Docker 端口,因此我使用docker exec从内部执行 HTTP 操作:

public function testApp()
{
    // Get the page and convert it to an XML object
    $html = $this->getWebPage();

    // CI is giving me some parsing issues, so let's see it
    echo str_replace("\n", "⏎", $html);

    $doc = simplexml_load_string($html);
    $message = trim((string) $doc->body->div);

    $this->assertEquals(
        "This is a 'hello world' for my CD container.",
        $message
    );
}

protected function getWebPage()
{
    $output = $return = null;
    $command = sprintf(
        'docker exec -ti %s php -r "echo file_get_contents(\'http://localhost\');"',
        escapeshellarg($this->getRepoName())
    );
    exec($command, $output, $return);

    // Check return value first
    if ($return)
    {
        throw new RuntimeException(
            sprintf(
                'Returned a failure exit code %d on Docker operation',
                $return
            )
        );
    }

    $imploded = implode(PHP_EOL, $output);

    return $imploded;
}

更新

我已经在 Alpine 3.8 中更新到 Apache 2.4.x,令我惊讶的是,我遇到了完全相同的问题。 因此,结果证明它不是 PHP Web 服务器。

我也试过 Alpine 3.7,同样的结果。 我再次尝试了 Ubuntu 18.10。

我试过php -rfile_get_contents()wget作为容器内的 HTTP 设备。

我现在认为从docker exec捕获标准输出是错误的。 我假设如果我在另一个镜像中设置我的测试并使用 Docker Compose 运行容器,它可能会工作。 或者,我可以使用docker exec ,写入一个容器文件,然后使用docker cp取出文件。

不过,知道出了什么问题仍然很有趣。

正如我在问题中推测的那样,这是通过执行docker exec并将标准输出重定向到容器中的临时文件来解决的。 然后我使用docker cp将文件从容器中取出回主机。

我没有发现是什么导致了奇怪的文本伪影,并想知道它是否可能特定于 CircleCI。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM