Here’s some functions that PHP shouldn’t be without; but it is. No problem, we just write them in PHP. Maybe some day they can be re-written and compiled in C++ and integrated into the PHP language itself. Until then, here they are:
Click to view the highlighted sourcecode, or visit our download page. All example output shown is created by the actual PHP code shown.
swap(&$V1, &$V2)
This is a basic and simple function who’s alias is often exchange() or an abbreviation of. We chose swap because it’s shorter. All it does is swap or exchange the values of the two variables passed to it. It does not return any value. It offers a clean, uncluttered way of managing this need.
<?php $a="hello"; $b=1;
swap($a, $b);
echo "<pre>",var_dump($a, $b),"</pre>"; ?>
int(1) string(5) "hello"
lbreak_at($Llen, $terminator, $string, $EOLflag=TRUE, $LBr="\n", $atEnd=FALSE)
This takes a string and formats it with line breaks inserted after $terminator at most every $Llen characters. If $EOLflag=TRUE the $terminator is left, otherwise it is removed at the line’s end. The examples should make it clear:
<?php $s="Billy Anderson, Jack Phillips, James McGraw, Bobby Thomas, Howie Mandell";
echo "<pre>",
lbreak_at(40, ",", $s),"<br>\n",
lbreak_at(40, ",", $s, FALSE),"<br>\n",
lbreak_at(40, ", ", $s),"<br>\n",
lbreak_at(40, ", ", $s, FALSE),"<br>\n",
lbreak_at(40, ", ", $s, FALSE, ",\n"),"<br>\n",
lbreak_at(40, " ", $s),"<br>\n",
lbreak_at(40, ", ", $s, FALSE, ";\n", TRUE),"<br>\n",
"</pre>"; ?>
Billy Anderson, Jack Phillips, James McGraw, Bobby Thomas, Howie Mandell
Billy Anderson, Jack Phillips James McGraw, Bobby Thomas Howie Mandell
Billy Anderson, Jack Phillips, James McGraw, Bobby Thomas, Howie Mandell
Billy Anderson, Jack Phillips James McGraw, Bobby Thomas Howie Mandell
Billy Anderson, Jack Phillips, James McGraw, Bobby Thomas, Howie Mandell
Billy Anderson, Jack Phillips, James McGraw, Bobby Thomas, Howie Mandell
Billy Anderson, Jack Phillips; James McGraw, Bobby Thomas; Howie Mandell;
The RegulateText class
This class evolved from the simple function XHTMLencode. The need for a class derives from the desire to
encapsulate the $HTML_ENTS
array-table, while allowing two separate methods (functions) access to it;
best coding practices stress the rule of not polluting the global namespace.
The three class methods could have all been wrapped up into one (XHTMLencode) and included $HTML_ENTS
locally, but they are far more useful when separate.
XHTMLencode($S, $nl_to_br=TRUE, $allowJS=TRUE, $modulate_multispace='toEntities', $xhtml=TRUE, $retain_formatting=TRUE, $strip_CtrlChrs=TRUE, $charset='ISO-8859-1', $alignEnts=FALSE, $transform_nonstandard_Ents=FALSE, $tabspacing=8, $hardspace=' ', $inaTag=FALSE)
First off, note that this function has many options, all of which are, well, optional.
You may want to only change the default value of one of the last in the list (say $tabspacing
);
this can get hairy trying to keep up with all the options, their order in the list, their default values,
and which default value your code is modifying.
Therefore, this function is ready to accept options in two different formats or “ways”.
You can pass them in order, as in the function definition; or you can pass an array as the second value,
with the keys of the array corresponding to the options,
and the values of said keys becoming the values of the options.
The code below exemplifies these two optional formats:
$encodedString=RegulateText::XHTMLencode(
$partiallyEncodedString, FALSE, TRUE, 'toEntities', TRUE, TRUE, TRUE, 'ISO-8859-1', FALSE, FALSE, 4);
$encodedString=RegulateText::XHTMLencode(
$partiallyEncodedString, array('nl_to_br' => FALSE, 'tabspacing' => 4));
This is similar to the native PHP
htmlentities()
function,
but different.
It encodes all stray entities, but preserves valid (X)HTML markup including already encoded entities as well as
well formed tags.
It can also intelligently apply a <br> or a <br /> before any “new line” characters
in the text similar to the native PHP function
nl2br()
,
except taking into consideration whether the line break is inside an HTML tag, or between
opening and closing <pre> </pre> tags.
It can also make spacing in text ‘stick’ using the same logic. More on that below.
Plus it can convert all tag names and attributes to lower-case for XHTML validity.
This allows your data provided by knowledgeable users to include markup,
but makes sure other data is ready for validate-able (X)HTML pages.
Note it does not fully validate the (X)HTML markup, it only makes sure it is well formed;
i.e. only “legal” entities and tags will be preserved, but it does not
take into consideration whether the tag attributes are legal, only that they are “well formed”.
It also takes no consideration of whether a tag is opened and closed properly,
or whether a tag may be nested inside another.
You can control the tags that are allowed when you create an instance,
or after the instance is created through the HTML_tags
property.
When you create an instance, you can pass in an array of all the tag names you want allowed.
There are several static properties of the RegulateText Class that contain arrays of tag names (see the code).
These are broken into three groups: most HTML4 tags, restricted HTML4 tags and HTML5 tags,
as it usually makes no sense to allow <head> or <frame> tags in data output,
nor does it make sense to script forms and their controls.
Note the awesome power the <object> and <applet> tags have,
and allowing them to be scripted by data requires faith in your data.
In fact, this function opens up the data to allowing JavaScript™
to be embedded in web pages via data. Care should be taken on how this is implemented.
Set the $allowJS
flag to FALSE
if you are processing user input from a
form on the World Wide Web to be posted on your public pages for security reasons;
likewise, trim back the allowed tags to your liking. For example:
$regulator=New RegulateText(array('a', 'b', 'i'));
allows only anchor, bold, and italics tags.
If you don't pass in an array of tags when creating an instance, any value passed in is treated as a Boolean value.
If it's true, all tags will be accepted; if false, restricted tags will not be accepted.
If no value is passed in, the default action is to avoid restricted tags.
You may also access or pass in any of the static properties. For example:
$regulator=New RegulateText(RegulateText::$HTML4_tags);
By default, HTML browsers collapse multiple spaces and line breaks into a single space.
By default, this function converts multiple spaces to a
format;
and any space following a line break is also converted into a .
[You may choose any entity you want besides
with the $hardspace
option]
If you set $modulate_multispace
to TRUE
, multiple spaces will be collapsed to one.
Logically, if you set $modulate_multispace
to FALSE
,
multiple spaces will be left “as is”.
When $tabspacing
is a positive number, any tab characters are likewise expanded in a
format as multiple spaces; the number of spaces being equal to $tabspacing
.
Usually, you want to leave $inaTag=FALSE
; this is used internally,
but you may too if you have a reason.
If $xhtml=FALSE
, a much less stringent format is allowed in HTML tags.
If $strip_CtrlChrs=TRUE,
all control characters [ASCII 0-31 (00-1F in hexadecimal)]
will be removed, with the exception of carriage returns and tabs when $retain_formatting=TRUE
.
Note, though, that if $strip_CtrlChrs=FALSE
carriage returns and tabs will remain even if
$retain_formatting=FALSE
.
You may pass your own hardspace, maybe  
as that is the same as
.
And the $charset
is simply passed through to PHP's
htmlentities() function.
The options $alignEnts
and $transform_nonstandard_Ents
simply call the
sibling methods of the RegulateText
class. By default these auxiliary methods are not called;
pass in the values you want passed through. More on those methods below...
XML_entitiesAlign($S, $alignTo='numeric', $nonstandard_Ents='numeric')
This will convert all entities to either numeric format (when $alignTo='numeric'
),
or (when $alignTo='mnemonic'
etc...) to textual format if such exists for that entity.
It will avoid converting nonstandard Entities to 'mnemonic' if you specify them separately as
'numeric'; but as the inverse is illogical, it will not convert nonstandard Entities to 'mnemonic'
if you specify $alignTo='numeric'
.
If you pass an array in as $nonstandard_Ents
(instead of the default string-based-flag format)
then the array will be used as the Entity Table (for use with custom XML docs), instead of the default
$HTML_ENTS
.
transform_nonstandard_entities($S, $flag='numeric')
This straightforward function simply takes your string and transforms the three “nonstandard” Entities (' ['] ‹ [‹] › [›]) either to/from 'numeric' to/from 'mnemonic'. It will transform both decimal and hexadecimal numericals to mnemonic, but only from mnemonic to decimal. Technically, ' is only allowed in XHTML documents, not in HTML. The other two are widely supported by modern browsers, yet they are still considered “nonstandard” and should therefore be converted to numeric format for proper validation in many cases. For readability purposes though, to 'mnemonic' was included as a bonus.
This class (RegulateText) and its methods are all best exemplified off-page with a working model. Here’s the highlighted demo sourcecode, and the working demo.
array_is_similar($A1, $A2, &$Adif="")
This function compares the two arrays passed to it, and returns TRUE if they have all the same values, FALSE if not. The keys do NOT have to match in any way. The values that are different can be passed back in the optional third parameter, but due to the way array_merge() works, this is not completely reliable with non-numeric indexes.
array_not_similar($A1, $A2)
This function returns an array of all the values in the two given arrays that are unique to one array in the pair, or NULL if they have all the same values. The keys do NOT have to match in any way. Due to the way array_merge() works, this is not completely reliable with non-numeric indexes.
array_equals(&$A1, &$A2, $IdentFLAG=FALSE)
This function looks deep into both arrays passed into it and returns TRUE if they have all the same keys with the same values, and FALSE otherwise. If you pass TRUE as the third value ($IdentFLAG), the arrays will be modified so all EQUAL values are set to NULL, leaving the rest identified.
casei_in_array($VALUE, $A)
If the string passed in $VALUE is a case-insensitive match to one of the strings in the array $A, this function returns the string from the array that matched or TRUE if the string evaluates to FALSE, or FALSE if no match is found.
array_ikey_exists($KEY, $A)
If the string passed in $KEY is a case-insensitive match to one of the keys in the array $A, this function returns the key from the array that matched, or FALSE if no match is found.
preg_key_grep($A, $preg, $KeepKey=FALSE)
This function is similar to preg_grep(), except it does a Perl-compatible Regular Expression check on the keys of the array passed to it, then returns an array of those values whose keys matched the check. The array returned is numerically indexed, unless you pass TRUE as the third value ($KeepKey) which preserves the original keys.
is_iterateable($var)
This function returns TRUE if the variable $var passed to it can be iterated using
foreach ($var as $arrayValue)
or FALSE if not.
Note it is defaulted to work only with PHP 5.3 and above, but you can comment that part out if needed.
array_multijunction($new_keys, $A1, $A2 [, $A3, ... $A10, ... $¿allKeys=FALSE])
This takes any number of arrays passed to it (minimum of 3); the first is the keys for the data, the rest are data. It creates one new array combining the others. It is the complement of the next function, array_subkey(). If the last value passed ($¿allKeys) is passed a boolean TRUE (this must be boolean), all keys in all arrays will be used to create the new array; otherwise the default is that the new array only contains keys found in all given data arrays. A couple examples should make all this clear:
<?php
$arr1=array('first' => "Jimmy", 'second' => "Jonny", 'third' => "Roger", 'forth' => "Tim");
$arr2=array('first' => "Hendrix", 'second' => "Cash", 'third' => "Waters", 'fifth' => "GaGa");
$arr3=array('first' => "guitar", 'second' => "guitar", 'third' => "bass", 'sixth' => "drums");
$keys=array("first-name", "last-name", "instrument");
echo "<pre>",var_dump(
array_multijunction($keys, $arr1, $arr2, $arr3),
"====================",
array_multijunction($keys, $arr1, $arr2, $arr3, TRUE) ),
"</pre>"; ?>
array(3) { ["first"]=> array(3) { ["first-name"]=> string(5) "Jimmy" ["last-name"]=> string(7) "Hendrix" ["instrument"]=> string(6) "guitar" } ["second"]=> array(3) { ["first-name"]=> string(5) "Jonny" ["last-name"]=> string(4) "Cash" ["instrument"]=> string(6) "guitar" } ["third"]=> array(3) { ["first-name"]=> string(5) "Roger" ["last-name"]=> string(6) "Waters" ["instrument"]=> string(4) "bass" } } string(21) "=====================" array(6) { ["first"]=> array(3) { ["first-name"]=> string(5) "Jimmy" ["last-name"]=> string(7) "Hendrix" ["instrument"]=> string(6) "guitar" } ["second"]=> array(3) { ["first-name"]=> string(5) "Jonny" ["last-name"]=> string(4) "Cash" ["instrument"]=> string(6) "guitar" } ["third"]=> array(3) { ["first-name"]=> string(5) "Roger" ["last-name"]=> string(6) "Waters" ["instrument"]=> string(4) "bass" } ["forth"]=> array(1) { ["first-name"]=> string(3) "Tim" } ["fifth"]=> array(1) { ["last-name"]=> string(4) "GaGa" } ["sixth"]=> array(1) { ["instrument"]=> string(5) "drums" } }
array_subkey($A, $indxLevel, $IDkey, $KeepKey=FALSE)
array_subkey¤5·3($A, $indxLevel, $IDkey, $KeepTree=FALSE)
These two sibling functions are the complement of array_multijunction(). The first, array_subkey(), is the little brother of the extraordinary array_subkey¤5·3(), but it still puts a simple-to-use tool in your hand that is very powerful. The most simple way to state its use is to say it returns a column of data from a row-based array. array_subkey¤5·3() can return many columns at once, re-key them, and even dig into class-objects; I call it the Jedi-powered Cuisinart of array functions :)
array_subkey¤5·3() is best suited for PHP 5.3 and up, but it can be adapted easily (see the internal comments in the sourcecode) to earlier versions. With PHP 5.3, you can pass closures as parameters defining what “keys” to return (in fact the closure-function can do anything you need it to do!). With versions of PHP that support Object Oriented Class Methods, you can pass instances of your class with a method called filter that works the same as passing a closure in PHP 5.3. With earlier versions, you pass a string which refers to a function named in your code; trouble begins when a key in your array has the same string-name as a function in your code. If you can guarantee to avoid this by either controlling the key names, or verifying ahead that there is no conflict, then array_subkey¤5·3() will work with PHP without Classes or Closures.
Both are designed to work with arrays of arrays of arrays..... as well as arrays of class-objects with properties that are arrays or class-objects ...... With array_subkey() you have simple access to a key or keys at your choice of “level” in the array passed into. Note that levels start with (1), not (0). Any number to the zero power is the singularity; that is to say an array at level (0) is the complete array. They both allow you to “pull out” the data you need buried deep in a multi-dimensional array. With array_subkey¤5·3(), you can filter through every dimension to pinpoint and retrieve exactly what you need at multiple levels, if you set up $IDkey with the right filter. Again, this is all best explained with examples. Below are examples using array_subkey(). Examples of array_subkey¤5·3() are off-page;. here’s the highlighted demo sourcecode and the demo output
<?php $arr=array(
'dancing_singer' => array('firstname' => "Donnie", 'lastname' => "Osman", 'job' => "glitter-glammer"),
'actor_director' => array('firstname' => "Ronnie", 'lastname' => "Howard", 'job' => "societal advisoure"),
'guitarist_songwriter' => array('firstname' => "George", 'lastname' => "Harrison", 'job' => "musician extraordinaire"));
echo "<pre>",var_dump(
array_subkey($arr, 2, "firstname"),
array_subkey($arr, 2, "firstname", TRUE),
array_subkey($arr, 2, array("firstname", "job")),
array_subkey($arr, 2, array("firstname", "job"), TRUE)),
"</pre>";
?>
array(3) { [0]=> string(6) "Donnie" [1]=> string(6) "Ronnie" [2]=> string(6) "George" } array(3) { ["dancing_singer"]=> string(6) "Donnie" ["actor_director"]=> string(6) "Ronnie" ["guitarist_songwriter"]=> string(6) "George" } array(3) { [0]=> array(2) { [0]=> string(6) "Donnie" [1]=> string(15) "glitter-glammer" } [1]=> array(2) { [0]=> string(6) "Ronnie" [1]=> string(18) "societal advisoure" } [2]=> array(2) { [0]=> string(6) "George" [1]=> string(20) "musician extrodinare" } } array(3) { ["dancing_singer"]=> array(2) { [0]=> string(6) "Donnie" [1]=> string(15) "glitter-glammer" } ["actor_director"]=> array(2) { [0]=> string(6) "Ronnie" [1]=> string(18) "societal advisoure" } ["guitarist_songwriter"]=> array(2) { [0]=> string(6) "George" [1]=> string(20) "musician extrodinare" } }