Універсального «очищення» не існує: екранування залежить від того, куди потрапляє рядок. Тому дані зберігають як є, а екранують у момент виведення - під конкретний контекст.
HTML (вміст і атрибути):
echo htmlspecialchars($comment, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
ENT_QUOTES екранує обидва типи лапок (важливо для атрибутів), ENT_SUBSTITUTE замінює зламаний UTF-8 замість повернення порожнього рядка. Blade {{ }} робить саме це.
Але HTML-екранування не захищає атрибут href: javascript:alert(1) пройде без змін. URL від користувача перевіряють за схемою (http/https).
SQL - не екранувати, а прив'язувати параметри:
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
addslashes для SQL небезпечний (кодування, інші СУБД), а ручне екранування легко забути.
URL:
$url = 'https://example.com/search?' . http_build_query(['q' => $query, 'page' => 2]);
rawurlencode($pathSegment); // для частини шляху
Командний рядок:
exec('convert ' . escapeshellarg($input) . ' ' . escapeshellarg($output));
Ще краще - не будувати рядок команди взагалі, а передати аргументи масивом (Symfony Process, Process::run([...]) у Laravel), тоді оболонка не бере участі.
JavaScript усередині HTML:
<script>const user = <?= json_encode($user, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;</script>
У Blade - @json($user) чи Js::from($user).
Правило: знати контекст виведення і використовувати засіб саме для нього. Рядок, безпечний для HTML, може бути небезпечним у SQL чи shell.