Robert Eisele
Systems Engineer, Architect and DBA

PHP Enhancement

I packed a lot of PHP functions I've developed in the past together to a new extension, which answers to the name Infusion. The functions are optimized to deliver the result as fast as possible. I would call it stable, because I use most of them in production for years.

So let's come further; what's about Infusion. Infusion is only a bunch of new functions, I've missed in the PHP core - and maybe someone else will find it usefull too. I want to give little example snippets here to let you imagine what you can do with these functions. Maybe some functions are similar to still existing ones of PHP, than treat it under the view of faster development.

So how would you return a string like this when you have a timestamp or a number of seconds: "5 minutes and 23 seconds ago"? You would say, break the time down to a passable size and return it anyhow. I've thought a long time about this problem and came to the solution, that the best way in terms of internationality and simplicity is the use of two functions. One for the calculation and one for the formatting.

<?php

echo time_chop(500); // echos 8 {12} {14} 20 {13}

?>

What can we do with this output? This output is a format string for strmap(). So let's create an array and fill strmap() with these two values:

<?php

$L_timechop['de'] = array('einem Jahr','einem Monat','einer Woche','einem Tag','einer Stunde','einer Minute','einer Sekunde','Jahren','Monaten','Wochen','Tagen','Stunden','Minuten','Sekunden','und');
$L_timechop['en'] = array(...);
echo strmap('8 {12} {14} 20 {13}', $L_timechop['de']); // echos 8 Minuten und 20 Sekunden

?>

In german you would say "vor 8 Minuten und 20 Sekunden"; in english you append the "ago" to the end. Maybe you have a language, which does not fit in that format, then you can return the result as an array and format by yourself. It's also possible to cut the number of entities or to specify the units you really want. The calculation is adjusted like this:

<?php

print_r(time_chop(time() - 5000, 'hs', true));

/*
Array
(
	[hours] => 1
	[seconds] => 1400
)
*/

?>

When we just focus on data breakings, we can proceed with number_chop(). This function is similar to the time_chop() function, but gives the possebility to define an array in what parts you want to split the number. For example, you want to say what money you need, to give it as large as possible - which is a good task for a cash terminal. Let's say we want split the amount of 3452.87€:

<?php

// Units
$units = array(
1, 2, 5, 10, 20, 50, 100,
200, 500, 1000, 2000, 5000,
10000, 20000, 50000
);

$num = 3452.87;

// Needed as we can handle integers only
$num*= 10;

print_r(number_chop($num, $units));
/*
Array
(
	[20000] => 1
	[10000] => 1
	[2000] => 2
	[500] => 1
	[20] => 1
	[5] => 1
	[2] => 1
	[1] => 1
)
*/

?>

The key of the resulting array is the number passed by the array and the value of the associative array is the count of occurrences. To give a seperated example for strmap() I only want to provide this little snippet, which explains the use really easy:

<?php

$arr = array('name' => 'Robert');
echo strmap('hi {name}...', $arr); // echos 'hi robert...'

?>

Another powerful string function is xsprintf(). Ordinarily I use this function as a SQL parser. This offers the possebility to avoid 100% SQL-Injections. The idea is quite the same like parameter binding but uses the normal API and you can transform the data before it will send to the server. My example here is quite a little different to show you, how you could use this function as a inline parameter handler. Look over this little example, where we use a fictional Tag class:

<?php

$tag = new Tag;
$tag->setMask('<a href="/tag/#u/" style="font-size:#25spx">#t</a> ');
$tag->getCloud();

?>

On the callback side, you have to handle the parameter "u" for the url token, "t" for the tag label and "s" respectively "25s" for the font size with the optional max value.

The next functions are more mathematically and only return the value as a number, so I will summarize them here in one big block and only provide the result as a comment after the statement:

<?php

echo sigfig(123.45, 6); // 123.45
echo sigfig(123.45, 5); // 123.45
echo sigfig(123.45, 4); // 123.5
echo sigfig(123.45, 3); // 123
echo sigfig(123.45, 2); // 120
echo sigfig(123.45, 1); // 100
echo sigfig(123.45, 0); // 0

##

echo bound(25, 0, 20); // 20
echo bound(-4, 0, 20); // 0
echo bound(17, 0, 20); // 17

##

echo limit(25, 20); // 20
echo limit(-4, 20); // -4

##

echo checksum(456); // 15

##

echo bround(44, 5)); // 45
echo bround(44, 2)); // 46

##

echo xround(33); // 100
echo xround(100); // 100

##

echo bround(44, 5); // 45
echo bround(44, 2); // 46

##

echo typeof(33); // 1

?>

The last examples cover the binary functions of PHP Infusion. I think you need a basic understanding of how numbers are represented inside of the machine to use them. I will only give you the result like in the examples above. If you want to understand the background see here or read elsewhere.

<?php

$n = 4;
var_dump(isbit($n, 2)); // true

$n = 3;
var_dump(isbit($n, 2)); // false

##

$n = 3;
echo setbit($n, 3); // 11

##

$n = 3;
echo invbit($n, 3); // 11
echo invbit(11, 3); // 3

##

echo numbit(14); // 3

##

echo msbit(5); // 3

?>

If you need more information about the parameters or want a complete list of all functions

This function is really hard WIP, which does not mean, that it is unstable but I'll bring updates to this extension as soon as I can call it stable in my development environment. If you really need such functionality in PHP and think, that it is a good improvement for this collection, feel free to contact me.

You might also be interested in the following

1 Comment on „PHP Enhancement”

mike

These are pretty neat. I've actually got somewhat of a time_chop() equivalent but in PHP userspace. Calculating the duration in C would be more efficient and it's always nice to have a non-userland and consistent function available. I have various versions of the code to slice up seconds into years/minutes/hours/etc.

The coolest function out of this I see is strmap - token-based string functions is what is used in localization and in places like Drupal and such, I could see something like this benefitting a lot of places...

A couple recommendations:

1) The OCD in me says "why mix functionfoo and function_bar function names" - I know it's how PHP does it, and it's one of the annoyances is the inconsistency where some functions have underscores and some are all one word.

2) Give a third param to strcut() to tell it to not cut on a word. So if TRUE, it will go backwards from say, 80 characters, until it finds a space equivalent character. Or Perhaps add a 4th param with default of ' ' that is the character it is allowed to cut on.

Something like this:
strcut(string $string, int $maxlength, bool $force = false, string $delimiter = ' ')

Similar idea with the truncate() function (why not call it str_truncate then, or strtruncate. It's a string fcnction after all.

Looking at this more, what is the difference between strcut() and substr()? Seems like you can do the exact same thing?

strcut($string, 80) = substr($string, 0, 80)

Unless I'm missing something?

I would submit this suite of functions for formal PHP review/inclusion!

 

Sorry, comments are closed for this article. Contact me if you have an inventive contribution.