Introducing Mr. Clean Consider him array_map++

Mr. Clean... what is it?

Initially I called it a "sanitizer", but that was misleading. People were concerned about why it wasn't handling XSS and the like, which is not its purpose at all. Now I'm calling it a "cleaner", but there still is some confusion, obviously. So let's clear it up.

Where Did This Come From?

I am currently working on a project where we are transferring a lot of data from an old terrible database to a new shiny database. One of the problems with the old terrible database was that the data was never cleaned before it went in. So there is a lot of trailing whitespace, empty strings where there should be nulls, 'true'/'Y'/'yes' where there should be booleans, Microsoft Word markup in HTML blocks, etc. As part of the transition it to the new shiny, we obviously wanted to clean it up a bit.

Got It. So What Does It Do?

Essentially, Mr. Clean is this:

$clean = array_map('trim', ['this', 'that', 'other thing']);

on steroids. It does that, but it does it like this:

$funcs = ['trim', 'stripslashes', 'htmlentities'];
$data = ['this', 'that', 'other thing'];

$clean = $mr_clean->scrubbers($funcs)->scrub($data);

So at its core, it's array_map++. But it's a little more than that.

Recursive

Mr. Clean will recursively look through whatever you pass into it until it finds a string, then continue looking until there are no more strings left to work with. So whether it is an array, and array of arrays, an array of objects, an array of objects containing arrays, whatever. If you pass it into the scrub method, it will find the value(s) and apply whatever callbacks you specify.

$scrubbed = $cleaner->scrubbers(['trim'])->scrub('Holy string, Batman.');

$scrubbed = $cleaner->scrubbers(['trim'])->scrub(['Holy', 'array', 'Batman']);

$scrubbed = $cleaner->scrubbers(['trim'])->scrub([
    ['Holy', 'array', 'of', 'arrays', 'Batman'],
    ['Holy', 'array', 'of', 'arrays', 'Batman'],
]);

$scrubbed = $cleaner->scrubbers(['trim'])->scrub((object) [
    'first_word'  => 'Holy',
    'second_word' => 'object',
    'third_word'  => 'Batman',
]);

$scrubbed = $cleaner->scrubbers(['trim'])->scrub([
    (object) [
        'first_word'  => 'Holy',
        'second_word' => 'array',
        'third_word'  => 'of',
        'fourth_word' => 'objects',
        'fifth_word'  => 'Batman',
    ],
    (object) [
        'first_word'  => 'Holy',
        'second_word' => 'array',
        'third_word'  => 'of',
        'fourth_word' => 'objects',
        'fifth_word'  => 'Batman',
    ],
]);

$scrubbed = $cleaner->scrubbers(['trim'])->scrub([
    (object) [
        'first_word'  => 'Holy',
        'second_word' => 'mixed',
        'third_word'  => ['bag', 'Batman'],
    ],
]);

It will essentially "deep clean" whatever you put pass into it. But Mr. Clean also allows you to be more specific if you need to be.

Cleaning Values of Specific Keys

If you pass it an associative array, Mr. Clean will pick up on the fact that you want to use those scrubbers on only those keys.

$scrubbers = [
    'first_name' => ['trim'],
    'last_name'  => ['stripslashes', 'htmlentities'],
];

$data = [
    [
        'first_name' => 'Joe ',
        'last_name'  => 'O\'Donnell',
    ],
    [
        'first_name' => ' Harold',
        'last_name'  => 'Frank & Beans',
    ],
];

$scrubbed = $cleaner->scrubbers($scrubbers)->scrub($data);

This worked for a lot of the data, but sometimes we needed to do something that was more complicated than just a basic string function. For that reason, Mr. Clean is also extensible.

Extensibility

All you have to do is extend MrClean\Scrubber\BaseScrubber which adheres to MrClean\Scrubber\ScrubberInterface. There is a single property, value available to you, and you must implement one method, scrub, which takes no arguments and returns the final value.

namespace YourNamespace;

use MrCleanScrubberBaseScrubber;

class YourCustomScrubber extends BaseScrubber {

    public function scrub()
    {
        return str_replace('!', '.', $this->value);
    }

}

From there, just register the scrubber:

$cleaner->register('YourNamespaceYourCustomScrubber');

and it is available for use:

$dirty = ['I need to calm down!', 'Me too!'];

$scrubbed = $cleaner->scrubbers(['your_custom_scrubber'])->scrub($dirty);

Learn More

You can get the full breakdown on Mr. Clean over at the GitHub page. I hope this clears up its origin story and purpose. Use it in good health.