Solved

why did code not enter a class xmlException

Posted on 2014-04-08
11
360 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 108

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 108

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
 

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 108

Expert Comment

by:Ray Paseur
ID: 39987672
OK, so what is the question in this context?
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: 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 108

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 108

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

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

Title # Comments Views Activity
Form Processing in PHP 11 32
how to use a function in heredoc 5 22
PHP: concatenate query 13 39
How to convert my query to the proper format? 5 18
Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to dynamically set the form action using jQuery.
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 …

920 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

14 Experts available now in Live!

Get 1:1 Help Now