Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Marcolino922's avatar

HTML Purifier - How to proceed?

I was wondering as a neophyte what to do to make the HTML of my script developed in Laravel 7 purified.

I state that I tried to download https://github.com/mewebstudio/Purifier but it releases me errors in the installation.

So I was wondering what other options might be? Also, basically, doesn't the Laravel framework already have input / output escapes?

0 likes
28 replies
Sinnbeck's avatar

yes you can remove all html using {{$variable}}, but if you want to show the html, you need something like purifier to do so.

What error are you getting? I am using the same package on laravel 7.

1 like
Marcolino922's avatar

Can't find my class. Also running the command: composer require mews/purifier removes many of the packages needed for my script, thus generating errors.

Sinnbeck's avatar

Sounds like you are having some problems with your composer.json file? Make sure that the packages you need are listed in that, and then run composer update

After that, try composer require mews/purifier again and let me know what error you are getting

1 like
Marcolino922's avatar

Do I have to insert the list of all my packages already installed in composer.json? In which section should I enter them?

"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "jeremykenedy/laravel-roles": "^3.2",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.1"
    },
    "require-dev": {
        "facade/ignition": "^2.0",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^4.1",
        "phpunit/phpunit": "^8.5"
    },

?

Marcolino922's avatar

PS: installing the package manually, in any case it gives me this error that it does not find the class, despite setting it in config/app.php

Sinnbeck's avatar

Did you add the config and such before installing it? You can't do it in that order. And what packages are disappearing?

1 like
Marcolino922's avatar

I try to remember, they have been removed .. Laravel, php-http, psr and a few others

Marcolino922's avatar

Is there a native php alternative to solve the same way?

Sinnbeck's avatar

I am very confused. Running composer install should never remove packages listed in the composer.json file. How do you know they are removed? Can you perhaps post a screenshot?

1 like
Marcolino922's avatar

Hi, I explain my movements. I use XAMPP, open Shell and go to the folder where I am working locally. After that, I run the "composer require mews / purifier" command.

By executing the command, the list lists the packages that are being updated, those that are being installed (therefore the latter) and removes other of my packages.

In fact, then reaching my script the errors come out because the necessary packages are not present.

I can take screenshots but would then have to reload the original files again. If it is necessary to understand something more I can do it, but roughly this is what happens.

PS: As I said, I also tried to load the package manually, but still nothing comes out the error that does not find the class.

Sinnbeck's avatar

Well if you project is broken I would suggest we focus on fixing that. If you can never install or update a package ever again, changes are you will run into big problems down the line.

You can of course write your own purifier from scratch. This the package that is used in purifier, and it is possible to implement this from scratch yourself (might take alot of time as it is quite complex) https://github.com/ezyang/htmlpurifier

Any chance you could put the project on github, so I can inspect the source code? Maybe I can then tell you how to fix it :)

1 like
Marcolino922's avatar

I paste the text directly instead of making the screen, this is what it shows me.

