Думаю кому-то понадобится еще. Сделал так.
Расширил компонент Response, разделил выдачу хедеров и выдачу контента на 2 метода. Стандартный же Yii::$app->response->send() отдает все вместе: и хедеры и контент сразу, что не подходит.
За счет разделения, обработку запроса и выдачу хедеров можно будет включить в свое сторонее приложение в самом начале, а выдачу контента (renderPartial в экшнах) лишь в определенных нужных страницах, внутри уже имеющегося HTML.
/components/Myresponse.php:
Код: Выделить всё
<?php
namespace app\components;
use yii\web\Response;
/**
* Class MyResponse
*
* Divides Headers and Content Response
*/
class MyResponse extends Response
{
/**
* Send Headers to user
*/
public function sendYiiHeaders()
{
if ($this->isSent) {
return;
}
$this->trigger(self::EVENT_BEFORE_SEND);
$this->prepare();
$this->trigger(self::EVENT_AFTER_PREPARE);
$this->sendHeaders();
}
/**
* Send Content to user
*/
public function sendYiiContent()
{
$this->sendContent();
$this->trigger(self::EVENT_AFTER_SEND);
$this->isSent = true;
}
}
Конфиг
/config/web.php:
Код: Выделить всё
...
'request' => [
'enableCsrfValidation' => true,
'enableCookieValidation' => true,
],
'response' => [
'class' => 'app\components\MyResponse',
],
...
Далее в своем стороннем приложении, где-то в самом начале подгружаем Yii, обрабатываем и отдаем хедеры.
include.php:
Код: Выделить всё
<?php
/**
* @link https://github.com/yiisoft/yii2/blob/master/docs/guide/using-3rd-party-libraries.md#using-yii-in-3rd-party-systems
*/
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
$yiiConfig = require(__DIR__ . '/config/web.php');
new yii\web\Application($yiiConfig); // No 'run()' invocation!
require(__DIR__ . '/config/aliases.php');
/**
* Handle User Request
*/
Yii::$app->trigger(Yii\web\application::EVENT_BEFORE_REQUEST);
Yii::$app->handleRequest(Yii::$app->getRequest());
Yii::$app->trigger(Yii\web\application::EVENT_AFTER_REQUEST);
/**
* Send Headers
*/
Yii::$app->response->sendYiiHeaders();
И уже на определенных страницах где надо отдать HTML content:
Например страница /forgot-password.php старого приложения:
Код: Выделить всё
<?php
$pageIndependent=true;
include 'myheader.inc.php'; // где-то здесь происходит инициализация Yii и вызов Yii::$app->response->sendYiiHeaders();
Yii::$app->response->sendYiiContent();
include 'myfooter.inc.php';
Далее чтобы полноценно обрабатывать только нужные url-ы стороннего приложения c помощью Yii, прописал вручную правила:
Код: Выделить всё
...
'components' => [
'urlManager' => [
'class' => 'yii\web\UrlManager',
'showScriptName' => false,
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'rules' => [
'forgot-password' => 'site/forgot-password',
'<controller:^(gii|debug).*>' => '<controller>', // don't block gii and debug
'<controller:.*>' => 'oldsite/ignore', // fake controller for urls Yii don't own
],
],
]
...
Последнее правило - служит как заглушка для урлов старого сайта. Fake-контроллер с выключенным CsrfValidation, в котором не выводится ничего.
/controllers/OldsiteController.php:
Код: Выделить всё
<?php
namespace app\controllers;
use Yii;
use yii\web\controller;
/**
* Class OldsiteController for Existing application
*
* @package app\controllers
*/
class OldsiteController extends Controller
{
public $enableCsrfValidation = false;
/**
* Default cap action used for all old urls outside of Yii
*
* @return null
*/
public function actionIgnore()
{
return null;
}
}
С виду не такой уж и костыль, Yii очень крут что можно легко переопределить поведения каких-то Core компонентов.
Фактически фреймворк работает полноценно в уже существующем приложении.
В итоге и овцы сыты и волки целы.
Думаю можно сделать как-то легче для стороннего приложения и правильнее без fake-контроллера, поэтому замечания очень приветствуются.