Debugging OO Code

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Debugging OO Code

Post by Benjamin »

I'm using the symfony framework to develop website applications. I've come across a problem with one of the symfony validators:

Code: Select all

 
new sfValidatorPropelUnique( 
    array( 
        'model'         => 'Members', 
        'column'        => array('user_name'), 
    ), 
    array( 
        'invalid'       => 'This user name has already been taken', 
    )
),
 
This is supposed to validate that a username isn't already in use. Whenever you update a record however, it's failing because someone already has that username... YOU. I'm assuming it's supposed to add criteria to the query that it runs or somehow be aware of an update automatically. For some reason it's not and I don't know how to fix it.

So my question is how am I supposed to debug this? Do I need to go through all the code echo'ing variables and dumping objects until I find the problem? What's the correct approach to this? Also, if you know why it's doing this that would be great. I'm pretty much dead in the water until I get this part working.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Debugging OO Code

Post by allspiritseve »

I have never used Symfony, but the best thing you could possibly do is download a testing framework like SimpleTest and take each class, mock out it's dependencies, and verify it does what it's supposed to. Unfortunately, that's more of a general solution than a specific fix for your bug.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Debugging OO Code

Post by Benjamin »

Ok, well I was able to get that fixed, The solution was simple as I figured it would be. I can probably get all the tests for the framework and run them. I'm more interested in how one goes about tracing the logic of the code at runtime. Is that just something that becomes intuitive with experience?
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Debugging OO Code

Post by jayshields »

Have you tried logging?
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Debugging OO Code

Post by Benjamin »

It has a built in logger, the output of which is below. If I added logging I'd have to add code to the core framework files all over the place I imagine.
Mar 11 17:44:51 symfony [info] {sfPatternRouting} Connect sfRoute "homepage" (/)
Mar 11 17:44:51 symfony [info] {sfPatternRouting} Connect sfRoute "content" (/:action.html)
Mar 11 17:44:51 symfony [info] {sfPatternRouting} Connect sfRoute "default_index" (/:module)
Mar 11 17:44:51 symfony [info] {sfPatternRouting} Connect sfRoute "default" (/:module/:action/*)
Mar 11 17:44:51 symfony [info] {sfPatternRouting} Match route "content" (/:action.html) for /update.html with parameters array ( 'module' => 'content', 'action' => 'update',)
Mar 11 17:44:51 symfony [info] {sfFilterChain} Executing filter "sfRenderingFilter"
Mar 11 17:44:51 symfony [info] {sfFilterChain} Executing filter "sfCacheFilter"
Mar 11 17:44:51 symfony [info] {sfFilterChain} Executing filter "sfCommonFilter"
Mar 11 17:44:51 symfony [info] {sfFilterChain} Executing filter "sfExecutionFilter"
Mar 11 17:44:51 symfony [info] {contentActions} Call "contentActions->executeUpdate()"
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} exec: SET NAMES 'utf8'
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT members.ID, members.COUNTRY, members.FIRST_NAME, members.LAST_NAME, members.EMAIL, members.USER_NAME, members.USER_ROLE, members.PASSWORD, members.YEAR_DIAGNOSED, members.DIAGNOSIS_TYPE, members.DOCTOR_TYPE, members.COINFECTION_ID, members.BIRTHDATE, members.ADDRESS_1, members.ADDRESS_2, members.CITY, members.PROVINCE, members.POSTAL_CODE, members.PHONE, members.APPROVED, members.VERIFIED, members.UNLOCK_KEY, members.CREATED_AT, members.UPDATED_AT FROM `members` WHERE members.ID=:p1
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '1' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT countries.ID, countries.NAME, countries.ISO2, countries.ISO3, countries.FORMAT FROM `countries` WHERE countries.ID=:p1 LIMIT 1
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '223' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT diagnosisTypes.ID, diagnosisTypes.NAME FROM `diagnosisTypes` WHERE diagnosisTypes.ID=:p1 LIMIT 1
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '1' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT coInfection.ID, coInfection.NAME FROM `coInfection` WHERE coInfection.ID=:p1 LIMIT 1
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '1' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT doctorTypes.ID, doctorTypes.NAME FROM `doctorTypes` WHERE doctorTypes.ID=:p1 LIMIT 1
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '1' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: UPDATE members SET `PASSWORD`=:p1, `UPDATED_AT`=:p2 WHERE members.ID=:p3
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '6be9b2749642020ff4ddb338bb65a1faaa7d961aa542f0d1d8c4d73ccfc5144f684f5f2eb5daab1025b37e401aaa1f3ebfaa7cb29a26e8a8cd09d80a1f788c7d' at position :p1 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding '2009-03-11 17:44:51' at position :p2 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} Binding 1 at position :p3 w/ PDO type PDO::PARAM_STR
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [info] {contentActions} Change template to "CURRENT/edit"
Mar 11 17:44:51 symfony [info] {sfPHPView} Render "/home/benjamin/public_html/ldnr/apps/frontend/modules/content/templates/editSuccess.php"
Mar 11 17:44:51 symfony [info] {sfPartialView} Render "/home/benjamin/public_html/ldnr/apps/frontend/modules/content/templates/_form.php"
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT countries.ID, countries.NAME, countries.ISO2, countries.ISO3, countries.FORMAT FROM `countries`
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT diagnosisTypes.ID, diagnosisTypes.NAME FROM `diagnosisTypes`
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT coInfection.ID, coInfection.NAME FROM `coInfection`
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} prepare: SELECT doctorTypes.ID, doctorTypes.NAME FROM `doctorTypes`
Mar 11 17:44:51 symfony [debug] {sfPropelLogger} 7
Mar 11 17:44:51 symfony [info] {sfPHPView} Decorate content with "/home/benjamin/public_html/ldnr/apps/frontend/templates/layout.php"
Mar 11 17:44:51 symfony [info] {sfPHPView} Render "/home/benjamin/public_html/ldnr/apps/frontend/templates/layout.php"
Mar 11 17:44:51 symfony [info] {sfWebResponse} Send status "HTTP/1.1 200 OK"
Mar 11 17:44:51 symfony [info] {sfWebResponse} Send header "Content-Type: text/html; charset=utf-8"
Mar 11 17:44:51 symfony [info] {sfWebDebugLogger} Configuration 6.66 ms (10)
Mar 11 17:44:51 symfony [info] {sfWebDebugLogger} Action "content/update" 142.91 ms (1)
Mar 11 17:44:51 symfony [info] {sfWebDebugLogger} View "Success" for "content/update" 134.48 ms (1)
Mar 11 17:44:51 symfony [info] {sfWebDebugLogger} Partial "content/_form" 121.14 ms (1)
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Debugging OO Code

Post by jayshields »

Yeah I suppose you'd have to add your own log messages into the code to get anywhere. I have informational log messages all over my latest project. Everytime any notable event happens in the code I send a plain english log message to the logger, whether the event is a success or failure.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Debugging OO Code

Post by Jenk »

Your tests should show up any erroneous functionality removing the need to debug :P
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Debugging OO Code

Post by josh »

Yeah I agree, I try to use exceptions instead of logging, basically build the "test" into the code or if it is directly testing business logic then move into a test suite. Sounds like you'd have to write tests for that Propel plugin individually though... you could just hard code a method for this use case and use their querying methods to send plain SQL.
Post Reply