# composer update
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 63 updates, 15 removals
  - Removing psr/http-client (1.0.1)
  - Removing php-http/promise (1.1.0)
  - Removing php-http/message-factory (v1.0.2)
  - Removing php-http/message (1.9.0)
  - Removing php-http/httplug (2.2.0)
  - Removing php-http/guzzle6-adapter (v2.0.1)
  - Removing php-http/discovery (1.10.0)
  - Removing omnipay/paypal (v3.0.2)
  - Removing omnipay/common (v3.0.4)
  - Removing moneyphp/money (v3.3.1)
  - Removing league/omnipay (v3.0.2)
  - Removing league/oauth1-client (v1.8.1)
  - Removing laravel/socialite (v5.0.1)
  - Removing intervention/image (2.5.1)
  - Removing clue/stream-filter (v1.4.1)
  - Upgrading dragonmantank/cron-expression (v2.3.0 => v2.3.1): Extracting archive
  - Upgrading symfony/polyfill-php80 (v1.18.1 => v1.20.0): Extracting archive
  - Upgrading symfony/polyfill-mbstring (v1.18.1 => v1.20.0): Extracting archive
  - Upgrading symfony/var-dumper (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/polyfill-intl-normalizer (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading symfony/polyfill-intl-grapheme (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading symfony/polyfill-ctype (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading symfony/string (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/service-contracts (v2.1.2 => v2.2.0): Extracting archive
  - Upgrading symfony/polyfill-php73 (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading symfony/console (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading scrivo/highlight.php (v9.18.1.1 => v9.18.1.4): Extracting archive
  - Upgrading monolog/monolog (2.1.0 => 2.1.1): Extracting archive
  - Upgrading voku/portable-ascii (1.5.2 => 1.5.3): Extracting archive
  - Upgrading phpoption/phpoption (1.7.4 => 1.7.5): Extracting archive
  - Upgrading vlucas/phpdotenv (v4.1.7 => v4.1.8): Extracting archive
  - Upgrading symfony/css-selector (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading tijsverkoyen/css-to-inline-styles (2.2.2 => 2.2.3): Extracting archive
  - Upgrading symfony/deprecation-contracts (v2.1.2 => v2.2.0): Extracting archive
  - Upgrading symfony/routing (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/process (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/polyfill-php72 (v1.17.0 => v1.20.0): Extracting archive
  - Upgrading symfony/polyfill-intl-idn (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading symfony/mime (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/http-foundation (v5.1.2 => v5.1.8): Extracting archive
  - Installing symfony/http-client-contracts (v2.3.1): Extracting archive
  - Upgrading symfony/event-dispatcher-contracts (v2.1.2 => v2.2.0): Extracting archive
  - Upgrading symfony/event-dispatcher (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/error-handler (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/http-kernel (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/finder (v5.1.2 => v5.1.8): Extracting archive
  - Upgrading symfony/polyfill-iconv (v1.17.1 => v1.20.0): Extracting archive
  - Upgrading egulias/email-validator (2.1.18 => 2.1.23): Extracting archive
  - Upgrading ramsey/collection (1.0.1 => 1.1.1): Extracting archive
  - Upgrading brick/math (0.8.15 => 0.9.1): Extracting archive
  - Upgrading ramsey/uuid (4.0.1 => 4.1.1): Extracting archive
  - Upgrading opis/closure (3.5.5 => 3.6.0): Extracting archive
  - Upgrading symfony/translation-contracts (v2.2.0 => v2.3.0): Extracting archive
  - Upgrading symfony/translation (v5.1.5 => v5.1.8): Extracting archive
  - Upgrading nesbot/carbon (2.40.0 => 2.41.5): Extracting archive
  - Installing league/mime-type-detection (1.5.1): Extracting archive
  - Upgrading league/flysystem (1.0.69 => 1.1.3): Extracting archive
  - Upgrading league/commonmark (1.5.1 => 1.5.7): Extracting archive
  - Upgrading laravel/framework (v7.18.0 => v7.29.3): Extracting archive
  - Upgrading filp/whoops (2.7.3 => 2.9.1): Extracting archive
  - Upgrading facade/ignition-contracts (1.0.0 => 1.0.1): Extracting archive
  - Upgrading facade/flare-client-php (1.3.2 => 1.3.7): Extracting archive
  - Upgrading facade/ignition (2.0.7 => 2.4.1): Extracting archive
  - Upgrading fideloper/proxy (4.4.0 => 4.4.1): Extracting archive
  - Upgrading guzzlehttp/psr7 (1.6.1 => 1.7.0): Extracting archive
  - Upgrading guzzlehttp/promises (v1.3.1 => 1.4.0): Extracting archive
  - Upgrading laravel/helpers (v1.2.0 => v1.4.0): Extracting archive
  - Upgrading eklundkristoffer/seedster (3.4 => 4.0): Extracting archive
  - Upgrading jeremykenedy/laravel-roles (v3.2.1 => v3.8.0): Extracting archive
  - Upgrading nikic/php-parser (v4.5.0 => v4.10.2): Extracting archive
  - Upgrading laravel/tinker (v2.4.0 => v2.5.0): Extracting archive
  - Upgrading laravel/ui (v2.1.0 => v2.5.0): Extracting archive
  - Upgrading hamcrest/hamcrest-php (v2.0.0 => v2.0.1): Extracting archive
  - Upgrading mockery/mockery (1.3.1 => 1.3.3): Extracting archive
  - Upgrading nunomaduro/collision (v4.2.0 => v4.3.0): Extracting archive
  - Upgrading webmozart/assert (1.9.0 => 1.9.1): Extracting archive
  - Upgrading phpdocumentor/type-resolver (1.3.0 => 1.4.0): Extracting archive
  - Upgrading phpdocumentor/reflection-docblock (5.1.0 => 5.2.2): Extracting archive
  - Upgrading theseer/tokenizer (1.1.3 => 1.2.0): Extracting archive
  - Upgrading phpspec/prophecy (v1.10.3 => 1.12.1): Extracting archive
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

In ProviderRepository.php line 208:

  Class 'Intervention\Image\ImageServiceProvider' not found


Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1
Sinnbeck's avatar

Ok great. I can see it is removing alot of packages that you are no longer using.. If you want to use any of them, you should add them to the composer.json file :) Note that these are not laravel itself. It might be packages you once used but now dont use any more.. Again you composer.json should hold the things you want to use

 - Removing psr/http-client (1.0.1)
  - Removing php-http/promise (1.1.0)
  - Removing php-http/message-factory (v1.0.2)
  - Removing php-http/message (1.9.0)
  - Removing php-http/httplug (2.2.0)
  - Removing php-http/guzzle6-adapter (v2.0.1)
  - Removing php-http/discovery (1.10.0)
  - Removing omnipay/paypal (v3.0.2)
  - Removing omnipay/common (v3.0.4)
  - Removing moneyphp/money (v3.3.1)
  - Removing league/omnipay (v3.0.2)
  - Removing league/oauth1-client (v1.8.1)
  - Removing laravel/socialite (v5.0.1)
  - Removing intervention/image (2.5.1)
  - Removing clue/stream-filter (v1.4.1)

And regarding the error. I assume you have once had intervention installed and now you dont. Open config/app.php and look for `Intervention\Image\ImageServiceProvider Now remove that line

Now you should be able to install.

1 like
Marcolino922's avatar

Thank you so much for your help, I wouldn't ask for more but I don't want to get confused yet, could you tell me with an example what should be the syntax to add these packages it removes?

"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "jeremykenedy/laravel-roles": "^3.2",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.1"
    },

Here?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Sure :) But do you know what you need them for. Cause most likely you just need the main package of each. Can you show an example of how you are using one of them? For instance I would assume you just need to install composer require php-http/guzzle6-adapter to get all the php-http packages back

If for instance you want intervention image back you just add it like this

require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "jeremykenedy/laravel-roles": "^3.2",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.1",
        "intervention/image" "^2.5.1"
    },

or install it again like this

composer require intervention/image

Either way should work :)

1 like
Marcolino922's avatar

If I directly put all the packages that removed me?


"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "jeremykenedy/laravel-roles": "^3.2",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.1",
        "psr/http-client": "^1.0",
        "php-http/promise": "^1.1",
        "php-http/message-factory": "^1.0",
        "php-http/message": "^1.9",
        "php-http/httplug": "^2.2",
        "php-http/guzzle6-adapter": "^2.0.1",
        "php-http/discovery": "^1.10.0",
        "omnipay/common": "^3.0.4",
        "league/oauth1-client": "^1.8.1",
        "laravel/socialite": "^5.0.1",
        "intervention/image": "^2.5.1",
        "clue/stream-filter": "^1.4.1"
    },
Sinnbeck's avatar

That should work. But if there are packages you dont use directly, you should consider removing them :) If a package needs one of those packages, it will install it by itself.

1 like
Marcolino922's avatar

I proceed as you said then, thank you for the support, I ask you one last thing to proceed so as not to get confused.

I proceed like this:

I run the "composer update" command

I will have thus removed those packages, which I will install again by running the command "composer require php-http / guzzle6-adapter" (it will load all the necessary php-http packages).

I run the command "composer require intervention/image"

After all this, I proceed to run "composer require mews/purifier"

Am I going like this?

Sinnbeck's avatar

Yup that sounds correct.

Doing composer require intervention/image" is just a shortcut for manually inserting it into composer.jsonand runningcomposer update` :) Also it will automatically find the newest version

1 like
Marcolino922's avatar

There is a problem. Installing "composer require intervention / image" removes the Socialite package, if I then try to install the Socialite package, it removes the Image package.

There is something that conflicts.


# composer require intervention/image
Using version ^2.5 for intervention/image
./composer.json has been updated
Running composer update intervention/image
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking intervention/image (2.5.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 2 removals
  - Removing league/oauth1-client (v1.8.2)
  - Removing laravel/socialite (v5.1.0)
  - Installing intervention/image (2.5.1): Extracting archive
2 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

In ProviderRepository.php line 208:

  Class 'Laravel\Socialite\SocialiteServiceProvider' not found


Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
Sinnbeck's avatar

Well as long as your installation fails you cannot complete your install :) So first track down Laravel\Socialite\SocialiteServiceProvider and remove it (I gave instructions in a previous post)

1 like
Marcolino922's avatar

Perfect, everything ok! Thanks a lot! I have left the appropriate votes.

Now I was wondering how to best use this package, how can I use it to prevent XSS attacks via html?

I have to purify every text/input with clean(Input::get('inputname')); ?

Sinnbeck's avatar

Happy to help

Well it depends on whether that field should be allowed to use html when shown. For instance the users name should never be rendered as html provided by the user :)

{{$somedata}} //This is safe, and will remove ALL html
{!!$somedata!!} //This is unsafe and will allow the rendering of the html written by the user.. If you need this, you should run `clean()` on it before saving/using it

So if the user should never use html, you dont need purifier at all :)

Hope that makes sense

2 likes
Marcolino922's avatar

So to be clear, it is good to use "clean" in the text of a page, or for example in a blog post, in the title and body, I go further .. in the biography that a user enters for his profile ... am I right?

Sinnbeck's avatar

Yup. If the data comes from some editor (ckeditor) or similar you should clean it :)

2 likes
Marcolino922's avatar

Perfect, thank you so much once again, I learned a lot today!

Marcolino922's avatar

I'm sorry to have to reopen the discussion, but I wanted to make sure that I was using the package correctly.

Let's assume we have a form for creating a page, where we therefore have title and body input.

Where should I sanitize, in the controller and therefore in the input before saving it in the database or directly in my template and then in the output?

{{ $item->title }}
{!! nl2br(clean($item->body)) !!}

or

$page = Page::create([
            'title'     => clean(request('title')),
            'body'    => clean(request('body')),
..
...

Please or to participate in this conversation.