Solved

is class exception parent of class xmlexception extends exception, and when does code break

Posted on 2014-04-23
8
239 Views
Last Modified: 2014-04-28
<?php

class XmlException extends Exception {
    private $error;

    function __construct( LibXmlError $error ) {
        $shortfile = basename( $error->file );
	print_r( $error );
        $msg = "[{$shortfile}, line# {$error->line}, col# {$error->column}] {$error->message}";
        $this->error = $error;
        parent::__construct( $msg, $error->code );
    }

    function getLibXmlError() {
        return $this->error;
    }
}

class FileException extends Exception { }
class ConfException extends Exception { }

class Conf {
    private $file;
    private $xml;
    private $lastmatch;

    function __construct( $file ) {
        $this->file = $file;
        if ( ! file_exists( $file ) ) {
            throw new FileException( "file '$file' does not exist" );
        }
        $this->xml = simplexml_load_file($file, null, LIBXML_NOERROR );
        if ( ! is_object( $this->xml ) ) {
            throw new XmlException( libxml_get_last_error() );
        }
        $matches = $this->xml->xpath("/conf");
        if ( ! count( $matches ) ) {
            throw new ConfException( "could not find root element: conf" );
        }
    }    

    function write() {
        if ( ! is_writeable( $this->file ) ) {
            throw new Exception("file '{$this->file}' is not writeable");
        }
        file_put_contents( $this->file, $this->xml->asXML() );
    }

    function get( $str ) {
        $matches = $this->xml->xpath("/conf/item[@name=\"$str\"]");
        if ( count( $matches ) ) {
            $this->lastmatch = $matches[0];
            return (string)$matches[0];
        }
        return null;
    }

    function set( $key, $value ) {
        if ( ! is_null( $this->get( $key ) ) ) {
            $this->lastmatch[0]=$value;
            return;
        }
        $conf = $this->xml->conf;
        $this->xml->addChild('item', $value)->addAttribute( 'name', $key );
    }
}


class Runner {
    static function init() { 
        try {
            //$error_test= new XmlException(1);
            //$conf = new Conf( dirname(__FILE__)."/conf01-edit.xml" );
            $conf = new Conf( dirname(__FILE__)."/conf.broken.xml" );
            $conf = new Conf( dirname(__FILE__)."/fake.xml" );
            print "user: ".$conf->get('user')."\n";
            print "host: ".$conf->get('host')."\n";
            $conf->set("pass", "newpass");
            $conf->write();
        } catch ( FileException $e ) {
            // permissions issue or non-existent file
            throw $e;
        } catch ( XmlException $e ) {
            // broken xml
        } catch ( ConfException $e ) {
            // wrong kind of XML file
        } catch ( Exception $e ) {
            // backstop: should not be called
        }
    }
}

Runner::init();

?>

Open in new window


LibXMLError Object ( [level] => 3 [code
] => 76 [column] => 12 [message] => Opening and ending tag mismatch: conf-broked line 2 and conf [file] => file:///C:/wamp/www/POPP-edition4-code/9781430260318_Chapter_04_Code/conf.broken.xml [line] => 6 )


when does this code break?
does code break after running
parent::__construct( $msg, $error->code );
is class exception parent of class xmlexception extends exception
after running line11
debugger goes to line12 and breaks
I think I know why error
why did code stop at that line
0
Comment
Question by:rgb192
  • 3
  • 3
  • 2
8 Comments
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40019407
Code is breaking on line 76
LibXMLError Object ( [level] => 3 [code
] => 76 [column] => 12 

Open in new window

Error is caused by a problem in the xml file you are using.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40019879
is class exception parent of class xmlexception extends exception
Yes.
why did code stop at that line
Line 74 creates a new Conf object in the variable named $conf.  Line 75 overwrites variable $conf with another new Conf object.  Line 76 does not appear to be the problem (I think the "76" came from an error code, not a line number).  I believe line 34 threw a new XmlException using the data in the PHP function libxml_get_last_error().  This happened because of the creation of a new Conf object on line 74, where the XML document is not valid.  From the document name, it appears that the XML is intentionally not valid.

Executive summary: The code did not "break" at all.  Line 11 called the Exception constructor.  This was perfectly normal and expected.

Maybe it's the IDE that has trouble following the logic here?
0
 

Author Comment

by:rgb192
ID: 40021606
line 11
 parent::__construct( $msg, $error->code );

is run

is this the 'error class'  which is not visible by my ide

ide waits 10 seconds and then runs line 12
}

and then stops

maybe finished the 'error child' class
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40021728
I don't know.  When you have layers of IDEs and example code, anyone's guess is as good as mine.  Anything that waits 10 seconds then resumes is a strange design.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:rgb192
ID: 40021776
is class exception parent of class xmlexception extends exception
0
 
LVL 52

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 40021970
Did not read your question properly before.

This is what is happening
- The code is running to line 74.
- The code attempts to read the broken xml file on line 32.
- On line 33 the return from 32 is tested to see if it is valid but fails
- The code drops to line 34 and throws an XmlException passing in the last error encountered by lib XML.
- This results in the instantiation of the XmlException object - and where your print_r($error) line executes
- The code then drops into the catch statement on line 84 - at this point you could do the following to your catch block
        } catch ( XmlException $e ) {
           $error = $e->getLibXmlError();
           echo "Exception caught: " . $error->message . 'in file : ' . $error->file . ' on line ' . $error->line ;
            // broken xml
        }

Open in new window

You can also make your error dump more informative by adding <pre> tags around it i.e.
echo "<pre>";
print_r($error);
echo "</pre>";

Open in new window

Which should output something like this
LibXMLError Object
(
    [level] => 3
    [code] => 5
    [column] => 56
    [message] => Extra content at the end of the document

    [file] => file:///G:/Projects/Sandbox/website/ee/broken.xml
    [line] => 6
)

Open in new window


The reason your debug stops on line 12 is that the exception is instantiated but you don't do anything with it in the catch block so there is nothing more to do.

By adding the code above to the catch block you should see the code terminate on or around line 87
0
 

Author Closing Comment

by:rgb192
ID: 40028560
thanks for information to dump variable values.
0
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40028834
You are welcome - thanks for the points.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now