M0UNTAIN 0F C0DE

Weird PHP Functions

PHP

I wondered if there was a way to get all the internal functions in PHP. Turns out, kind of ironically, that there is a function for doing just that: get_defined_functions(). For PHP 8.4 with minimal extensions that list contains 1,555 entries.

There are some functions on there that I had never come across in over 15 years of writing PHP, I'd like to highlight some.

_()

Yep, just a single underscore. It is an alias of the gettext() function which appears to be to do with localisation. It makes sense now why Laravel uses the __() function for localisation.

https://www.php.net/manual/en/function.gettext.php


chop()

Another alias, this time for rtrim().

https://www.php.net/manual/en/function.chop.php


mb_scrub()

Replaces ill formed byte sequences with ?

https://www.php.net/manual/en/function.mb-scrub.php


readdir()

Allows for reading a list of file names from a directory.

$dh = opendir($dir);

while (($file = readdir($dh)) !== false) {
    echo "filename: " . $file;
}

https://www.php.net/manual/en/function.opendir.php


count_chars()

A weird function which given a string returns an array containing the number of times each character (byte) appears.

var_export(count_chars('I am a teeeeeapot', 1));
array (
  32 => 3,
  73 => 1,
  97 => 3,
  101 => 5,
  109 => 1,
  111 => 1,
  112 => 1,
  116 => 2,
)​

The second argument is a magic number which changes the returned values. Dial 3 if you want all the unique characters:

var_export(count_chars('I am a teeeeeapot', 3));
' Iaemopt'​

https://www.php.net/manual/en/function.count-chars.php


disk_free_space()

Want to know how much free space your disk has? PHP's got you covered.

var_export(disk_free_space('/'));
22422302720.0​

There is also the complementary disk_total_space()

https://www.php.net/manual/en/function.disk-free-space.php


fnmatch()

A string matching function, similar to preg_match() but uses pattern matching common in shells.

fnmatch("backup_[0-9]*.*", 'backup_2025-01-01.gz'); // true

https://www.php.net/manual/en/function.fnmatch.php


frenchtojd()

Converts a date from the French Republican Calendar to a Julian Day Count These routines only convert dates in years 1 through 14 (Gregorian dates 22 September 1792 through 22 September 1806). This more than covers the period when the calendar was in use.

Wat?

frenchtojd(month: 10, day: 2, year: 4); // 2377207

https://www.php.net/manual/en/function.frenchtojd.php


get_mangled_object_vars()

As far as I can tell this function returns an array of an objects properties and values, including protected and private ones. Not sure what's mangled about them?

class Post
{
    public string $url = 'post-about-a-thing';
    protected int $wordCount = 1435;
    private bool $isPublished = false;
}

$instance = new Post();

var_export(get_mangled_object_vars($instance));
array (
  'url' => 'post-about-a-thing',
  '' . "\0" . '*' . "\0" . 'wordCount' => 1435,
  '' . "\0" . 'Post' . "\0" . 'isPublished' => false,
)​

https://www.php.net/manual/en/function.get_mangled_object_vars.php


get_meta_tags()

This one actually seems useful! It parses an HTML file and extracts the <link> tags and their values.

var_export(get_meta_tags('https://mountainofcode.co.uk'));
array (
  'description' => 'Mountain of code is a collection of web and dev ops related projects mixed with a little hacking and tinkering.',
  'viewport' => 'width=device-width, initial-scale=1',
)

https://www.php.net/manual/en/function.get-meta-tags.php


grapheme_str_split()

I believe this is fairly new. Used for correctly splitting a string which contains multibyte sequences, for example emoji:

grapheme_str_split('emoji: πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§'); // ['e', 'm', 'o', 'j', 'i', ':', ' ', 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§']
str_split('emoji: πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§'); // Error: Unexpected encoding - UTF-8 or ASCII was expected

https://www.php.net/manual/en/function.grapheme-strrpos.php


hypot()

A trigonometry shortcut. Calculates the hypotenuse given the lengths of opposite and adjacent sides of a right angle triangle.

hypot(3, 4); // 5

https://www.php.net/manual/en/function.hypot.php


phpcredits()

The current credits for the creators/maintainers/etc for PHP.

https://www.php.net/manual/en/function.phpcredits.php


str_increment()

It's not well known, or really expected, that strings can be (in|de)cremented. The only genuine use I have found for it is spreadsheet columns.

$column = 'AA';
str_increment($column); // 'AB'

This works with the regular (in|de)crement syntax too. A notable difference is that the function does not modify the variable, it returns a new value;

$column = 'AA';
str_increment($column); // 'AB'
$column; // 'AA';

// vs

$column = 'AA';
++$column; // 'AB'

https://www.php.net/manual/en/function.str-increment.php


strspn()

This will count the longest run of characters which match a given set, starting from the beginning of the given string.

Not sure what this would be useful for.. You could see how many digits a string started with for example:

strspn('000somestring12345', '0123456789'); // 3

https://www.php.net/manual/en/function.strspn.php


strpbrk()

This will return part of the given string starting with the first occurrence of any provided characters.

strpbrk('0243323-bdsadbhe-ghref', '-'); // 'bdsadbhe-ghref'

https://www.php.net/manual/en/function.strpbrk.php


time_sleep_until()

Pretty obvious functionality, like sleep but with takes an absolute time rather than a relative one, like sleep() expects. It also supports microseconds.

https://www.php.net/manual/en/function.time-sleep-until.php


wordwrap()

I'm sure I've written a user-land implementation of this function before. It will add a wrapping string every n characters. By default, it will split on spaces, but it can split in the middle of words too.

In the case of HTML it is always best to allow CSS to do the wrapping but could be useful in a CLI context.

wordwrap(
    string: 'The quick brown fox jumped over the lazy dog.',
    width: 20,
    break: '<br>',
); // The quick brown fox<br>jumped over the lazy<br>dog

https://www.php.net/manual/en/function.wordwrap.php