Next: , Previous: , Up: Overloading Operators   [Contents]


4.3 Unary Operators

SyntaxInstruction
~$aZEND_BW_NOT
!$aZEND_BOOL_NOT

A unary operator takes one operand (opline->op1), and always returns a value. Modification of the operand is allowed, provided that the operand type is IS_CV.

There’s no opcode for negation operator -$a or unary plus operator +$a, as said in #2.2, because they are compiled to multiplication by -1 and 1. In cases where they are not expected to behave identically, add some logic to the ZEND_MUL handler to workaround this.

Note that compatibility issues exists between PHP 7.3 and versions below 7.3.

PHPSyntaxInstructionOperand 1Operand 2
7.3, 7.4-$a or +$aZEND_MUL$a-1 or 1
7.1, 7.2-$a or +$aZEND_MUL-1 or 1$a

Here’s a simple example to workaround the negation operator for all major PHP versions.

int mul_handler(
    zend_execute_data *execute_data
) {
    return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv) {
        if (Z_TYPE_P(zv1) == IS_OBJECT) {
#if PHP_VERISON_ID >= 70300
            if (Z_TYPE_P(zv2) == IS_LONG && Z_LVAL_P(zv2) == -1) {
                // Handle `-$zv1`.
                return true;
            }
#endif
            // Handle `$zv1 * $zv2`.
            return true;
        } else if (Z_TYPE_P(zv2) == IS_OBJECT) {
#if PHP_VERISON_ID < 70300
            if (Z_TYPE_P(zv1) == IS_LONG && Z_LVAL_P(zv1) == -1) {
                // Handle `-$zv2`.
                return true;
            }
#endif
            // Handle `$zv1 * $zv2`.
            return true;
        }
        return false;
    });
}