Fork me on GitHub

article

Quickly unserialize PHP array data in TextMate

August 28, 2009 | PHP Scripting

Every once in a while I need to see what’s hiding in a serialized array in a database field and finally just wrote a little TextMate command to do the job for me. If I’m already working in that area of code its easier to just dump it someone in the page output to read it, or maybe dump it to the error_log, but often enough I just need to see the data. It turned out to be much different than I thought it’d be. I figured I’d write a line of Ruby to call PHP via the command line but then I found that PHP can be used directly in TextMate commands.

Okay, that helps.

So, add a new command to your bundle (I keep a bundle just for adding miscellaneous things to so that I don’t pollute other bundles and/or lose my additions when those bundles are upgraded). Make a new command whose Input is “Entire Document” and Output is “Replace Document”. Give it a key binding if you want.

Then put this code in as the script:

  1.  #!/usr/bin/env php
  2.  <?php
  3.  print_r(unserialize(file_get_contents('php://stdin')));
  4.  exit;

There is no save button for bundle items. Simply switch to another item, any item in the bundle to save this one.

Voila. Copy and paste some serialized array data in to a new document, run the command and it’ll be replaced with a nicely formatted output of the array data and structure. Haven’t tried it with objects yet, but they probably won’t work anyway unless they’re generic objects that don’t need to have their class definition loaded to properly unserialize.

3 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  • Man this helped me a lot today. I needed to modify a serialized row in a DB and this made looking through it much easier. I went 1 more step and made a reverse of this so that I could make changes then serialize it back. It involved some preg_match-ing and works like a charm. Here’s the code (not sure if it will parse correctly on this page but we will see):

    #!/usr/bin/env php
    <?php

    $string_to_array = explode("\n",file_get_contents('php://stdin'));

    foreach ($string_to_array as $line) {
    if(preg_match("/(\s+)\[/", $line))
    {
    $key = preg_replace("/(\s+\[(.*)\].+)/","$2",$line);
    $value = preg_replace("/.+(=> (.*)\n?)/","$2",$line);
    $array_result[$key] = $value;
    }
    }

    echo serialize($array_result);

    ?>

    Erik Reagan, October 27, 2009 2:41 pm | permalink

  • Good stuff! Thanks. I love finding new ways to abuse TextMate!

    Shawn, October 27, 2009 2:47 pm | permalink

  • I know this isn’t a recent post but it’s one of the first in google Anyway, I couldn’t get Erik’s un-print_r solution to work with multidimensional arrays & found this to work:


    #!/usr/bin/php
    <?php

    function print_r_reverse($in) {
    $lines = explode("\n", trim($in));
    if (trim($lines[0]) != 'Array') {
    // bottomed out to something that isn't an array
    return $in;
    } else {
    // this is an array, lets parse it
    if (preg_match("/(\s{5,})\(/", $lines[1], $match)) {
    // this is a tested array/recursive call to this function
    // take a set of spaces off the beginning
    $spaces = $match[1];
    $spaces_length = strlen($spaces);
    $lines_total = count($lines);
    for ($i = 0; $i /m", $in, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
    $pos = array();
    $previous_key = '';
    $in_length = strlen($in);
    // store the following in $pos:
    // array with key = key of the parsed array's item
    // value = array(start position in $in, $end position in $in)
    foreach ($matches as $match) {
    $key = $match[1][0];
    $start = $match[0][1] + strlen($match[0][0]);
    $pos[$key] = array($start, $in_length);
    if ($previous_key != '') $pos[$previous_key][1] = $match[0][1] - 1;
    $previous_key = $key;
    }
    $ret = array();
    foreach ($pos as $key => $where) {
    // recursively see if the parsed out value is an array too
    $ret[$key] = print_r_reverse(substr($in, $where[0], $where[1] - $where[0]));
    }
    return $ret;
    }
    }

    $in = file_get_contents("php://stdin");

    echo serialize(print_r_reverse($in));

    ?>

    It’s taken from here: http://www.php.net/manual/en/function.print-r.php#93529

    Also, in order to help with the editing of some serialised database data I also needed a quick termite command to serialise arrays & use the following:

    #!/usr/bin/env php

    Hope it helps someone.

    Roger, September 1, 2011 5:19 am | permalink

Comments are closed