Skip to content

Instantly share code, notes, and snippets.

@n1215
Last active December 5, 2022 09:16
Show Gist options
  • Save n1215/1cf315c63fdadd8a33a4d65f10d41241 to your computer and use it in GitHub Desktop.
Save n1215/1cf315c63fdadd8a33a4d65f10d41241 to your computer and use it in GitHub Desktop.
Compile string by Blade template engine.
<?php
declare(strict_types=1);
namespace App\View;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Factory;
use Symfony\Component\Debug\Exception\FatalThrowableError;
/**
* Class StringBladeRenderer
* @package App\View
*/
class StringBladeRenderer
{
/** @var BladeCompiler */
private $bladeCompiler;
/** @var Factory */
private $viewFactory;
/**
* コンストラクタ
* @param BladeCompiler $bladeCompiler
* @param Factory $viewFactory
*/
public function __construct(BladeCompiler $bladeCompiler, Factory $viewFactory)
{
$this->bladeCompiler = $bladeCompiler;
$this->viewFactory = $viewFactory;
}
/**
* @param string $template
* @param array $data
* @return string
* @throws \Throwable
*/
public function render(string $template, array $data = []): string
{
try {
$this->viewFactory->incrementRender();
$contents = $this->evaluate($template, $data);
$this->viewFactory->decrementRender();
$this->viewFactory->flushStateIfDoneRendering();
return $contents;
} catch (\Exception $e) {
$this->viewFactory->flushState();
throw $e;
} catch (\Throwable $e) {
$this->viewFactory->flushState();
throw $e;
}
}
/**
* @param string $template
* @param array $data
* @return string
* @throws \Exception
*/
private function evaluate(string $template, array $data): string
{
$obLevel = ob_get_level();
ob_start();
extract(array_merge($this->viewFactory->getShared(), $data), EXTR_SKIP);
try {
eval($this->bladeCompiler->compileString($template));
} catch (\Exception $e) {
$this->handleViewException($e, $obLevel);
} catch (\Throwable $e) {
$this->handleViewException(new FatalThrowableError($e), $obLevel);
}
return ltrim(ob_get_clean());
}
/**
* @param \Exception $e
* @param $obLevel
* @throws \Exception
*/
private function handleViewException(\Exception $e, $obLevel)
{
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw $e;
}
}
<?php
use App\View\StringBladeRenderer;
// register
app()->singleton(StringBladeRenderer::class, function ($app) {
return new StringBladeRenderer($app->make('blade.compiler'), $app->make('view'));
});
// helper
if (! function_exists('blade')) {
function blade(string $template, array $data = []): string {
return app()->make(StringBladeRenderer::class)->render($template, $data);
}
}
// use
echo blade('@foreach(range(1, 10) as $val) {{$val}}{{$suffix}} @endforeach', ['suffix' => '_cat'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment