Here is what I am trying to achieve:
class Parser { protected $src; public function __construct($src) { $this->src = $src; } } class Format1Parser extends Parser { public function Parse() { // Parsing format 1 // ... } } class Format2Parser extends Parser { public function Parse() { // Parsing format 2 // ... } } class ParserFactory { public static function GetParser($src) { $header = substr($src,0,7); if ( $header == "format1" ) { return( new Format1Parser($src) ); } if ( $header == "format2" ) { return( new Format2Parser($src) ); } return(false); } } $parser = ParserFactory::GetParser( file_get_contents("file.txt") ); $parser->Parse();
First, I would use a suffix (Parser_Format1) instead of a prefix (Format1Parser), because IMHO it's clearer.
As for the factory method itself, you could use dynamic instantiation:
class ParserFactory {
static public function getParser($src) {
// may want to change the following line, because it assumes your parser
// type is always 7 characters long.
$type = substr($src, 0, 7);
$pattern = 'Parser_%type';
$className = str_replace('%type', $type, $pattern);
if (!class_exists($className)) {
throw new InvalidArgumentException("Invalid parser $type");
return new $className;
}
}
Another thing, your Parser class should be abstract and define an abstract function Parse()
:
abstract class Parser {
protected $src;
public function __construct($src)
{
$this->src = $src;
}
abstract public function Parse();
}
Defining abstract methods within a base abstract class ensure that most errors (i.e.: a missing Parse
method) are caught when the class is parsed (at the beginning of the program), as opposed as to when it's called (in the middle of runtime).