What is the difference between Laravel setEscapedC

2019-09-17 02:48发布

问题:

To better understand how Laravel tag settings work, I tried the following:

Blade::setContentTags('<x', 'x>');
Blade::setEscapedContentTags('<y', 'y>');
Blade::setRawTags('<z', 'z>');

in my controller constructor.

In Blade view, I added

<div>
  <x 'test' x>
  <y 'test' y>
  <z 'test' z>
</div>

I cleaned storage/framework/views folder and reloaded the page.

As a result, in compiled view I got

<div>
    <?php echo e('test'); ?>

    <?php echo e('test'); ?>

    <?php echo 'test'; ?>

</div>  

As you see, the code compiled for tags specified with setContentTags and setEscapedContentTags looks the same. Why do we need both of these options then?

回答1:

It's kind of safety reason. By default, Blade will return equal results for content with regular and escaped tags. BladeCompiler class has protected property $echoFormat with value e(%s). This property is used when content compiles with regular tags (in your case it's 'x').

/**
 * The "regular" / legacy echo string format.
 *
 * @var string
 */
protected $echoFormat = 'e(%s)';

The property works as a placeholder for the function e

/**
 * Escape HTML entities in a string.
 *
 * @param  string  $value
 * @return string
 */
function e($value)
{
    return htmlentities($value, ENT_QUOTES, 'UTF-8', false);
}

The e function is also called when content compiles with escaped tags (in your case it's 'y')

Your can change format also:

/**
 * Set the echo format to be used by the compiler.
 *
 * @param  string  $format
 * @return void
 */
public function setEchoFormat($format)
{
    $this->echoFormat = $format;
}

With default settings Blade will return different results for content with regular and escaped tags if you prefix your text with an @ symbol.

For view param

['str' => "<script>alert('name')</script>"]

With template

<div>@{{ $str }}</div>
<div>@{{{ $str }}}</div>

<div>@{{"<a>Plain text</a>"}}</div>
<div>@{{{"<a>Plain text</a>"}}}</div>

The result will be

<div>{{ $str }}</div>
<div>@&lt;script&gt;alert(&#039;name&#039;)&lt;/script&gt;</div>

<div>{{"<a>Plain text</a>"}}</div>
<div>@&lt;a&gt;Plain text&lt;/a&gt;</div>