• PHP $_POST converting array to string 'Array'

    Posted on 22nd Jun 2012

    I've been developing in PHP for about 5 years now, processing form data using $_POST on almost a daily basis. It was only yesterday though that I came across this little headache for the first time. What looks like and array, talks like an array, should be an array but is actually the 5 character string 'Array'!?

    Here's the scenario I was in. I was trying to post some fairly normal form submission data (a few text inputs and a checkbox array) using cURL to an API that would in turn update a database record. I would then expect a JSON result from the server letting me know if all went well or if we had any errors in the form data or updating process. Seemed straight forward enough.

    My basic cURL code was this.

    <?php
    $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://example.co.uk/api/update/format/json'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST); $buffer = curl_exec($ch); curl_close($ch); $result = json_decode($buffer); ?>

    I've used this code a few times before, and even in the same project. But there was something going on this time that was causing some of the $_POST data that should have been an array, to actually be converted into the string 'Array'. Weird huh? Using print_r() and var_dump() on $_POST was showing me the right data in the right format. But if I returned the $_POST data from the API method and used print_r() on the $result variable it would show any array now as a string.

    More often than not Google will find me a result or something near enough to put me on the right track but after 3 hours searching I was drawing a blank! People had experienced similar issues previously but there never seemed to be a a solution by the end of the forum posts. Close to tears it eventually dawned on me that it must be something to do with the way cURL was handling multi-dimensional arrays. All my other forms in the project using the same code and that were working, weren't posting multi-dimensional arrays (an array in an array, for those not sure what on earth I'm talking about).

    A little digging around cURL quite quickly informed me that in fact cURL does not handle these sorts of arrays well at all. The fact still remains however that I needed to send this data through, so the question was how to convert a multi-dimensional array into something like a string that could easily be sent but then on the receiving end convert the string back into the array?

    Well fortunately the solution is not a complex one. PHP has 2 native functions that will do exactly what we need in this case, serialize() and unserialize().

    We need to use the serialize() function to convert our form data in the global $_POST array into its string representation.

    Simple enough, my new code is now.

    <?php
    $postArgs = array('data' => serialize($_POST)); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://example.co.uk/api/update/format/json'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs); $buffer = curl_exec($ch); curl_close($ch); $result = json_decode($buffer); ?>

    A new step is now required on our receiving end in the API method now to convert our string back to it's original array. So in the receiving method we'll use the unserlialize() function like so.

    <?php
    function update_post() { // Convert the $_POST data from string representation back to multi-dimensional array $_POST = unserialize($_POST['data']); /* * Validate and Sanitize form data then update Database Record */ } ?>

    So there we have it. The solution is a simple one but it was a real fight getting there. I hope it helps others who run into the same or similar issues.

    I only got through by the power of Yorkshire Tea and stroopwafels.

  • IE9 Z-index stacking problem? Or something stranger?

    Posted on 29th Mar 2012

    I thought we were well beyond stacking issues in Internet Explorer, but it turns out that isn't the case.

    Whilst building a gallery module on a recent site I noticed that IE9, unlike all other browsers, was 'ignoring' the z-index, or so I thought.

    Here's a basic run-down of what I had.

    <div id="gallery">
    <div class="gallery-container"> <ul class="gallery-images"> <li class="current"> <h1>1980</h1> </li> <li> <img src="/images/gallery1.jpg" width="400" height="300" alt="gallery image 1"> </li> <li> <img src="/images/gallery2.jpg" width="400" height="300" alt="gallery image 2"> </li> <li> <img src="/images/gallery3.jpg" width="400" height="300" alt="gallery image 3"> </li> </ul> </div> <a href="#" title="Show previous image" class="gallery-prev gallery-nav"> <span class="sprite next-arrow"></span> </a> <a href="#" title="Show next image" class="gallery-next gallery-nav"> <span class="sprite prev-arrow"></span> </a> </div>

    And for the CSS

    #gallery {
    position: relative; z-index: 3000; height: 560px; } .gallery-nav { height: 330px; width: 80px; display: block; position: absolute; left: 0; top: 0px; z-index: 1000; } .gallery-next { left: auto; right: 0; } .gallery-nav span { width: 80px; height: 330px; background: transparent; } .gallery-nav:hover span { background: url(/images/sprite.png) -341px 0; } .gallery-nav:hover .next-arrow { background-position: -420px 0; } .gallery-container { height: 330px; width: 940px; overflow: hidden; position: relative; z-index: 0; } .gallery-images { position: absolute; top: 0; left: 0; width: 4000px; z-index: 0; } .gallery-images li { float: left; margin: 0; }

    Pretty straight forward. What I expected to happen was when I hovered over the right, or left hand side of the gallery, the next or previous navigation arrows would show up.

    What actually happened was, well nothing. I thought it was a z-index issue as this sort of thing has been well documented in the past in previous versions of Internet Explorer. However after about 40 minutes trying to implement those workarounds, still nothing.

    Eventually I stumbled across a forum post that provided a little extra insight.

    The fix

    From that forum post:

    In IE the element with the link must have background in order to be click-able. Otherwise the mouse 'sees right through it'. Oddly though, we can give it a phony background image.

    So if you need your link to have a transparent background but to still show it's contents when hovered you simply need to add a 'fake' background image to it. I just generated a 1px by 1px transparent GIF file and linked it up to the gallery navigation like so.

    .gallery-nav { background: url(/images/fixer.gif); }
    

    And that fixed it straight away. So it looks like a z-index bug, acts like a z-index bug, but isn't really a z-index bug.

  • Apache Performance Tuning

    Posted on 15th Mar 2012

    When working with Apache servers on a regular basis it's a good idea to have a few performance tweaks under your belt to get the best out of your sites from the get go.

    This article will provide some basic apache (httpd) performance tuning. The objective of this article is to perform simple edits that will allow your (dv) server to run with less memory and to ensure higher availability under heavier loads.

    Apache Timeout setting

    The Timeout setting is the number of seconds before data "sends" or "receives" (to or from the client) time out. Having this set to a high number forces site visitors to "wait in line" which adds extra load to the server.

    First, backup the file with the following command:

    # cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.bkup.kb-246.1

    The following command opens httpd.conf and searches for the term Timeout:

    vi +/Timeout /etc/httpd/conf/httpd.conf

    You should see the following lines:

    #Timeout: The number of seconds before receives and sends time out.
    Timeout 120

    Edit the section that reads:

    Timeout 120

    Change to a more reasonable value like the following:

    Timeout 20

    Save this file by pressing the escape key followed by :wq! which will save the file and exit vi.

    Then restart Apache to apply the changes:

    /etc/init.d/httpd restart

    Editing the php.ini file

    There are a few parameters that I tend to adjust in the php.ini file, normally to allow larger files to be uploaded through forms, to turn of PHPs safe mode or to allow more memory allowance for PHP executions. These parameters include:

    safe_mode
    register_globals upload_max_filesize post_max_size max_execution_time memory_limit

    Use the following command at the command prompt to start editing:

    vi /etc/php.ini

    If you have upgraded to PHP5, the ini is located at

    /opt/php51/etc/php5/fastcgi/php.ini

    If you are looking for a specific parameter and would like to go straight there, type the following:

    vi +/parameter /etc/php.ini

    Example:

    vi +/safe_mode /etc/php.ini

    When you are finished editing your php.ini, you will need to restart your apache server. Run the following command:

    /etc/init.d/httpd restart

    More advanced optimisation techniques

    You can find more official documentation on performance tuning for Apache over at their site. These optimisations are not for the faint hearted!

  • Adding some depth to your webpage

    Posted on 15th Mar 2012

    Although these techniques are subtle (which arguably is a good thing so those browsers without support don't look hugely different), they do provide a significant 'lift' to a page giving a greater sense of depth.

    1. Subtle borders and horizontal rules

    This is probably the technique I use most often to add a bit of punch to a page. Really easy to conjure up and provides that little emboss effect.

    For this to work you will need to be working with a background that isn't white.

    border-bottom: 1px solid #E3E3E3;
    box-shadow: 0 1px 0 #FCFCFC;

    To get this playing nicely in as many browsers as possible we can add in all the vendor prefix versions of box-shadow too, so our final code would be.

    border-bottom: 1px solid #E3E3E3;
    -webkit-box-shadow: 0px 1px 0 #FCFCFC;
    -moz-box-shadow: 0px 1px 0 #FCFCFC;
    box-shadow: 0px 1px 0 #FCFCFC;

    This will work in almost all browsers except IE8 and below.

    2. Embossed text

    A similar technique to the one above, the idea here is that we give the text a 1px solid shadow that is both lighter than the text colour and lighter than the background colour so it is still visible.

    The text-shadow property has been around for ages, but because of a slow uptake into Internet Explorer this still isn't going to work until the release of IE10. But no biggie they still get perfectly legible text, just without the extra pazzaz.

    text-shadow: 0px 1px 0px #fcfcfc;
    color: #333;
  • Reconfigure Plesk to use your vhost file

    Posted on 4th Mar 2012

    I never remember how to do this even though I often find myself fiddling with vhost files

    This works on the Dedicated Virtual Server (3.5) that I use most often from Media Temple, so it may not work in your situation.

    Reconfigure your server to use the new vhost.conf file using Plesk's websrvmng command:

    /usr/local/psa/admin/sbin/websrvmng -a -v
    

    To carry out the same function on a dv 4.0 set-up you can use

    /usr/local/psa/admin/sbin/httpdmng --reconfigure-all