【问题标题】:Different php.ini file loaded dependant upon the code content根据代码内容加载不同的 php.ini 文件
【发布时间】:2018-06-15 13:59:30
【问题描述】:

我真的不知道发生了什么——这一切都始于尝试运行测试覆盖率报告时出现Error: No code coverage driver is available 的 PHPUnit 错误,并以我调试到下面描述的可复制集而结束。但要设置舞台 - 我正在使用 Laravel 5.5、Xdebug 2.5.5、PHPUnit 6.5.5。我的测试代码说明了这个问题:

<?php

use Tests\TestCase;

class A extends TestCase
{
    public function testA()
    {
        echo( get_cfg_var('cfg_file_path')); exit;
    }
}

输出C:\Users\xxx\AppData\Local\Temp\7598.tmp

将其与输出正确 php.ini 路径的代码进行比较:

<?php

use PHPUnit\Framework\TestCase;

class A extends TestCase
{
    public function testA()
    {
        echo( get_cfg_var('cfg_file_path')); exit;
    }
}

输出:C:\server\php\php.ini

怎么可能?加载的 php.ini 文件如何根据执行的代码进行更改?更好的是 - 如何加载我正确的 php.ini 文件(启用了 xdebug),而不是这个冒名顶替者?

在这两种情况下,测试都是使用phpunit tests\unit\a启动的

文件夹结构为:

Laravel Project
└───tests
    └───Unit
        └───A.php

【问题讨论】:

  • 您究竟是如何启动测试的? 测试框架通常可以使用自定义php.ini 文件,有些默认情况下会这样做。 PHP 解释器allows it。这可能是这里发生的事情吗?
  • 在这两种情况下,我都使用phpunit 命令启动它。据我了解,如果要加载自定义 php.ini,两种情况都会加载
  • 那么这里唯一的区别是use语句中的类路径不同?
  • 是的!___________
  • 那么,在那种情况下,Tests\TestCase 究竟扩展了什么?层次结构是否回到PHPUnit\Framework\TestCase

标签: php phpunit xdebug laravel-5.5


【解决方案1】:

我们已经追踪到 Composer 的 XdebugHandler.php::writeTmpIni 函数位于 vendor\composer\composer\src\Composer\XdebugHandler.php 的问题。

显然,在应用程序初始化期间,一个单独的php 进程会产生一个临时的php.ini,并且该 php 进程是传递给的测试,但 为什么 它这样做目前超出了我的范围。

将在 Laravel 的 bugtracker 上标记它如何处理这个问题。

添加 Composer 作为一个包(在我的例子中)的依赖是 larapack/hooks,它本身就是 larapack/voyager-hooks 的依赖,它本身就是 Voyager 的依赖。

据我所知,在 Laravel 应用程序的初始化过程中,不应触发此行为(为什么要初始化一个不需要的依赖项,至少是明确的)。为什么 Composer 会在那个阶段自己触发,我也想不通。

我们应用的解决方案是添加:

<php>
    <env name="COMPOSER_ALLOW_XDEBUG" value="1"/>
</php>

phpunit.xml 文件中


我现在已将此作为问题提交:https://github.com/laravel/framework/issues/22782


根据 GitHub 上的讨论,这是由 Laravel 5.5 中关于处理服务提供者的更改引起的 (https://laravel.com/docs/5.5/packages#package-discovery)。它是如何更新的,我不知道 - 对我来说,这是 5.4 和 5.5 之间的变化,值得在升级中注意(但请阅读 Github 上发生的讨论并自行决定此事);老实说,报告这个问题让我觉得很酸,我不会再追究了。


我还在 larapack/voyager-hooks 上提出了一个关于处理 5.5 中引入的服务提供者发现的问题 - https://github.com/larapack/voyager-hooks/issues/16

此问题现已在 larapack/hooks:v1.0.3 中得到修复

【讨论】:

  • (随机想法)可能是性能优化(例如更改配置以禁用 xdebug 扩展).. 但这可能对作曲家自己的功能有任何意义(例如 composer update 或类似的)和不适用于应用程序使用...如果您使用 Composer 发回您的发现(作为提及我的附加评论)会很好 - 我想知道结果(总体上非常有趣的情况)。
  • 不用担心 - 会的。我发现有趣的是,干净的 Laravel 项目在包中没有 vendor/Composer,所以它可能是一个过时的依赖项。仍然 - 必须检查所有软件包,检查它的来源,以及它是否确实是一个问题(对于以前版本的 Composer)/它是否存在于当前版本中(怀疑,因为干净的安装没有这些问题)。 Composer 确实抱怨 xdebug 正在运行,但这是我第一次看到如此奇特的东西。
  • 我要做的是在writeTmpIni() 中放置一个断点,或者只是在那里抛出一个异常,这样我就可以看到堆栈跟踪并了解为什么以及由谁composer 参与运行测试。 (如果测试是由 Composer 的 composer exec phpunit -vvv 执行的,我会理解,但似乎不是这样。)
  • @Smuurf 这当然是帮助跟踪的好主意。到目前为止,我所做的是在 vendor 文件夹中搜索所有包含 composer 要求的 composer.json 并且只有一个实例(在 larapack/hooks 中),所以这似乎是罪魁祸首。跨度>
【解决方案2】:

我以前遇到过一些其他问题,我觉得很奇怪。 看来您正在使用 Windows 机器作为您的开发人员。 我不确定你的php安装。但是发生在我身上的是,我有很多不同的 apache、php、phpunit、nginx、mysql 实例位于不同的文件夹中。

我的意思是,您的机器上似乎安装了许多 php。 并且由于某种原因,在 OP 中描述的 2 种情况下使用了不同的 php 解释器。

我可能是错的,但我对用于执行这两个测试的命令和文件夹的评论仍然没有回应。

但你可以输出

echo PHP_BINDIR;

在两个测试中确保在两种情况下都使用相同的 php 解释器。

【讨论】:

  • 两种情况下都执行相同的 php 解释器。问题是,当使用use Tests\TestCase; 时,Laravel 应用程序会被初始化,这会产生一个新的 php 请求,该请求使用动态生成的 php.ini,其中 xdebug 已注释掉。当然如果你使用use PHPUnit\Framework\TestCase 那么 Laravel 应用程序没有初始化,这不会产生问题。
猜你喜欢
  • 1970-01-01
  • 2018-06-27
  • 2018-11-26
  • 1970-01-01
  • 2015-01-11
  • 2013-04-17
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
相关资源
最近更新 更多