You don't have the need to use class_alias
or declare static methods. A basic factory class can help you.
class RulesFactory
{
/*
public function __construct($validNames = array('IT', 'DE', 'EN')) {
// ...
}*/
public /*static*/ function build($rules_name)
{
$className = "Rules_" . strtoupper($rules_name);
if(class_exists($className)) {
return new $className();
} else {
throw new InvalidArgumentException("Invalid rules name given.");
}
}
}
interface Rules
{
public function myMethod();
public function getParam($name);
}
abstract class AbstractRules implements Rules
{
protected $param = [];
public function getParam($name, $default = null)
{
if (isset($this->param[$name])) {
return $this->param[$name];
} else {
return $default;
}
}
}
class Rules_IT extends AbstractRules
{
protected $param = ['MYCONST_1' => 5, 'MYCONST_2' => 3, 'MYCONST_3' => 10];
public function myMethod()
{
return 'Something';
}
}
class Rules_DE extends AbstractRules
{
protected $param = ['MYCONST_1' => 3, 'MYCONST_2' => 2, 'MYCONST_3' => 15];
public function myMethod()
{
return 'Something different';
}
}
You can use that with:
$factory = new RulesFactory();
$rules = $factory->build('IT');
echo $rules->myMethod(), "\n";
echo $rules->getParam('MYCONST_1');
You can also declare RulesFactory::build
as a static method, in that case you can use it as
RulesFactory::build('IT')->myMethod();
MISC:
Why using getParam
instead of using constants?
Because it gives you a more flexible way to define and call those parameters. Example:
abstract class AbstractRules implements Rules
{
protected $param = [];
public function getParam($name)
{
if (isset($this->param[$name])) {
return $this->param[$name];
}
throw new InvalidArgumentException("$name parameter doesn't exists.");
}
public function hasParam($name)
{
return isset($this->param[$name]);
}
public function addParam($name, $value)
{
$this->param[$name] = $value;
}
}
Static property are not associated to any particular instance/object of a class, they belong to the class itself. You may don't want this. But if you do, you can simply do this:
class Rules_IT extends AbstractRules
{
const MYCONST_1 = 5;
const MYCONST_2 = 3;
const MYCONST_3 = 10;
public function myMethod()
{
return 'Something';
}
}
$rules = (new RulesFactory())->build('IT');
echo $rules::MYCONST_1;
Why use an interface "Rules"? What is the benefit?
Interfaces are a way to represent contractual obligations. Why would I want to use Interfaces?. You could already take advantage of this with:
public function build($rules_name)
{
$className = "Rules_" . ucwords($rules_name);
if(class_exists($className)) {
$object = new $className();
if (!$object instanceof Rules) {
throw new InvalidArgumentException("$className must implement Rules interface");
}
return $object
}
throw new InvalidArgumentException("Invalid rules name given.");
}