Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP7 - Uncaught Error: Access to undeclared static property

Tags:

php

I've been attempting to play with this dicecalculator found here: https://github.com/ringmaster/dicecalc

Previously everything functioned as expected, I could "roll" 3d6, 3d6+2, 1d12, etc without any problems.

After upgrading my vps to Ubuntu 16.04 with php7 on it, I started to receive the following error:

mod_fcgid: stderr: PHP Fatal error: Uncaught Error: Access to undeclared static property: DiceCalc\CalcOperation::$operators in /public_html/dice/src/DiceCalc/CalcOperation.php:34

I've done a few searches on Access to undeclared static property to no avail. I've tried returning static:: on each of them. Here's the CalcOperation.php it's referencing:

<?php
/**
 * Class CalcOperation
 *
 * @package DiceCalc
 * @author  Owen Winkler <[email protected]>
 * @license MIT http://opensource.org/licenses/MIT
 */
namespace DiceCalc;
class CalcOperation {
    /**
     * @param  string $operator
     * @param $operand2
     * @param $operand1
     *
     * @throws \Exception
     * @return bool|number
     */
    public function calc($operator, $operand1, $operand2) {
        $operators = array(
            '+' => 'add',
            '*' => 'multiply',
            '=' => 'equalto',
            '<' => 'lessthan',
            '>' => 'greaterthan',
            '^' => 'exponent',
            '/' => 'divide',
            '-' => 'subtract'
        );
        if (isset($operators[$operator])) {
            return self::$operators[$operator](self::reduce($operand1), self::reduce($operand2));
        }
        throw new \Exception('Unknown operator "' . $operator . '".');
    }
    /**
     * @param $operand
     *
     * @return number|string
     * @throws \Exception
     */
    public function reduce($operand) {
        if (is_numeric($operand)) {
            return $operand;
        } elseif ($operand instanceof Calc) {
            return $operand();
        }
        throw new \Exception('This is not a number');
    }
    /**
     * @param  number      $operand1
     * @param  number      $operand2
     *
     * @return bool|number
     */
    public function add($operand1, $operand2) {
        return $operand1 + $operand2;
    }
    /**
     * @param  number      $operand1
     * @param  number      $operand2
     *
     * @return bool|number
     */
    public function multiply($operand1, $operand2) {
        return $operand1 * $operand2;
    }
    /**
     * @param  number      $operand1
     * @param  number      $operand2
     *
     * @return bool|number
     */
    public function subtract($operand1, $operand2) {
        return $operand1 - $operand2;
    }
    /**
     * @param  number    $operand1
     * @param  number    $operand2
     *
     * @return bool|number
     */
    public function divide($operand1, $operand2) {
        return $operand1 / $operand2;
    }
    /**
     * @param  number      $operand1
     * @param  number      $operand2
     *
     * @return bool|number
     */
    public function exponent($operand1, $operand2) {
        return pow($operand1, $operand2);
    }
    /**
     * @param  number $operand1
     * @param  number $operand2
     *
     * @return bool
     */
    public function greaterthan($operand1, $operand2) {
        return $operand1 > $operand2;
    }
    /**
     * @param  number $operand1
     * @param  number $operand2
     *
     * @return bool
     */
    public function lessthan($operand1, $operand2) {
        return ($operand1 < $operand2);
    }
    /**
     * @param  number $operand1
     * @param  number $operand2
     *
     * @return bool
     */
    public function equalto($operand1, $operand2) {
        return ($operand1 == $operand2);
    }
}

And here's the line that calls the class:

$stack[] = CalcOperation::calc($step, $r2, $r1);

I'm just beginning to wrap my head around classes etc so I'm not sure how to fix this. I've tried switching the return self:: to return static:: among a few other things I've found by searching on here. I'm just stuck now. Anyone able to help?

like image 422
Micheal Luttrull Avatar asked May 31 '16 21:05

Micheal Luttrull


2 Answers

This is caused by a change in the way PHP 7.0+ parses code:

Indirect access to variables, properties, and methods will now be evaluated strictly in left-to-right order, as opposed to the previous mix of special cases. The table below shows how the order of evaluation has changed.

enter image description here

Just change:

return self::$operators[$operator](self::reduce($operand1), self::reduce($operand2));

To:

return self::{$operators[$operator]}(self::reduce($operand1), self::reduce($operand2));

In PHP7, self::$operators[$operator] is interperated as "the $operator key of the self::$operators array" (which does not exist).

like image 192
Will Avatar answered Nov 03 '22 22:11

Will


To define $operators as a static property of the class :

class CalcOperation {

    static $operators = array(
            '+' => 'add',
            '*' => 'multiply',
            '=' => 'equalto',
            '<' => 'lessthan',
            '>' => 'greaterthan',
            '^' => 'exponent',
            '/' => 'divide',
            '-' => 'subtract'
        );

 /**
     * @param  string $operator
     * @param $operand2
     * @param $operand1
     *
     * @throws \Exception
     * @return bool|number
     */
    public function calc($operator, $operand1, $operand2) {
...
}
...//rest of class...

Then access the $operators throughout your class using self::$operators

like image 1
Dan Avatar answered Nov 03 '22 21:11

Dan