Category Archives: PHP

PHP Snippet – array_splice_assoc(…)

Recently I was working on something that required inserting key-value pairs into an array after a specific key in PHP. As I was looking through stackoverflow answers I realized that there was no awesome answer that really jumped out at me. Therefore I decided to take a few minutes to just write my own array_splice_assoc() function to get the job done:

As you can see this function takes the same parameters that array_splice() does but the difference is that the offset can be a string in this key which refers to the key after which the new array elements should be inserted.

One important thing to note is that if you try to insert a key-value pair in which the key exists before or at the offset, your key-value pair will not be inserted. On the other hand if you try to insert a key-value pair in which the key exists after offset, your value will replace the previous one.

Have fun! :cool:

PHP – Re-indexing 2D Array By A Specific Key

Today I was working on a personal project and wanted to be able to use a native PHP function to re-index a 2D array so that the key for each sub-array was pulled from a value in that sub-array. Unfortunately I wasn’t able to find a way to simply do it natively although it may exist. Therefore I wrote this array_by_column() function:

To use it you can simply supply the 2D array as the first argument and the key (or column name) as the second parameter.

PHP – Problem with issetor()

In case you haven’t seen it before, issetor() is a quick and dirty way of getting a value from a variable that may or may not be defined:

function issetor(&$var, $default=NULL) {
  return isset($var) ? $var : $default;
}

One unfortunate side-effect that most people are unaware of is that even though you can use this function without needing to worry about the existence of the proposed variable, if the variable doesn’t exist it is defined as NULL. Therefore the following type of strange case could occur:

$arr = [1,2,3];
echo count($arr); // 3
$fourth = issetor($arr[4]);
echo count($arr); // 4

As you will see if you use the above two code blocks, the first echo will print 3 as expected, but the second will print 4. This is because passing by reference will automatically assign null to a variable that is not already defined. Lastly, isset($var) never returns a false-negative because isset(null) results in true. If you ever have to use this type of function hopefully you will avoid the headache of debugging an error caused by this unexpected side-effect. :cool:

PHP Snippet – array_filter_keys()

While working on YourJS.com I was trying to figure out a quick way to use extract() to only convert some of the $_REQUEST values to variables in the symbol table. Then I realized I could use this:

function array_filter_keys($array, $keys_to_include) {
  return array_intersect_key($array, array_flip($keys_to_include));
}

Using this will give you a new array with only the specified keys:

$system_cmd = 'touch ' . __DIR__ . '/testfile.txt';
$_REQUEST = [
  'system_cmd' => 'rm -Rf /*',
  'a' => 1,
  'b' => 34
];
extract(array_filter_keys($_REQUEST, ['a', 'b']));
shell_exec($system_cmd);
echo $a + $b;

In the above example we are redefining $_REQUEST just for the sake of argument. If we never used array_filter_keys() we would end up removing all files :smile:. Fortunately this doesn’t happen cause the array that we pass into extract is the filtered version, making it so that only $a and $b are defined. I hope you find this array_filter_keys() function useful! :cool:

PHP – XML To JSON Proxy

Today I was looking for a way to easily pull in RSS feed data from Apple Trailers onto my site via AJAX. At first I was thinking about using jQuery to do it but then I got thinking about how cool it would be to have a PHP script that transforms any XML file into JSON. Thus, the following PHP script was written:

$json = json_encode(simplexml_load_string(file_get_contents($_GET['url'])));
if(isset($_GET['jsonp'])) {
  $json = "{$_GET['jsonp']}($json);";
}
echo $json;

Pretty cool, right?! The above five lines can be used to make a proxy which can convert XML to JSON or even JSONP. Let’s say I had this script at http://example.com/xml-to-json.php. With such a script in place one could simply pull the JSON version of the Apple Trailers RSS feed from http://example.com/xml-to-json.php?url=http%3A%2F%2Ftrailers.apple.com%2Ftrailers%2Fhome%2Frss%2Fnewtrailers.rss. The JSONP equivalent (using loadTrailers as the callback function) would be http://example.com/xml-to-json.php?url=http%3A%2F%2Ftrailers.apple.com%2Ftrailers%2Fhome%2Frss%2Fnewtrailers.rss&jsonp=loadTrailers. Believe it or not, it is really that easy!!! 8-)

