I've defined an abstract superclass in one file and a subclass in another. I have required the super-classes file and the stack trace reports to find an include it.
However, it then returns an error when it hits the 'extends' line: Fatal error: Class 'HTMLBuilder' not found in View/Markup/HTML/HTML4.01/HTML4_01Builder.php on line 7
.
I had this working with another class tree that uses factories a moment ago. I just added the builder layer in between the factories and the consumer. The factory layer looked almost exactly the same in terms of includes and dependencies.
So that makes me think I must have done something silly that's causes the HTMLBuilder.php file to not be included correctly or interpreted correctly or some such.
Here's the full stack trace (paths slightly altered):
# Time Memory Function Location
1 0.0001 53904 {main}( ) ../index.php:0
2 0.0002 67600 require_once( 'View/Page.php' ) ../index.php:3
3 0.0003 75444 require_once( 'View/Sections/SectionFactory.php' ) ../Page.php:4
4 0.0003 81152 require_once( 'View/Sections/HTML/HTMLSectionFactory.php' ) ../SectionFactory.php:3
5 0.0004 92108 require_once( 'View/Sections/HTML/HTMLTitlebarSection.php' ) ../HTMLSectionFactory.php:5
6 0.0005 99716 require_once( 'View/Markup/HTML/HTMLBuilder.php' ) ../HTMLTitlebarSection.php:3
7 0.0005 103580 require_once( 'View/Markup/MarkupBuilder.php' ) ../HTMLBuilder.php:3
8 0.0006 124120 require_once( 'View/Markup/HTML/HTML4.01/HTML4_01Builder.php' ) ../MarkupBuilder.php:3
Here's the code in question:
Parent class (View/Markup/HTML/HTMLBuilder.php):
<?php
require_once('View/Markup/MarkupBuilder.php');
abstract class HTMLBuilder extends MarkupBuilder {
public abstract function getLink($text, $href);
public abstract function getImage($src, $alt);
public abstract function getDivision($id, array $classes=NULL, array $children=NULL);
public abstract function getParagraph($text, array $classes=NULL, $id=NULL);
}
?>
Child Class, (View/Markup/HTML/HTML4.01/HTML4_01Builder.php):
<?php
require_once('HTML4_01Factory.php');
require_once('View/Markup/HTML/HTMLBuilder.php');
class HTML4_01Builder extends HTMLBuilder {
private $factory;
public function __construct() {
$this->factory = new HTML4_01Factory();
}
public function getLink($href, $text) {
$link = $this->factory->getA();
$link->addAttribute('href', $href);
$link->addChild($this->factory->getText($text));
return $link;
}
public function getImage($src, $alt) {
$image = $this->factory->getImg();
$image->addAttribute('src', $src);
$image->addAttribute('alt', $alt);
return $image;
}
public function getDivision($id, array $classes=NULL, array $children=NULL) {
$div = $this->factory->getDiv();
$div->setID($id);
if(!empty($classes)) {
$div->addClasses($classes);
}
if(!empty($children)) {
$div->addChildren($children);
}
return $div;
}
public function getParagraph($text, array $classes=NULL, $id=NULL) {
$p = $this->factory->getP();
$p->addChild($this->factory->getText($text));
if(!empty($classes)) {
$p->addClasses($classes);
}
if(!empty($id)) {
$p->setID($id);
}
return $p;
}
}
?>
Note that, in the trace, HTMLBuilder.php requires MarkupBuilder.php requires HTML4_01Builder.php. You've got an include cycle. When HTML4_01Builder
is defined, PHP hasn't finished processing HTMLBuilder.php. In particular, it hasn't reached the beginning of the abstract class HTMLBuilder
definition.
There's no need to include a descendent class when defining the ancestor. PHP uses late binding of class names, so the descendent only needs to exist by the time the methods are invoked.
MarkupBuilder.php:
<?php
// unnecessary:
//require_once('View/Markup/HTML/HTML4.01/HTML4_01Builder.php');
class MarkupBuilder {
static public function getInstance(...) {
...
return new HTML4_01Builder(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With