Solved

why did code not enter a class xmlException

Posted on 2014-04-08
11
361 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
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 

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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

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 …
3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

773 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