Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php classes (I think)

Tags:

oop

php

class

Is there a way to create a php class (or function) that "simplifies" this

ucfirst(str_replace('_',' ',html_entity_decode(trim($variable), ENT_QUOTES))));

The $variable could "come" from anywhere e.g a global from another function or just a "standard" variable

like image 284
user351657 Avatar asked Aug 21 '10 10:08

user351657


People also ask

What are PHP classes?

A PHP class, and more generally, object-oriented programming, provides additional approaches to reusability, and can be used for a variety of purposes: They can describe entities that have known properties and behaviors. They can be used as messages to functions and other objects.

What is :: VS --> in PHP?

Simply put, :: is for class-level properties, and -> is for object-level properties.

What is $this in PHP with example?

$this is a reserved keyword in PHP that refers to the calling object. It is usually the object to which the method belongs, but possibly another object if the method is called statically from the context of a secondary object. This keyword is only applicable to internal methods.

What does :: class do in PHP?

SomeClass::class will return the fully qualified name of SomeClass including the namespace. This feature was implemented in PHP 5.5. It's very useful for 2 reasons. You can use the use keyword to resolve your class and you don't need to write the full class name.


2 Answers

If you want to have this in a class (as the question title implies), then you should create Filter classes. This is a common thing to do. However, compared to the simple function nesting, it will be much more code to do it properly. The advantage is, you can easily extend and combine filters to virtually any filtering needs you have.

I have whipped up something for you quickly.

interface IFilter {
    /**
     * @param Mixed $value The value to be filtered
     * @return Mixed The filtered value
     */
    public function filter($value);
}

All filters must implement the IFilter interface. This is to make sure that whenever you are using a Filter, it has a filter() method that accepts a single $value argument. We cannot enforce return values, but the doc block indicated we expect it to return the filtered value. Two very simple filters would look like this:

class ucFirstFilter implements IFilter
{
    public function filter($value) {
        return ucfirst($value);
    }
}

class TrimFilter implements IFilter
{
    public function filter($value) {
        return trim($value);
    }
}

This is nothing but an object wrapper around two of PHP's native functions. You use it like this:

$trimFilter = new TrimFilter;
echo trimFilter->filter('   trim me   ');
// returns 'trim me'

The other two filters are somewhat more complex, because they can be passed more than one argument:

class SeparatorToSeparatorFilter implements IFilter
{
    protected $_separator;
    protected $_replacement;
    public function __construct($separator = '_', $replacement = ' ')
    {
        $this->_separator = $separator;
        $this->_replacement = $replacement;
    }
    public function filter($value) {
        return str_replace($this->_separator, $this->_replacement, $value);
    }
}

class HtmlEntityDecodeFilter implements IFilter
{
    protected $_quoteStyle;
    protected $_charset;
    public function __construct($quoteStyle=ENT_COMPAT, $charset='ISO-8859-1')
    {
        $this->_quoteStyle = $quoteStyle;
        $this->_charset = $charset;
    }
    public function filter($value) {
        return html_entity_decode($value, $this->_quoteStyle, $this->_charset);
    }
}

As you can see, the configuration of the additional arguments is done through the constructor. I have used some default values, so you only have to supply them when you need to deviate from those. In the case of the second filter, I have used the native function's default settings. This is how you use them:

$trimFilter = new TrimFilter;
$separatorFilter = new SeparatorToSeparatorFilter('-');
echo $separatorFilter->filter($trimFilter->filter('   trim-me   '));
// returns 'trim me';

Now you might be tempted to add multiple filterings into a single Filter class. Dont. Each Filter should do exactly one thing only. There is a better way to combine filters. All you need is a Filter that aggregates multiple other filters aka a FilterChain:

class FilterChain implements IFilter
{
    protected $_filters;
    public function __construct()
    {
        $this->_filters = new SplObjectStorage;
    }
    public function chain(IFilter $filter)
    {
        $this->_filters->attach($filter);
        return $this;
    }
    public function remove(IFilter $filter)
    {
        $this->_filters->detach($filter);
        return $this;
    }
    public function filter($value) {
        foreach($this->_filters as $filter) {
            $value = $filter->filter($value);
        }
        return $value;
    }
}

The FilterChain accepts any object that implements IFilter and if you call it's filter() method, it will iterate over all chained Filters in the order you chain()ed them and return the passed in $value:

$filterChain = new FilterChain;
$filterChain->chain(new ucFirstFilter)
            ->chain(new SeparatorToSeparatorFilter)
            ->chain(new HtmlEntityDecodeFilter(ENT_QUOTES, 'UTF-8'))
            ->chain(new TrimFilter);

echo $filterChain->filter('  i am a "string_to_be_filtered"  ');
// outputs 'i am a "string to be filtered"'

Because the FilterChain also implements IFilter itself, you can also add it to other FilterChains. This is a Composite Pattern. The filter above could be written as

$chain1 = new FilterChain;
$chain1->chain(new ucFirstFilter)
       ->chain(new SeparatorToSeparatorFilter);

$chain2 = new FilterChain;
$chain2->chain($chain1);
$chain2->chain(new HtmlEntityDecodeFilter(ENT_QUOTES, 'UTF-8'))
       ->chain(new TrimFilter);

As you can see, it is much more code, but it is also very extensible. The main advantage over having a single function that wraps all native functions into one function is you can combine anything any way you want. If you decided you need another function that does not utilize the trim() function, you'd have to write a completely new function and you'll inadvertently end up with a lot of functions and redundant code for any possible combination of filters. With a FilterChain you simply add the Filters and FilterChains together as needed. And since a FilterChain is an object, you can pass it around freely.

Fortunately, Filter libraries like this already exist, for instance Zend_Filter offers a number of premade filters and can used standalone (e.g. without having to migrate your app to ZF).

like image 152
Gordon Avatar answered Oct 07 '22 01:10

Gordon


If you are using it more than once, then I would definitely put it into a function. That way you won't be repeating all the code.

function functionName($input){
    return ucfirst(str_replace('_',' ',html_entity_decode(trim($input), ENT_QUOTES)));
}

echo functionName($variable);
like image 38
Sam152 Avatar answered Oct 07 '22 01:10

Sam152