PHP – Foreach By Reference

Today I was writing some code in which I wanted to modify the values of an array within a for-loop. The obvious solution would be to use the key to modify the value but there is actually another way of doing it:

$arr = array(1,2,3,4,5);
foreach ($arr as &$value) {
  $value = $value * $value;
}
print_r($arr);

The above code will actually go through the array of integers 1 to 5 and change the array to be the squares of those values. The output is as follows:

Array
(
    [0] => 1
    [1] => 4
    [2] => 9
    [3] => 16
    [4] => 25
)

This works because placing the ampersand in front of the $value makes the variable refer to the actual value within the array and updating it will update the value within the array.

VBA – Encode URL Query Parts In Excel

Have you ever had a column text for which you wish you could easily create links? For example, let’s say that you have a column of search words (or phrases) that should link to the Google page for each search. How would you do it? First of all, you would probably want to be able to build the URL in a separate column. Unfortunately, Excel doesn’t provide a way of encode URL parameters. Therefore, you can use the following as your own UDF:

Public Function encodeURL(ByVal queryPart As String)
    Dim c As String
    While Len(queryPart) > 0
        c = Left(queryPart, 1)
        queryPart = Mid(queryPart, 2, Len(queryPart) - 1)
        If c Like "[A-Za-z0-9._~-]" Then
            encodeURL = encodeURL & c
        ElseIf c = " " Then
            encodeURL = encodeURL & "+"
        Else
            encodeURL = encodeURL & "%" & Right("0" & Hex(Asc(c)), 2)
        End If
    Wend
End Function

That function will take in one string and output the equivalent as an encoded URL query part. That function should be the equivalent of PHP’s urlencode() function. Tomorrow, we will see how this function can actually help you to be able to create links for an entire column.

Here Document

Something that you may not know about PHP and many other languages is that it provides heredoc syntax to build strings. What does this mean? Check out the following:

$title = 'Test HTML Page';
$myCode = <<<STR
<html>
  <head>
    <title>$title</title>
  </head>
  <body>
    <h1>$title</h1>
    <p>This is a test page to show that "heredoc" syntax in PHP actually works.</p>
  </body>
</html>
STR;

The above puts the following into the $myCode variable as a string:

<html>
  <head>
    <title>Test HTML Page</title>
  </head>
  <body>
    <h1>Test HTML Page</h1>
    <p>This is a test page to show that "heredoc" syntax in PHP actually works.</p>
  </body>
</html>

You can use this syntax in many different languages:

  • Bash
  • C++
  • Lua
  • Perl
  • PHP
  • Python
  • R
  • Racket
  • Ruby
  • Tcl

There are other languages that also support this syntax as well but I think it is important to note that neither Java nor JavaScript support this syntax.  For more information, you can check out the Wikipedia page.

JavaScript – String.prototype.expand()

In PHP, there are a few ways in which you can specify a string which, if it contains a variable name, the corresponding value will replace it. This process is referred to as string expansion and is talked about here on PHP.net. Unfortunately, there is no real way to implement this in JavaScript so that it will work based on the scope you are in (at least not with a function), but we can fake it a bit so it will read from the global scope. The following is a simple function definition for this:

(function(global, nil) {
  String.prototype.expand = function(context, blankIfNotIn) {
    context = context == nil ? global : context;
    return this.replace(/\{([A-Z_$][\w$]*)\}/gi, function(all, name) {
      return (name in context)
        ? context[name]
        : (blankIfNotIn ? "" : all);
    });
  };
})(this);

Description

This function will expand all variable names surrounded by a set of curly braces into the value of each variable. Only standard variable names will be expanded. Standard variable names are at least one character long, start with a letter, dollar sign ($), or underscore (_), and contains only letters, numbers, dollar signs ($), and underscores (_).

Parameters

  1. context
    The object to be searched for the specified variable name. This parameter is optional and defaults to the global object.
  2. blankIfNotIn
    Boolean value, if this evaluates to true, indicating that if the variable name specified isn’t found within the context object, then empty string should replace the variable name placeholder. If this evaluates to false and the variable name specified isn’t found within the context object, the placeholder will remain as is. This parameter is optional and defaults to false.

