PHP doesn't really support method overloading, so it's not all that simple to realize, but there are ways.
Why provide static and non-static?
What I would ask myself first though is if it is really needed to offer both static and non-static approaches. It seems overly complicated, possibly confusing to the users of your color class, and doesn't seem to add all that many benefits. I would just go with the non-static approach and be done with it.
Static Factory Class
What you basically want are static factory methods, so you could create an extra class that realizes this:
class Color {
private $color;
public function __construct($color)
{
$this->color = $color;
}
public function darken($by)
{
// $this->color = [darkened color];
return $this;
}
}
class ColorFactory {
public static function darken($color, $by)
{
$color = new Color($color);
return $color->darken($by);
}
}
An alternative would be to put the static method inside Color
and give it a different name, eg createDarken
(this should be the same each time, so all static factory methods would be called createX
for user convenience).
callStatic
Another possibility is to use the magic methods __call
and __callStatic
. The code should look something like this:
class Color {
private $color;
public function __construct($color)
{
$this->color = $color;
}
// note the private modifier, and the changed function name.
// If we want to use __call and __callStatic, we can not have a function of the name we are calling in the class.
private function darkenPrivate($by)
{
// $this->color = [darkened color];
return $this;
}
public function __call($name, $arguments)
{
$functionName = $name . 'Private';
// TODO check if $functionName exists, otherwise we will get a loop
return call_user_func_array(
array($this, $functionName),
$arguments
);
}
public static function __callStatic($name, $arguments)
{
$functionName = $name . 'Private';
$color = new Color($arguments[0]);
$arguments = array_shift($arguments);
// TODO check if $functionName exists, otherwise we will get a loop
call_user_func_array(
array($color, $functionName),
$arguments
);
return $color;
}
}
Note though that this is somewhat messy. Personally, I would not use this approach, because it's not that nice for the users of your class (you can't even have proper PHPDocs). It is the simplest for you as programmer though, because you do not need to add a lot of extra code when adding new functions.
$color->darken()->darken()->saturate()
etc. – Appendectomy$color->darken(0.1);
changes the state of the$color$
object? Yes, then it's not immutable. It was just unclear, because you assign the return value to$darkenColor
, suggesting that you are returning a new object, instead of changing the state of the existing one (and possibly returning itself). – UnpracticalColor::darken
supposed to return? An object instance or a string? If an object instance, there's basically no advantage to having a static method, as the same can be had with(new Color('#fff'))->darken(0.1)
. That's virtually the same code with ever so slightly different syntax. – Dispassion