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 '<script>alert("Hacked");</script>' (length=55)
As you can see, <
is transformed into <
and >
is transformed into >
.
__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");
OverloadingTest
with a private method cantAccess
. If we instantiate this class and call the cantAccess
method, we get Fatal error.<?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");
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");
$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");
__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 isDino 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);
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" );
What’s going on here?
- Since we have
__call()
method implemented, we’re going to call it. The first argument is therandomCallbackFunction
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]);
}
}
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];
}
}
$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];
}
}
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.
POPULAR PHP LIBRARY FOR WORKING WITH DATES AND TIMES
Carbon is a PHP dependency that extends the DateTime class. It has a lot more simplified interface and is extremely simple to use.
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.
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.