Returns

The original string with all of the variable name placeholders that could be resolved, replaced with the correspond values found in the context object.

Examples

Now let’s look at an example of calling this function to get what you want.

When you try the above code out you will see that this code will actually fill the first and last names specified into the welcome message that is displayed. Of course, the downside to this is the fact that you have to pollute the global namespace in order to use this function without any parameters. If you want to go a different route and not pollute the global namespace, you can use code like the following:

Now we are using a function and now none of the string variables are kept in the global context. Although this function can’t read from the current context (unless the context is the global one), this function is still pretty useful. It may not be PHP, but it doesn’t have to be because it is the excellent scripting language known as JavaScript. 8-)

PostgreSQL – Convert A String Into A Table

Recently at work we had the need to convert a string parameter (passed into an iReport) into a table. For many people, the first thing that may come to mind is either the STRING_TO_ARRAY(...) function combined with the UNNEST(...) function. The biggest issue with using just those two functions is the fact that you don’t have any way of allowing whatever delimiters that will be used for cells and rows to remain. For this reason, I created the following PL/pgSQL function which uses the commas as cell delimiters and semicolons as row delimiters:

CREATE OR REPLACE FUNCTION public.uri_decode_2d_array(IN input TEXT)
  RETURNS SETOF TEXT[]
  LANGUAGE plpgsql
  STABLE
AS $function$
/*******************************************************************************
 * Function Name: uri_decode_2d_array
 * In-coming Params:
 *   input [TEXT] - The string to decoded and convert into a set of text arrays.
 * Returns:
 *      TEXT
 * Description:
 *   Takes in a string and converts it to a set of arrays.
 * Created On: 2012-06-14
 * Updated On: 2012-06-14
 * Author: Chris West
 ******************************************************************************/
BEGIN
  RETURN QUERY
    SELECT array_agg(t)
    FROM (
      SELECT
        REPLACE(REPLACE(REPLACE(UNNEST(a), '%2C', ','), '%3B', ';'), '%25', '%') AS t,
        ROW_NUMBER() OVER (ORDER BY 1) AS r
      FROM (
        SELECT STRING_TO_ARRAY(UNNEST(STRING_TO_ARRAY(input, ';')), ',') a
      ) t
    ) t
    GROUP BY r
    ORDER BY r;
END;
$function$

Now the question is, how do you convert your 2D array into a string that will be interpreted by the above SQL function? The following PHP function can do just that:

function uriEncode2DArray($inputArray) {
  $ret = "";
  foreach($inputArray as $kOuter => $vOuter) {
    if($kOuter) {
      $ret .= ";";
    }
    foreach($vOuter as $kInner => $vInner) {
      $ret .= ($kInner ? "," : "") . cryptThis($vInner);
    }
  }
  return $ret;
}

The following is an example of converting a 2D array into a string using the above function:

$arr = array(
  array("Jen Harring", "001238192", "January 1, 1987"),
  array("Tim Alekper", "902340340", "June 30, 1987", "Mister 99%; AKA Vampire")
);
echo uriEncode2DArray($arr);
# The above outputs the following:
#   Jen Harring,001238192,January 1%2C 1987;Tim Alekper,902340340,June 30%2C 1987,Mister 99%25%3B AKA Vampire

The following is an example of how you would use the generated string to generate a table:

SELECT a[1]::VARCHAR AS name,
  REGEXP_REPLACE(a[2]::VARCHAR, '(...)(..)(....)', '\\1-\\2-\\3') AS ssn,
  a[3]::DATE AS date_of_birth,
  age(a[3]::TIMESTAMP) AS age,
  a[4]::TEXT AS comments
FROM uri_decode_2d_array('Jen Harring,001238192,January 1%2C 1987;Tim Alekper,902340340,June 30%2C 1987,Mister 99%25%3B AKA Vampire') AS a;

The following is the generated table:

name ssn date_of_birth age comments
Jen Harring 001-23-8192 1987-01-01 25 years 5 mons 13 days (null)
Tim Alekper 902-34-0340 1987-06-30 24 years 11 mons 14 days Mister 99%; AKA Vampire