Solved

why did code not enter a class xmlException

Posted on 2014-04-08
11
364 Views
Last Modified: 2014-04-22
from matt zandstra php book


when line 72 is uncommented
Catchable fatal error: Argument 1 passed to XmlException::__construct() must be an instance of LibXMLError, integer given, called in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_04_Code\listing4.22.php on line 72 and defined in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_04_Code\listing4.22.php on line 6

I see that error is about libxml type which means an attempt to enter class xmlException

using line 74 or line 75
in this case line 74:
LibXMLError Object ( [level] => 3
 => 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 ) 

code never went to
xmlException::__construct()
line 6









[code]<?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

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
  • 6
  • 5
11 Comments
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 39987329
This statement means that the class can only be instantiated if it is given an object instance of LibXmlError as its argument.  In effect you're telling PHP to kill the script if you get any data structure other than LibXmlError sent into the constructor.

function __construct( LibXmlError $error ) {

If you try it like this ...

function __construct( $error ) {

... then you will be able to use var_dump($error) to see what the program logic sent to the XMLException class constructor.
0
 

Author Comment

by:rgb192
ID: 39987547
function __construct( LibXmlError $error ) {

If you try it like this ...

function __construct( $error ) {

Okay this is the answer for line 72

but why can line 74,75 not enter the constructor
(there is no $msg echo)


I made error with code block
this is correct code:
<?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



and this is the error for
line 74: (line 75 uncommented also does not enter constructor)
LibXMLError Object ( [level] => 3=> 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 )

code never went to
xmlException::__construct()
line 6
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 39987571
This line suppresses XML errors...

 $this->xml = simplexml_load_file($file, null, LIBXML_NOERROR );

I don't really know what "suppresses" means in this context.  It may mean that the suppressed error is not available to libxml_get_last_error().  I think I would set up some var_dump() statements to visualize the the contents of these function calls before using their output in another PHP statement.  Example:

Instead of this:

if ( ! is_object( $this->xml ) ) {
    throw new XmlException( libxml_get_last_error() );
}

Something more like this:

if ( ! is_object( $this->xml ) ) {
    // IT IS NOT AN OBJECT, SO WHAT IS IT?
    var_dump($this->xml);
    // WHAT IS IN THE ERROR FUNCTION?
    var_dump( libxml_get_last_error() );
    // NOW TRY TO THROW THE EXCEPTION
    throw new XmlException( libxml_get_last_error() );
}

Refs:
http://php.net/manual/en/libxml.constants.php
http://php.net/manual/en/function.libxml-get-last-error.php
0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:rgb192
ID: 39987595
Warning: simplexml_load_file(): file:///C:/wamp/www/POPP-edition4-code/9781430260318_Chapter_04_Code/conf.broken.xml:6: parser error : Opening and ending tag mismatch: conf-broked line 2 and conf in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_04_Code\listing4.22b.php on line 32

Warning: simplexml_load_file(): </conf> in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_04_Code\listing4.22b.php on line 32

Warning: simplexml_load_file(): ^ in C:\wamp\www\POPP-edition4-code\9781430260318_Chapter_04_Code\listing4.22b.php on line 32
bool(false) object(LibXMLError)#2 (6) { ["level"]=> int(3) ["code"]=> int(76) ["column"]=> int(12) ["message"]=> string(61) "Opening and ending tag mismatch: conf-broked line 2 and conf " ["file"]=> string(84) "file:///C:/wamp/www/POPP-edition4-code/9781430260318_Chapter_04_Code/conf.broken.xml" ["line"]=> int(6) } LibXMLError Object ( [level] => 3 [c
ode] => 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 )



<?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,null);
        if ( ! is_object( $this->xml ) ) {
          // IT IS NOT AN OBJECT, SO WHAT IS IT?
          var_dump($this->xml);
          // WHAT IS IN THE ERROR FUNCTION?
          var_dump( libxml_get_last_error() );
          // NOW TRY TO THROW THE EXCEPTION
          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





I was not sure how to edit
 $this->xml = simplexml_load_file($file, null, LIBXML_NOERROR );

I tried
 $this->xml = simplexml_load_file($file, null, null );


code did not enter the constructor
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 39987672
OK, so what is the question in this context?
0
 

Author Comment

by:rgb192
ID: 39987782
I think line 74,75 when uncommented should enter XmlException::__construct()

and you think the isssue is because
$this->xml = simplexml_load_file($file, null, LIBXML_NOERROR );
suppresses the error
0
 

Author Comment

by:rgb192
ID: 40012806
OK, so what is the question in this context?

I am using a line by line debugger and I do not see code entering the constructor
why?
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 40012857
Could you please set up the SSCCE and post the code and test data here?  I'll be glad to experiment with it and show you what I see, if I know I am starting from a point that makes sense to you.
0
 

Author Comment

by:rgb192
ID: 40013699
http://www.experts-exchange.com/viewCodeSnippet.jsp?refID=39987595&rtid=20&icsi=1


difficult to show test data because there is absence of output



    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 );
    }

Open in new window


is never used.
I want to echo $msg
0
 
LVL 110

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 40014834
As I understand it, here is the full class definition:
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;
    }
}

Open in new window

If the constructor is never entered, it's because nothing threw a new XmlException.  This might be a logic error, or it might be "good news" that something worked correctly and had no need to raise an XMLException.  If you want to see what is in $msg, you might add var_dump($msg) after line 7.  $msg is a local variable so it will not be apparent if you dump the object.  You must dump $msg from within the class definition to see its contents.
0
 

Author Closing Comment

by:rgb192
ID: 40016199
okay nothing threw the xml exception
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

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…
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

738 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