maxudaskin Posted April 5, 2010 Share Posted April 5, 2010 I get the error below when running my application. Any help in solving the error or improving the code is appreciated. Thank you in advance. Fatal error: Call to a member function attributes() on a non-object in /**removed**/htdocs/include/classes/menu.php on line 42 Here is the offending code: function elementsToArray(&$element) { $count = 0; foreach ($element->attributes() as $key => $val) // Line 42 { $atts[$key] = $val; } foreach ($element->children() as $child) { $children[$count] = elementsToArray($child); $count++; } $arr = array( '0' =>$element->name(), '1' => $element->value(), '2'=>$atts, '3'=>$children); return $arr; } Here is the whole file, and below are the included files. <?php include_once($_SERVER['DOCUMENT_ROOT'] .'/include/classes/VFXP.inc.php'); class Menu { var $xmldoc; var $rootelem; function __constructor() { $this->xmldoc =& new VFXP_Document(); $this->xmldoc->parseFromFile($_SERVER['DOCUMENT_ROOT'] .'/include/config/menu.xml'); $this->rootelem =& $xmldoc->rootElement(); } function reconstruct() { $this->xmldoc =& new VFXP_Document(); $this->xmldoc->parseFromFile($_SERVER['DOCUMENT_ROOT'] .'/include/config/menu.xml'); $rootelem =& $this->xmldoc->rootElement(); } function display($loggedIn) { $this->reconstruct(); $elements = ($loggedIn) ? $this->parseElements('isLogin') : $this->parseElements('noLogin'); // Include Cascading Style Sheet and Javascript Functions echo '<link href="../styles.css" rel="stylesheet" type="text/css" />'; echo '<script type="text/javascript" src="../classes/menuFunctions.js"></script>'; } function parseElements($type) { return $this->elementsToArray($this->rootelem); } function elementsToArray(&$element) { $count = 0; foreach ($element->attributes() as $key => $val) { $atts[$key] = $val; } foreach ($element->children() as $child) { $children[$count] = elementsToArray($child); $count++; } $arr = array( '0' =>$element->name(), '1' => $element->value(), '2'=>$atts, '3'=>$children); return $arr; } } ?> VFXP.inc.php <?php // Package: VFXP - Very Fast XML Parser // Author: Claudio Castelpietra // Email: [email protected] // Web site: http://www.wopweb.com/ // License: "LGPL" // Release history: // 18/11/2005 - v.1.0 - First release. // 24/01/2006 - v.1.1 - Some API added. Some php compatibility issues fixed. // Description: // Very Fast XML Parser for PHP. // Completely standalone: no need for any PHP extension library. // Very fast processing, using iterative single-cycle parsing, instead of recursive or multi-step parsing. // Very useful for just loading simple application configuration parameters. // Strongly simplified and intuitive DOM API, with respect to the DOM Core Level 1 // Works with PHP >= 3 // Limitations in version 1.0: // XML version and encoding declaration tags are ignored. // DOCTYPE declaration tags are ignored. // Notes: // I developed this class because the faster extension-independent PHP XML parser I've found took about 500 milliseconds to parse my configuration file, and this is not acceptable for a web page generation. // This class takes about 20 times less than the previous one. // Anyway, this it a PHP-interpreted class, so its performance cannot be compared to a C-compiled class. // // The Document Class // class VFXP_Document { // Parses XML from a file // function parseFromFile($filename) { $fp = fopen($filename, 'rb'); $this->_docContentLength = filesize($filename); $this->_docContent = fread($fp, $this->_docContentLength); fclose($fp); $this->_parseContent(); unset($this->_docContent); } // Parses XML from a string // function parseFromString($content) { $this->_docContent = $content; $this->_parseContent(); unset($this->_docContent); } // Returns a reference to the root Element // function & rootElement() { return $this->_docRoot; } // Private variables and methods: var $_docContent; // The XML content var $_docContentLength; var $_docRoot; // Reference to the root element // Iterative method for fast XML parsing // function _parseContent() { // Removing some tags we don't handle $this->_docContent = eregi_replace('<\?xml [^>]+\?>|<!doctype [^\\[>]+(\\[[^]]*\\])?>', '', $this->_docContent); $parseStack = array(); $stacklen = 0; $currpos = 0; while (true) { // let's extract the next tag $tag = new VFXP_Tag(); // find the begin of the tag $tag->pos_start = strpos($this->_docContent, '<', $currpos); if ($tag->pos_start === FALSE) { die("VFXP - Error: XML tag not found."); } // check and skip comments if (substr($this->_docContent, $tag->pos_start, 4) == '<!--') { // we found a comment, let's look for its end $tag->pos_end = strpos($this->_docContent, '-->', $tag->pos_start + 4) + 2; if ($tag->pos_end === FALSE) { die("VFXP - Error: incomplete XML comment"); } // skipping comment tag $currpos = $tag->pos_end + 1; continue; } // check and skip CDATA sections if (substr($this->_docContent, $tag->pos_start, 9) == '<![CDATA[') { // we found a cdata section, let's look for its end $tag->pos_end = strpos($this->_docContent, ']]>', $tag->pos_start + 9) + 2; if ($tag->pos_end === FALSE) { die("VFXP - Error: incomplete XML CDATA section"); } // skipping cdata section $currpos = $tag->pos_end + 1; continue; } // find the end of the tag $tag->pos_end = strpos($this->_docContent, '>', $tag->pos_start); if ($tag->pos_end === FALSE) { die("VFXP - Error: incomplete XML tag"); } $currpos = $tag->pos_end + 1; // We have the tag. Let's check its type. if (substr($this->_docContent, $tag->pos_start + 1, 1) == '/') { $tag->is_opening = false; $tag->is_closing = true; $tag->name = substr($this->_docContent, $tag->pos_start + 2, $tag->pos_end - $tag->pos_start - 2); // $tag->attributes = array(); // will not be used } else { $tag->is_opening = true; if (substr($this->_docContent, $tag->pos_end - 1, 1) == '/') { $tag->is_closing = true; $tag->name = substr($this->_docContent, $tag->pos_start + 1, $tag->pos_end - $tag->pos_start - 2); } else { $tag->is_closing = false; $tag->name = substr($this->_docContent, $tag->pos_start + 1, $tag->pos_end - $tag->pos_start - 1); } // Tag attributes parsing ereg("^([^ \n\r\t/]+)([ \n\r\t/](.*))?$", $tag->name, $regs); $tag->name = $regs[1]; $attr_string = $regs[3]; $tag->attributes = array(); while ($attr_string != '') { // magic regular expression for extracting the attributes one at a time if (ereg("[ \n\r\t]*([^ \n\r\t=]+)(=(\"(\"|([^\"]*[^\\])\")|[^ \n\r\t\"][^ \n\r\t]*))?([ \n\r\t].*)?$", $attr_string, $regs)) { if ($regs[5] != '') { $tag->attributes[$regs[1]] = $regs[5]; } else { $tag->attributes[$regs[1]] = $regs[3]; } $attr_string = $regs[6]; } else { break; } } } // Let's check the tag against the parsing stack if ($tag->is_opening) { // building the element corresponding to the found opening tag $elem =& new VFXP_Element(); $elem->_name = $tag->name; $elem->_value = NULL; $elem->_attributes = $tag->attributes; $elem->_subelements = array(); if ($stacklen == 0) { // This is the root element $this->_docRoot =& $elem; } $tag->elem_ref =& $elem; // saving a reference to the element into the opening tag array_push($parseStack, $tag); // pushing the opening tag onto the parsing stack ++$stacklen; } if ($tag->is_closing) { --$stacklen; $tag_top = array_pop($parseStack); if ($tag_top->name != $tag->name) { print("VFXP - Closing tag not matching. Tag:".$tag->name." Pos:".$tag->pos_start . "<br>\nParse Stack:<br>\n"); print_r($parseStack); die(); } // element complete // estraction of the element value - only if non self-closing or if without subelements if (!$tag->is_opening && count($tag_top->elem_ref->_subelements) == 0) { $tag_top->elem_ref->_value = substr($this->_docContent, $tag_top->pos_end + 1, $tag->pos_start - $tag_top->pos_end - 1); // processing CDATA sections if (substr($tag_top->elem_ref->_value, 0, 9) == '<![CDATA[') { $tag_top->elem_ref->_value = substr($tag_top->elem_ref->_value, 9, -3); } } // let's add the element to the list of the subelements of the parent element if ($stacklen > 0) { $parseStack[$stacklen-1]->elem_ref->_subelements[] =& $tag_top->elem_ref; //print($tag_top->elem_ref->name . ' child of ' . $parseStack[count($parseStack)-1]->elem_ref->name . "<br>\n"); } else { // stack exausted - elaboration finished break; } } } } } // The Document Element // class VFXP_Element { // Returns the name of the element // function name() { return $this->_name; } // Returns the value of the element // function value() { return $this->_value; } // Returns true if there is at least one child with the given name // function hasChildren($elementname = NULL) { if ($elementname) { return (firstChild($elementname) != NULL); } else { return isset($this->_subelements[0]); } } // Returns a reference to the first element with the given name, or NULL if not found. // function & firstChild($elementname = NULL) { if ($elementname) { for ($pos = 0; $pos < count($this->_subelements); ++$pos) { if ($this->_subelements[$pos]->_name == $elementname) { return $this->_subelements[$pos]; } } } else { if (isset($this->_subelements[0])) { return $this->_subelements[0]; } } $tmp0 = NULL; $tmp =& $tmp0; return $tmp; } // Returns the value of the first child with the given name, or NULL if not found. // function childValue($elementname = NULL) { $elem =& $this->firstChild($elementname); if ($elem) { return $elem->_value; } else { return NULL; } } // Returns an array of references to the subelements having a given name. // function children($elementname = NULL) { if ($elementname) { $tmparr = array(); for ($pos = 0; $pos < count($this->_subelements); ++$pos) { if ($this->_subelements[$pos]->_name == $elementname) { $tmparr[] =& $this->_subelements[$pos]; } } return $tmparr; } else { return $this->_subelements; } } // Returns an associative array of couples (child-name => child-value) // function childrenAssociative() { $tmparr = array(); for ($pos = 0; $pos < count($this->_subelements); ++$pos) { $tmparr[$this->_subelements[$pos]->_name] = $this->_subelements[$pos]->_value; } return $tmparr; } // Returns a reference to the array-map of the attribute-name=>attribute-value pairs // function & attributes() { return $this->_attributes; } // Returns the value of the given attribute, or NULL if not found // function attributeValue($attributename) { if (isset($this->_attributes[$attributename])) { return $this->_attributes[$attributename]; } else { return NULL; } } var $_name; var $_value; // string value, or NULL if self-closing tag of if has children var $_attributes; // attributes array-map var $_subelements; // subelements array } // Temporary tag objects for parsing // class VFXP_Tag { var $pos_start; // first tag character var $pos_end; // last tag character var $is_opening; var $is_closing; var $name; var $attributes; // array-map of the tag attributes var $elem_ref; // reference to the corresponding element } ?> Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/ Share on other sites More sharing options...
oni-kun Posted April 5, 2010 Share Posted April 5, 2010 Apparently on line 42 there is a non-object. Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/#findComment-1037025 Share on other sites More sharing options...
maxudaskin Posted April 5, 2010 Author Share Posted April 5, 2010 Apparently on line 42 there is a non-object. The thing is, if you see, it is referring to the variable $element. $element has it's value (a reference to $rootelem) passed down. I had tested this outside of a class and it worked fine. Here is that code: <?php require_once($_SERVER['DOCUMENT_ROOT'] .'/include/classes/VFXP.inc.php'); $xmldoc = new VFXP_Document(); $xmldoc->parseFromFile($_SERVER['DOCUMENT_ROOT'] .'/include/config/menu.xml'); $rootelem =& $xmldoc->rootElement(); function spaces($n) { $out = ''; for ($p = 0; $p < $n; ++$p) { $out .= ' '; } return $out; } function recursive_print(&$element, $level = 0) { $out = ''; $out .= spaces($level* . 'Begin Element' . "\n"; $out .= spaces($level* . '-------Name: ' . $element->name() . "\n"; $out .= spaces($level* . '------Value: ' . $element->value() . "\n"; $out .= spaces($level* . '-Attributes: ' . "\n"; foreach ($element->attributes() as $key => $val) { $out .= spaces($level*8+ . "[{$key}] => $val" . "\n"; } $out .= spaces($level* . '---Children: ' . "\n"; foreach ($element->children() as $child) { $out .= recursive_print($child, $level + 1); } $out .= spaces($level* . 'End Element' . "\n"; return $out; } function elementsToArray(&$element) { $count = 0; foreach ($element->attributes() as $key => $val) { $atts[$key] = $val; } foreach ($element->children() as $child) { $children[$count] = elementsToArray($child); $count++; } $arr = array( '0' =>$element->name(), '1' => $element->value(), '2'=>$atts, '3'=>$children); return $arr; } ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>VFXP Test</title> </head> <body> <pre> <?php //print_r($rootelem); $arr = elementsToArray($rootelem); print_r ($arr); ?> </pre> </body> </html> Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/#findComment-1037289 Share on other sites More sharing options...
KevinM1 Posted April 5, 2010 Share Posted April 5, 2010 Some thoughts/observations/suggestions/questions: 1. Are you sure that $element is, itself, an object? 2. In your class, you have parseElements($type), yet you never do anything with $type. 3. Since your object already contains $rootelem, you don't need to pass it into the argument list for elementsToArray. So, do something like: function parseElements($type) { // do something with $type return $this->elementsToArray(); } function elementsToArray() { // if $this->rootelem exists, run the function, else, error } Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/#findComment-1037303 Share on other sites More sharing options...
maxudaskin Posted April 5, 2010 Author Share Posted April 5, 2010 2. In your class, you have parseElements($type), yet you never do anything with $type. The class functions are not complete yet. I ran into this error and stopped coding to problem solve. I took your advice in #3, but I'm still getting this error :/ Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/#findComment-1037330 Share on other sites More sharing options...
maxudaskin Posted April 5, 2010 Author Share Posted April 5, 2010 I made the suspect variables local to the function parseElements which has fixed the issue. Thank you all for your time and help. Link to comment https://forums.phpfreaks.com/topic/197599-oop-error-calling-function-on-object/#findComment-1037341 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.