php - 从 Web 应用程序运行控制台时,Yii2 header 发送两次

标签 php google-app-engine yii2

您好,我正在尝试将 Yii2 应用程序部署到 Google App Engine Standard(而非 Flex)。

标准环境不允许后台任务或popen(),甚至不允许写入php://stdout。此外,GAE Cron 作为队列任务似乎使用 http 与其他服务进行通信。因此,我试图找出一种通过 Web 服务包装我的控制台应用程序的方法,我将限制访问该 Web 服务仅供实习生使用。我的尝试是以下操作:

public function actionMigrateTest()
{
    /**
     * GAE use
     * https://cloud.google.com/appengine/docs/standard/php/googlestorage/
     */
    // defined('STDOUT') or define('STDOUT', fopen('gs://stdout0/stdout', 'w'));
    // defined('STDERR') or define('STDERR', fopen('gs://stdout0/stderr', 'w'));

    /**
     * local use
     */
    defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
    defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
    defined('STDERR') or define('STDERR', fopen('php://stderr', 'w'));

    $migration = new \yii\console\controllers\MigrateController('migrate', Yii::$app);
    $status = $migration->runAction('up', ['migrationPath' => '@app/migrations/', 'interactive' => false]);

    fclose(\STDOUT);
    fclose(\STDERR);
}

效果很好,并且在取消注释顶行以写入 GAE 存储而不是 php://stdout 后执行脚本。当我发现写入该文件的响应类似于以下内容时,没有问题:

Yii Migration Tool (based on Yii v2.0.15.1)

No new migrations found. Your system is up-to-date.

问题是当控制台任务执行时,响应类似于:

...
...
*** applying m180206_052910_create_variant_value_table
*** applied m180206_052910_create_variant_value_table (time: 0.129s)


15 migrations were applied.

Migrated up successfully.

在该成功的脚本之后,会出现以下错误(在 GAE 中,就像在我的本地环境中一样):

An Error occurred while handling another error:
exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/db/Migration.php on line 591.' in /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/web/Response.php:366
Stack trace:
#0 /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
#1 /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/web/ErrorHandler.php(135): yii\web\Response->send()
#2 /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\HeadersAlreadySentException))
#3 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\HeadersAlreadySentException))
#4 {main}
Previous exception:
exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/db/Migration.php on line 591.' in /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/web/Response.php:366
Stack trace:
#0 /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
#1 /Users/salem/Sites/kt/shell55/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Response->send()
#2 /Users/salem/Sites/kt/shell55/web/index.php(28): yii\base\Application->run()
#3 {main}

知道为什么 header 与特定响应一起发送两次或者如何避免它吗?

最佳答案

尝试使用 ob_start()ob_get_clean() 包装迁移运行,或在此方法末尾放置 exit 以防止进一步处理。

public function actionMigrateTest()
{
    ob_start();

    defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
    defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));
    defined('STDERR') or define('STDERR', fopen('php://stderr', 'w'));

    $migration = new \yii\console\controllers\MigrateController('migrate', Yii::$app);
    $status = $migration->runAction('up', ['migrationPath' => '@app/migrations/', 'interactive' => false]);

    fclose(\STDOUT);
    fclose(\STDERR);

    return ob_get_clean();
}

由于 Yii 2.0.14 不允许在 Controller 中回显,因此您需要返回响应。 GitHub上有几个类似的问题.

关于php - 从 Web 应用程序运行控制台时,Yii2 header 发送两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49638762/

相关文章:

python - Dispatch 未正确路由内部队列请求

google-app-engine - 将文件从 Google App Engine 上传到 Amazon S3 会导致异常

php - 访问 yii2 Controller 方法时找不到对象

yii2 - 使用composer创建yii2项目出错

php - Yii2:如何在 CheckboxList 中显示选中的值

php - 在 Crontab 中获取包含 jQuery 帖子的网页

php - Kohana 3.1 中的 XSS 清理

python - 请求有效而 URLFetch 无效

php - 阻止 php 出现在背景图片上方

javascript - 如何使用 PHP 从 SQL Server 填充 HTML 表单字段