Вы всегда можете использовать метод First как статический, а остальные как методы экземпляра:
$value = Math::toValue(5)->add(3)->subtract(2)->add(8)->result();
Или еще лучше:
$value = Math::eval(Math::value(5)->add(3)->subtract(2)->add(8));
class Math {
public $operation;
public $operationValue;
public $args;
public $allOperations = array();
public function __construct($aOperation, $aValue, $theArgs)
{
$this->operation = $aOperation;
$this->operationValue = $aValue;
$this->args = $theArgs;
}
public static function eval($math) {
if(strcasecmp(get_class($math), "Math") == 0){
$newValue = $math->operationValue;
foreach ($math->allOperations as $operationKey=>$currentOperation) {
switch($currentOperation->operation){
case "add":
$newvalue = $currentOperation->operationValue + $currentOperation->args;
break;
case "subtract":
$newvalue = $currentOperation->operationValue - $currentOperation->args;
break;
}
}
return $newValue;
}
return null;
}
public function add($number){
$math = new Math("add", null, $number);
$this->allOperations[count($this->allOperations)] &= $math;
return $this;
}
public function subtract($number){
$math = new Math("subtract", null, $number);
$this->allOperations[count($this->allOperations)] &= $math;
return $this;
}
public static function value($number){
return new Math("value", $number, null);
}
}
Просто к вашему сведению .. Я написал это на макушке (прямо здесь, на сайте). Таким образом, это может не работать, но это идея. Я мог бы также сделать рекурсивный вызов метода для eval, но я подумал, что это может быть проще. Пожалуйста, дайте мне знать, если вы хотите, чтобы я уточнил или предоставил любую другую помощь.