Solved

why did code not enter a class xmlException

Posted on 2014-04-08
11
362 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
  • 6
  • 5
11 Comments
 
LVL 109

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 109

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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

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 109

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 109

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 109

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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Row insertion failed. Array 5 48
PHP Mail error 3 28
Log in through ID 5 19
check mysql insert 12 28
Things That Drive Us Nuts Have you noticed the use of the reCaptcha feature at EE and other web sites?  It wants you to read and retype something that looks like this.Insanity!  It's not EE's fault - that's just the way reCaptcha works.  But it is …
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…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

830 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