Built In Functions

Using trim() for input sanitization, htmlspecialchars() for security, and __call() for dynamic method handling

Through the last 100 PHP articles, we’ve used all sorts of built in functions. It’s time to collect them in one place, give a couple of examples, and add any additional ones that I might have missed. You may be asking what a built in function is. It’s just a function that comes with the PHP installation. You don’t have to know where they’re at. You don’t have to instantiate an object. They’re available globally.

The functions that we’re going to look at are the following:

  • trim(), ltrim()rtrim()
  • htmlspecialchars()
  • __call()
  • preg_match()
  • filter_var()
  • addslashes()
  • str_replace()
  • strlen()
  • strtolower()
  • strtoupper()
  • ucfirst()
  • strpos(), stripos(), strrpos(), strripos()
  • Array Functions like: array_chunk(), array_diff(), array_key_exists(), array_key_first(), array_key_last(), array_map(), array_merge(), array_push(), array_sum(), asort(), arsort(), count(), in_array(), ksort(), krsort(), sort(), rsort(), shuffle(), sizeof(), is_array(), explode(), implode()
  • Magic Methods like: __invoke(), __toString()

No rhyme or reason to this. Let’s just run through the list.

trim(), ltrim(), rtrim()

These are string operations that “trim” or remove white spaces. The trim() function removes white spaces from both sides; ltrim() removes whitespaces only from the left side of the string; rtrim() removes the whitespaces only from the right side. None of these functions remove whitespaces from the middle of a string.

<?php

// trim()
$string = " Hello There ";
$string = trim($string);
var_dump($string);
var_dump(Carbon::SECONDS_PER_MINUTE); // int(60)
/app/98 Functions/index.php:6:string 'Hello There' (length=11)

The trim() function removes the whitespace from the beginning and the end. The initial string length is 13, but only 11 after the trim() function is applied.

<?php

// ltrim()
$string = " Hello There ";
$string = ltrim($string);
var_dump($string);
/app/98 Functions/index.php:11:string 'Hello There ' (length=12)

The ltrim() function removes the whitespace only from the left side. That’s why we’re left with a string length of 12.

<?php

// rtrim()
$string = " Hello There ";
$string = rtrim($string);
var_dump($string);
/app/98 Functions/index.php:16:string ' Hello There' (length=12)

The rtrim() function yields the same string length as ltrim(), but the last whitespace is eliminated this time, and not the first.

htmlspecialchars()

This is a very important function. It converts special characters into HTML entities. This helps in preventing your applications from accepting malicious code, like some JavaScript injections.

<?php

$html = '<script>alert("Hacked");</script>';
$sanitized = htmlspecialchars($html);
var_dump($sanitized);
/app/98 Functions/index.php:21:string '&lt;script&gt;alert(&quot;Hacked&quot;);&lt;/script&gt;' (length=55)

As you can see, < is transformed into &lt; and > is transformed into &gt;.

__call()

The call method allows for method overloading. You can make up whatever method name you’d like. I’ll show you what I mean.

<?php

