I have an object, KbArticle
, that originally in it's constructor, would try to return null if the SQL query that retrieves the data for its required properties came up with 0 rows. A friend told me that constructors shouldn't return null
, and that I should look into the Factory Pattern. I did and I see the benefits, so I'm wondering how I can implement this better/"properly."
Quick overview: Knowledgebase.php
is the page an end-user sees, it calls a function in factory.php
which calls the constructor in kb_fnc.php
and then it ends up creating the object back on Knowledgebase.php
if things all go well.
Knowledgebase.php
<?php
if ($kb = Factory::make('KbArticle', $_GET['a'])) {
$kb->echoNavTrail();
} else {
die('failed constructor');
}
?>
factory.php
Note: It disappoints me that apparently the functions in here have to be public
instead of private
, because my factory method is static
? This seems not ideal, or am I incorrect?
<?php
require_once('kb/kb_fnc.php');
class Factory {
public static function make($obj, $params) {
$succ = false;
switch($obj) {
case('KbArticle'):
return tryNewKnowledgebaseArticle($params);
break;
}
}
}
function tryNewKnowledgebaseArticle($id) {
try {
$kb = new KbArticle($id);
} catch (Exception $e) {
return null;
}
return $kb;
}
?>
kb_fnc.php
Note: Is throwing an exception here smart? In my quick tests yesterday, I couldn't access the custom string on the exception after it was chained back, so it seems not that useful—at least not without knowing how to log that string to console at the end or something, for debugging purposes.
class KbArticle {
function __construct($id) {
//do SQL
if (odbc_num_rows($res) > 0) {
//fill in properties with data from table
} else {
throw new Exception('KbA constructor failed SQL query');
}
}
}
My biggest questions are regarding:
- Does this look sensible?
- Can I access that custom exception string in my
factory
class, so I can ultimately encode it inJSON
for aconsole.log
for easier debugging if things go awry down the line? - The functions in my
factory
class being public instead of encapsulated as private bothers me.
$e
? \$\endgroup\$