The only and greatest benefit of using a template engine library with PHP is that it runs htmlspecialchars without omission.
https://github.com/phpstan/phpstan/issues/351#issuecomment-381421561
As commented in this issue, I partially agree with using standard PHP classes for type checking.
Partial means that I want to write a mixed HTML and PHP template as shown below.
<?php
namespace App;
class ProductDto
{
/** @var int */
public $product_id;
/** @var string */
public $name;
/** @var ?string */
public $description;
}
<?php
namespace App;
class ProductHtml {
public function view(ProductDto $product): void {
?>
<div>
<div>
<?= $product->product_id ?>
</div>
<div>
<?= $product->name ?>
</div>
<div>
<?= $product->description ?>
</div>
</div>
<?php
}
}
PHPStan (or rather PHP-Parser) correctly parses PHP with mixed HTML.
The only complaint about this way is that it cannot check htmlspecialchars exhaustively.
For example, <? = $ Product-> description?>
May cause XSS.
PHPStan has a plugin mechanism, so we decided to add a htmlspecialchars check as a trial.
nishphp / phpstan-echo-html-rule
htmlspecialchars checker for PHPStan
PHPStan Echo Html Rule Extension
This package is a PHPStan extension for checking whether htmlspecialchars is called from a pure PHP template.
Install
composer require --dev nish/phpstan-echo-html-rule
How to use
Add to phpstan.neon
includes:
- vendor/nish/phpstan-echo-html-rule/rules.neon
If your composer.json
is:
"autoload": {
"psr-4": { "App\\": "src" },
"files": [
"src/functions.php"
]
},
Value Object class src/ProductDto.php
:
<?php
namespace App;
class ProductDto
{
/** @var int */
public $product_id;
/** @var string */
public $name;
/** @var ?string */
public $description;
}
Html Template src/ProductHtml.php
:
<?php
namespace App
class ProductHtml {
public function view(ProductDto $product): void {
?>
<div>
<div>
<?= $product->product_id ?>
</div>
<div>
<?= $product->name ?>
</div>
<div>
<?= $product->description ?>
</div>
</div>
<?php
}
…Adding this extension will report an error similar to the following:
3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ----------------------------------------------------
Line ProductHtml.php
------ ----------------------------------------------------
16 Parameter #1 (string) is not safehtml-string.
19 Parameter #1 (string|null) is not safehtml-string.
------ ----------------------------------------------------
[ERROR] Found 2 errors
htmlspecialchars
needs return safehtml-string
because the extension added a virtual type safehtml-string
.
<?php
/**
* @param int|string|null $input
* @return safehtml-string
*/
function h($input)
{
return htmlspecialchars((string)$input);
}
/**
* @param int|string|null $input
* @return safehtml-string
*/
function raw($input)
{
return (string)$input;
}
Then, correct the part that caused the error.
<?php
namespace App;
class ProductHtml {
public function view(ProductDto $product): void {
?>
<div>
<div>
<?= $product->product_id ?>
</div>
<div>
<?= h($product->name) ?>
</div>
<div>
<?= h($product->description) ?>
</div>
</div>
<?php
}
}
All other echo calls that do not use htmlspecialchars are now reported as errors too.
Top comments (0)