class OverloadingTest
{
    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest();
$test->cantAccess("Dino Cajic");
We have a very simple class called OverloadingTest with a private method cantAccess. If we instantiate this class and call the cantAccess method, we get Fatal error.

But lets say that you’re trying to give access to that method if a user is authenticated. Let’s first “authenticate” the user.
<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
We now have a class, OverloadingTest, that now has a private property called $userHasAccess; it’s initialized to false. If we pass true to the constructor, it will change the property value to true. Great, but we still can’t access the cantAccess() private method. We can with our __call() method.
<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->cantAccess($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");

When we have a __call() method, it takes precedence over our regular methods, if they’re not accessible. So, if you call $test->cantAccess("Dino Cajic"), it actually calls the __call() method. The arguments $name and $args will receive the function name and argument respectively, which are cantAccess and Dino Cajic.

Our __call() method first checks to see if the userHasAccess and if he/she does, the cantAccess method is called and the $args[0] method is passed; $args is an array in the __call() method.

The output that we receive is as expected: Hello Dino Cajic.

I chose the same name as our private method, but I could have chosen anything, like randomFunction. Do you think it’ll work?

<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->cantAccess($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->randomFunction("Dino Cajic");

It does! So you can pass whatever you want. Let’s take a closer look at the __call() method by dumping the $name and $args parameters.

<?php

class OverloadingTest
{
    public function __call($name, $args)
    {
        var_dump($name);
        var_dump($args);
    }
}

$test = new OverloadingTest(true);
$test->randomFunction("Dino Cajic");
/app/98 Functions/Overloading.php:17:string 'randomFunction' (length=14)

/app/98 Functions/Overloading.php:18:
array (size=1)
  0 => string 'Dino Cajic' (length=10)

Just as expected: the $name is the function name randomFunction and $args is an array that contains the string we just passed Dino Cajic.

Let’s get back to our function:

$this->cantAccess instead of $this->randomFunction

<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->cantAccess($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
We can make a modification inside of our __call() method. We don’t have to call $this->cantAccess() inside of it; we can call $this->$name().
<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->$name($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
This can get super confusing. Let’s rename our first __call() argument from $name to $function_name.
<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($function_name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->$function_name($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name;
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
Lets zoom in on the __call() method now.

public function __call($function_name, $args)
{
    if ( $this->userHasAccess ) {
        $this->$function_name($args[0]);
    }
}
  • Once the object is instantiated, and we call the method cantAccess, it calls __call(“cantAccess”, array(“Dino Cajic”)).
  • Next, if the userHasAccess$this->$function_name is called. This is the same as $this->cantAccess once evaluated.
  • The first argument is from the $args array is passed, which is Dino Cajic$this->cantAccess(“DinoCajic”).
  • Since we’re in the same object, we have access to the private cantAccess method. It evaluates the expression and echos it out.

To solidify this concept. Let’s create another method and call it the exact same way.

<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($function_name, $args)
    {
        if ( $this->userHasAccess ) {
            $this->$function_name($args[0]);
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name . ". ";
    }

    private function cantAccessTwo(int $age)
    {
        echo "You are " . $age . " years old.";
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
$test->cantAccessTwo(25);
We added the cantAccessTwo method. We can’t access it normally, but we can access it via our __call() method. Let’s add one more for the sake of doing it. We’re going to pass a callback function that outputs the users email. This is going to be the function that we call:
<?php
//...

$test->randomCallbackFunction( function($email) {
    echo "Your email is " . $email;
}, "dino@example.com" );
If you need a refresher on callback functions, here you go:

What’s going on here?

  • Since we have __call() method implemented, we’re going to call it. The first argument is the randomCallbackFunction name. It gets attached to the $function_name parameter.
  • The second argument is an anonymous function that will apparently accept an email address and outputs that email. It gets attached to $args[0].
  • There is one additional argument passed: the string dino@example.com. It’s attached to $args[1].

We’ll need to modify our __call() method next. We first need to see if our method even exists. If it does, we’ll call it.

public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    }
}
This is great for our cantAccess method, but what about the randomCallbackFunction method? It doesn’t exist, so we skip it. The callback function is stored inside of our $args[0] element. Let’s assign it to a $callback variable to make it more explicit.
public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    } else {
        $callback = $args[0];
    }
}
The email address is stored in $args[1] so lets assign that to something more human readable.
public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    }

    $callback = $args[0];
    $callback_argument = $args[1];
}

public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    } else {
        $callback = $args[0];
        $callback_argument = $args[1];
    }
}
Great. Now we need to call it. But before we do, we need to make sure that it’s actually a function that’s callable. How do we do that? With the is_callable function.
public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    } else {
        $callback = $args[0];
        $callback_argument = $args[1];

        if (is_callable($callback)) {
            // Do Something if callable
        }
    }
}

If it is callable, we’ll call the callback and pass the $callback_argument to it, which is our dino@example.com email address.

public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    } else {
        $callback = $args[0];
        $callback_argument = $args[1];

        if (is_callable($callback)) {
            $callback($callback_argument);
        }
    }
}

The full code then looks like this:

<?php

class OverloadingTest
{
    private bool $userHasAccess = false;

    public function __construct($userHasAccess)
    {
        $this->userHasAccess = $userHasAccess;
    }

    public function __call($function_name, $args)
    {
        if ( $this->userHasAccess && method_exists($this, $function_name) ) {
            $this->$function_name($args[0]);
        } else {
            $callback = $args[0];
            $callback_argument = $args[1];

            if (is_callable($callback)) {
                $callback($callback_argument);
            }
        }
    }

    private function cantAccess(string $name)
    {
        echo "Hello " . $name . ". ";
    }

    private function cantAccessTwo(int $age)
    {
        echo "You are " . $age . " years old. ";
    }
}

$test = new OverloadingTest(true);
$test->cantAccess("Dino Cajic");
$test->cantAccessTwo(25);

$test->randomCallbackFunction( function($email) {
    echo "Your email is " . $email;
}, "dino@example.com" );

The result:

Hello Dino Cajic. You are 25 years old. Your email is dino@example.com

Last bit of cleanup. Let’s move our $callback_argument into the is_callable body. If it’s not callable, there’s not guarantee that we’re going to have argument at element $args[1].

public function __call($function_name, $args)
{
    if ( $this->userHasAccess && method_exists($this, $function_name) ) {
        $this->$function_name($args[0]);
    } else {
        $callback = $args[0];

        if (is_callable($callback)) {
            $callback_argument = $args[1];
            $callback($callback_argument);
        }
    }
}

Pretty interesting stuff. I’m going to leave it at this and continue with the remainder of our functions in the next article.

Carbon

POPULAR PHP LIBRARY FOR WORKING WITH DATES AND TIMES

PHP – P100: carbon

Carbon is a PHP dependency that extends the DateTime class. It has a lot more simplified interface and is extremely simple to use.

Built In Functions

Using trim() for input sanitization, htmlspecialchars() for security, and __call() for dynamic method handling, PHP empowers developers with a trio of versatile tools.

PHP – P101: built in functions

Through the last 100 PHP articles, we’ve used all sorts of built in functions. It’s time to collect them in one place, give a couple of examples, and add any additional ones that I might have missed.

Built In Functions

ENABLING PRECISE PATTERN MATCHING AND TEXT MANIPULATION

PHP – P102: BUILT IN FUNCTIONS PREG MATCH

A regular expression is just a sequence of characters that is used to search for specific patterns in a string.

Leave a Reply