?
Solved

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

Posted on 2014-04-23
8
Medium Priority
?
249 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
8 Comments
 
LVL 58

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 111

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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 111

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
 

Author Comment

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

Accepted Solution

by:
Julian Hansen earned 2000 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 58

Expert Comment

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

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

These days socially coordinated efforts have turned into a critical requirement for enterprises.
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses

719 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