• Technosailor.com
  • Desk of the Editor
  • Entrepreneurship
  • Web Marketing
  • Tech Policy
  • Contenido Español
Technosailor
  • Blog
  • Authors
  • Twitter Pitch Me!
  • Disclosures
  • Advertise on Technosailor.com
Nov
28
2005

Case Study b5Media: Debugging PHP - Part 1

Posted by: Aaron Brazell

I talked earlier about landing a deal with “b5media”:http://www.b5media.com to implement a migration script to move their 32 new blogs into WordPress. I thought the deal would be straightforward enough but I ran into a number of issues with the importer.

I wanted to give you a window into the process of debugging for one MAJOR issue. For reference, here is “the original nucleus.php file”:http://www.technosailor.com/nucleus.phps I began debugging with this afternoon.

h3. Issue Reported: Not all comments Seemed to be imported

As a first run, we imported a blog called “The Beauty Blog”:http://www.aboutweblogs.com/beauty/. It was noted that it did not appear all comments were imported as there were some missing. As a point of reference, one entry on the original blog entitled “My Solution for Buildup”:http://www.aboutweblogs.com/beauty/?itemid=2608 had 4 distinct comments from 2 users.

However, upon import and viewing in the new WordPress blog, only 2 comments showed up by the same user

h3. How I figured things out

I will let you dissect the script to find out the basis of what happens. However, we know that the problem seemed to be happening on the execution of the import_comments() function.

From the code, this function looks like this:

[php]function import_comments()
{
// Comment Import
$comments = $this->get_nuc_comments();
$this->comments2wp($comments);

_e(’<form action=”admin.php?import=nucleus&step=6″ method=”post”>’);
_e(’<input type=”submit” name=”submit” value=”Import Links” />’);
_e(’</form>’);
}
[/php]

This bit of code tells us that first we are going to run the get_nuc_comments() function which will gather all the comment data from Nucleus into an associative array and return the data to a variable $comments. We will then pass $comments to comments2wp() where the data will be passed to the WordPress API and inserted into the new WordPress blog.

We know something is going wrong in this process so let’s start at the top… get_nuc_comments(). This function looks like this:
[php]
function get_nuc_comments()
{
// General Housekeeping
global $nucdb;
set_magic_quotes_runtime(0);
$nuc_com = array();
$prefix = get_option(’npre’);
$blog_id = get_option(’blog_id’);

$storedUsers = $nucdb->get_results(”SELECT cmember FROM nucleus_comment”);

foreach($storedUsers as $su)
{
if(0 d;d; $su->cmember)
{
return $nucdb->get_results(’SELECT
cnumber,
cbody,
cuser,
cemail,
citem,
ctime,
chost,
cip
FROM nucleus_comment
WHERE cblog = ‘.$blog_id,
ARRAY_A);
}
else
{
return $nucdb->get_results(’SELECT
cnumber,
cbody,
mname AS cuser,
memail AS cemail,
murl AS curl,
citem,
ctime,
chost,
cip
FROM nucleus_comment, nucleus_member
WHERE cmember=mnumber
AND cblog = ‘.$blog_id,
ARRAY_A);
}
}
return false;
}[/php]

Now, most of this function is direct database queries from the Nucleus database. The schema of the two tables referenced (nucleus_comment and nucleus_member) are as follows:

nD@0,IrW&nܞz]M93T,rz{[ܭ{M93T,ˬzڭZyT,ɚ[ڭZ]4uں[MPۯ&zfޮ)W^} -r+^)SNL -ןjmmz͸ٺrئy֭zئxӓ5Buں[|^M4M4M4͸ٺr,rG^} -r*oj!jy4Py6V]M93T,^}͵O6fڶ)){x4Py6׭<ۍ `r{mۯ!(Fz'fޭ(Fצr+^BLE(Fnrqɺш4

Nucleus has a feature similar to WordPress in that if a member exists as a result of signing up for an account, they are stored in the nucleus_member database. However, having a membership is not required to comment on a Nucleus blog. As a result, Nucleus stores comments with all the standard comment information (email, name, IP address, etc) and stores a 0 in the cmember field if the user is NOT a Nucleus member. However, if the member *is* a member, cmember stores their member ID number and leaves the name and email fields blank because it will get the stored member information in nucleus_member.

Make sense? It did to me too until I started debugging! The get_nuc_comments(), in theory, worked like this:

# Get the cmember field for all the comments
# Loop through the cmember fields
# If the cmember field was equal to 0 (not a member), then perform a direct query only on the nucleus_comment table
# If the cmember field was NOT equal to 0 (is a member commenting), then perform a query getting the comment data from the nucleus_comment table and the associated member information from the nucleus_member table.
# return the data for use in the comments2wp() function

Looking over my code for errors, the first thing I noticed was that in my first query, I used a field “cemail” when, from the schema, that field should be “cmail”. I changed the alias name in the second query as well for consistency, but knew that that second query should not fail because we were actually selecting “memail” from the members table and that field _did_ exist!

I figured this was the solution to the problem. This query was failing because the field name was incorrect and somewhere along the line, it was _failing silently!_ Saved the file and re-ran the import. No errors reported, however that post that should have 4 comments, still only had the same 2.

Sigh. Back to the drawing board. Let’s look back at that code.

Ahha! Do you see what I see? I’m returning both of those queries. In PHP, Perl, C++ and most languages of similar syntax, a return means that the function is completed and the data that is being returned is what should be kicked back out. Only one query should be getting run, right?

So I made the following change to the code:
[php]
function get_nuc_comments()
{
// General Housekeeping
global $nucdb;
set_magic_quotes_runtime(0);
$nuc_com = array();
$prefix = get_option(’npre’);
$blog_id = get_option(’blog_id’);

$storedUsers = $nucdb->get_results(”SELECT cmember FROM nucleus_comment”);

foreach($storedUsers as $su)
{
if(0 == $su->cmember)
{
$com = $nucdb->get_results(’SELECT
cnumber,
cbody,
cuser,
cemail,
citem,
ctime,
chost,
cip
FROM nucleus_comment
WHERE cblog = ‘.$blog_id,
ARRAY_A);
}
array_push($nuc_com, $com);
else
{
$com = $nucdb->get_results(’SELECT
cnumber,
cbody,
mname AS cuser,
memail AS cemail,
murl AS curl,
citem,
ctime,
chost,
cip
FROM nucleus_comment, nucleus_member
WHERE cmember=mnumber
AND cblog = ‘.$blog_id,
ARRAY_A);
array_push($nuc_com, $com);
}
return $nuc_com;
}
return false;
}[/php]

This change would assign each query result to a variable, $com and then use the "array_push()":http://www.php.net/array_push function to push the resulting array onto the end of the $nuc_com array.

Save. Load. Execute. Failure.

Now I’m getting pissed. This should work.

Let’s see what the $nuc_com array contains. Drop this right before the return $nuc_com; and reload.

[php]
echo’<pre>’;
print_r($nuc_com);
echo’</pre>’;
exit;
[/php]

Kicked out is a long nested array looking similar to (changing details to protect the innocent):
nnۯ

Well this is not very useful on it’s face because I need to know how many of these commenters have a cmember value of 0 or non-zero. This will tell me if only one of the queries is being executed or if both are. I added “cmember” to both of the SELECT queries and re-executed.

nnۯ

Scanning the resulting output, I see that all of the results have non-zero cmember values. Not good. Obviosuly, only the second query is being executed. When this happens, the first place I look to is the conditional — the if/else statement. IF something is true, then run this code, OTHERWISE run that code. In our case _that_ code was running and _this_ code never was.

To be continued…

  • Add to Mixx!
  • Stumble it!
About the Author: Aaron Brazell is the lead editor of Technosailor.com and a social media expert. His passion is to see companies and individuals use the internet and web technologies wisely and effectively to promote their brands and companies. He served as Director of Technology at b5media from 2005-2008 and is currently an independent consultant.
Tagged: b5media, php, Programming at 7:20 am -
discussion by DISQUS

Add New Comment

  • Subscribe:  This Thread
  • Go to:  My Comments ·  Community Page
  • Sort thread by:

    Viewing 6 Comments

    Thanks. Your comment is awaiting approval by a moderator.

    Do you already have an account? Log in and claim this comment.

      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Crash Test Dummy 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      You are doing a fantastic job, Aaron--this is very interesting to read your thought processes!
      reply  edit  flag   record video comment
      http://www.ebeautydaily.com /people/9e937d59bfff3abe2173165355aea409/
      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Eric Coleman 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      What do you use on a normal basis for debugging?

      I usually use PEAR's Log class, and I have xdebug installed (and profiling enabled).

      It's a great help :)
      reply  edit  flag   record video comment
      /people/17009a4dfbac5e12b23c4c3fc831ee7a/
      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Aaron 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      bq. What do you use on a normal basis for debugging?

      My brain. :-)
      reply  edit  flag   record video comment
      http://www.technosailor.com /people/d409f7e3d0b43dd41dcfbd58aa255601/
      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Eric Coleman 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      Your a funny one, let me tell ya ;)

      You obviously don't stare at php code for 60+ hours a week ;P

      BTW, fix those code blocks... the double spacing is making me go blind :P
      reply  edit  flag   record video comment
      /people/17009a4dfbac5e12b23c4c3fc831ee7a/
      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Eric Coleman 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      Aaron,

      I get parse errors every time I submit a comment, however they are submitted anyways :)

      -- eric
      reply  edit  flag   record video comment
      /people/17009a4dfbac5e12b23c4c3fc831ee7a/
      • ^
      • v
      • Permalink
      • Admin
        • Remove Post
        • Block email
        • Block IP address
      Aaron 2 years ago 1 point

      Please login to rate.

      Do you already have an account? Log in and claim this comment.

      It's my way to get you to leave. ;)

      kidding, of course.

      YEah it's the Subscribe to Comments plugin. I need to address it but, as you pointed out, it doesn't prevent commenting or subscibing so it's not at the top of the priority list at the moment. Thanks though.
      reply  edit  flag   record video comment
      http://www.technosailor.com /people/d409f7e3d0b43dd41dcfbd58aa255601/
    discussion by DISQUS

    Add New Comment

    close Joe Chill(joechill)
    konvict

    status via twitter

    Murdering the Wayne parents, creating Batman · 2 minutes ago

    recent comments (follow comments)

      View Profile »
      Powered by Disqus · Learn more
      blog comments powered by Disqus
      • Recent Posts

        • Fantasy Football for Charity
        • Findability is a Legitimate Concern for Bloggers
        • Search and Findability
        • Will I See you in Boston? Or in San Francisco? Or in Boulder? Or in Vegas?
        • The Psychology of Gap Marketing
      • Recent Comments

        Powered by Disqus
      • Tags

        Aaron Brazell Advertising Apple b5media Blogging book conferences Design entrepreneurship Facebook Finance and Funding Google guest_blogging holidays humor hurricanes_and_natural_disasters interesting job Links Marketing Music nfl Op-Ed Perfect Pitch personal politics pr Predictions productivity Programming Security Social Issues Social Media Social Networking social_issues Sports Tech Industry Technology Technosailor Travel twitter unix Venture Files WordPress you_can_blog

      • License Creative Commons Attribution-Noncommercial-Share Alike 3.0 | Copyright © 2004 - 2008 - Aaron Brazell | Lisa helped out | Privacy Policy

        Twitter Pitch!

        <p>Twitter pitching is a form of pitch that requires succint "what does this mean for me" kind of pitching. It is the ultimate efficiency of words. You have 140 characters or less to tell me why your pitch matters to me or my readers. Please include a means of contacting you. This is included in your 140 characters. If you send successive pitches, you will likely be ignored, unless it's obvious that the first pitch was a case of "accidental send", etc.</p> <p>This form of pitching does not mean I'm being a diva. It means that my time is valuable, and you want a piece of it. It's good practice for you, and delivers your pitch in a format I want. Win-win.</p>


        (X) Close

        Twitter Pitch Me!