PHP Empty Multidimensional Arrays

Discovered today that running empty() on a multidimensional array returns false.

http://forums.phpfreaks.com/topic/183410-checking-if-multidimensional-array-is-empty/

To get around this, I propose using array_filter on the multidimensional array first.  I’m betting this will not work for an array within an array within an array, but it seems to work fine for an array within an array.

So:

empty( array_filter( $multidim_array ) )

Preventing Post Resubmission

http://stackoverflow.com/questions/11377259/form-is-resubmitted-when-the-back-button-is-pressed

The above link had some good links inside.  I’ve attached them below:

http://stackoverflow.com/questions/3923904/preventing-form-resubmission

http://stackoverflow.com/questions/660329/prevent-back-button-from-showing-post-confirmation-alert

 

The following link contains info on how to do it server side.

http://bjw.co.nz/developer/general/75-how-to-prevent-form-resubmission

Debugging relative links in php

First I should mention that I’ve gotten good results when using the get_cwd() function.  With it, I can tell what directory I am starting from, and from there build the appropriate relative paths.

It’s simple to use.

echo getcwd();

Run the script, and you’ll know where your starting point is.

That said, beware of the register_shutdown_function().  I noticed the get_cwd() result changed while inside of this function.  I found a link with a workaround, but the gist of it is that the working directory of the script can change.

http://stackoverflow.com/questions/10861606/write-to-file-with-register-shutdown-function

Here’s a sample you can use:

<?php

        echo "Using Dir: " . __DIR__;
        echo "\n\n";
        echo "Using Get Current Working Directory: " . getcwd();
        echo "\n\n";
        echo "Using Get Include Path: " . get_include_path();
        echo "\n\n";

        $cwd = getcwd();

        register_shutdown_function(function(){
            echo "GetCWD inside of register_shutdown_function:" . getcwd();
               exit(1);
        });

        function throw_error($message)
        {
            trigger_error($message, E_USER_ERROR);
            exit(1);
        }
?>

Starting and Ending Transactions

Following the spirit of atomic operations, I found a link on starting and ending a transaction.

http://stackoverflow.com/questions/12091971/how-to-start-and-end-transaction-in-mysqli

And this might be a good link for figuring out where to place the commit statement when using prepared statements.

http://stackoverflow.com/questions/10642635/how-can-i-use-prepared-statements-combined-with-transactions-with-php

Names, ID’s, Classes, and whatnot

When working with an HTML page, the attributes that you need depend on the plugins that you’re using.

Name Attribute:
Used when submitting a post.

ID Attribute:
Used by Jquery to find an element when doing a $(#id_name).
Used by CSS.  Prefixed by (#)

Class Attribute:
Used by CSS.  Prefixed by (.)

I didn’t cover all of the cases, since I jotted down what I remembered, but it is a good idea to create a table for this stuff.

 

SSL theory

When preparing a site for Secure Socket Layer (SSL), it’s been said that you need to use relative paths on the website.

http://stackoverflow.com/questions/64631/what-does-a-php-developer-need-to-know-about-https-secure-socket-layer-connect

I believe that this is mainly because if you used absolute paths, you would usually throw an http:// in front of the path.  Or even if you don’t, you could be pulling the images from an external source that defaults to an unsecure service.

That being said, I was trying to keep paths relative on the php server itself.  I know why I was doing it, but if you think about it carefully…doing so does not achieve the same result as above.

 

See if you can spot the error!

$ControlColumns = array("col1", "col2", "col3", "col4", "col5");
$params = array();
$cols = array();
$colnames = array_column($ControlColumns, 1);

$bindtypes = "sssss";

foreach ($colnames as $col)
{
    $params[] = &$cols[$col];
}

$result = mysqli_stmt_bind_param($stmt, $bindtypes, $params);

Here’s the error:

Number of elements in type definition string doesn’t match number of bind variables in E:\XAMPP\xampp\htdocs\PHPTest\insert.php

And assume that the $stmt is a perfectly prepared statement with multiple parameters. In other words, it works fine.

Give up?

I guess I’m just stupid, but it took me an hour of messing around before I finally remembered that mysqli_stmt_bind_param was not designed to take an array input.

Use call_user_func_array to call that function instead.  Remember to reference the variables.

$params = array();
$params[] = $stmt;
$params[] = &$bindtype;

$result = call_user_func_array('mysqli_stmt_bind_param', $params);

 

PHP Foreach and Reference Variables

Here’s a crazy gotcha.  I was playing with references when I realized that I was getting the wrong values.

Here’re the values that I used:
$valuearray = array(‘%CTRL%’, ‘%2%’);

Here’s my original loop:

foreach($valuearray as $val)
(
    $params[] = &$val;
)

 

And here’s what the print_r($params) gave me.

Array
(
    [0] => %2%
    [1] => %2%
)

Do you see the problem yet?

In a nutshell, I was trying to load references of each element in $valuearray into $params.  It wasn’t working too well because I was shoving the reference of $val itself into $params.  Whatever $val last points at is what’s going to show up for all elements in the array.  Interesting!  But ultimately not what I was aiming for.

http://www.php.net/manual/en/control-structures.foreach.php

The above link had part of the solution.  The next step of the debugging process would be this loop (I’ve highlighted the change in cyan):

foreach($valuearray as &$val)
(
    $params[] = $val;
)

And here’s what the print_r($params) gave me.

Array
(
    [0] => %CTRL%
    [1] => %2%
)

That’s correct.  But we’re not out of the woods yet.  If you’re trying to shove this into a mysql query that needs references, it should give you an error that a value was received when it was expecting a reference.

Here’s the final iteration (I’ve highlighted the change in cyan):

foreach($valuearray as &$val)
(
    $params[] = &$val;
)

And now I’ve fulfilled my original goal, load references to an array’s elements into another array.

Templating Engines

I was creating a website when I had the bright idea of pre-creating a webpage template and then filling in the values that I needed.  At first I was going to roll my own, and then I realized that there were many PHP templating engines in existence already.  I decided to give Twig a try since it seemed to be well-known.

http://devzone.zend.com/1886/creating-web-page-templates-with-php-and-twig-part-1/

  • Twig example.
  • Shows the basics.
  • Unfortunately, does not demonstrate a straightforward loop.

http://readwrite.com/2010/08/31/twig-templating-engine-quick-s#awesm=~opErZeZWdq7zLX

  • It’s almost crap.
  • Despite its claims, for a five minute guide, it doesn’t show the basics like how to include the dependencies.  In addition, the code throws an error if you put it in a try-catch block.
  • However this sample does show how to create a template with a loop.
  • The error disappeared when I replaced display/print with render/echo. I wonder if the error hid itself or did I really fix it.