# 运算符

This article describes Zephir’s operators. For precedence, you can check the Operator Precedence article.

Zephir’s operators are similar to the ones in PHP, and inherit some of their behaviors.

`a + b`

`a * b`
`a / b`

## 按位运算符

`a & b`

Xor (exclusive or) `a ^ b`
`~a`

``````if a & SOME_FLAG {
echo "has some flag";
}
``````

## 比较运算符

`a == b` 等于 `true`如果a在去除类型后等于b。
`a === b` 完全相同的 `true`如果a等于b，它们是相同类型的。
`a != b` 不等于 `true`如果a在去除类型后不等于b。
`a <> b` 不等于 `true`如果a在去除类型后不等于b。
`a !== b` 不一致 `true`如果a不等于b，或者它们不是同一类型。
`a < b` 小于 如果a严格小于b，则`true`
`a > b` 大于 如果a严格大于b，则`true`
`a <= b` 小于或等于 `true`如果a小于或等于b。
`a >= b` 大于或等于 `true`如果a大于或等于b。

``````if a == b {
return 0;
} else {
if a < b {
return -1;
} else {
return 1;
}
}
``````

## 逻辑运算符

`a && b`
`a || b`
`!a`

``````if a && b || !c {
return -1;
}
return 1;
``````

## 三元运算符

Zephir支持C或PHP中的三元运算符:

``````let b = a == 1 ? “x”:“y”; //如果a = 1， // b设为“x”，否则赋值为“y”
``````

## 特殊运算符

### Empty

``````let someVar = "";
if empty someVar {
echo "is empty!";
}

let someVar = "hello";
if !empty someVar {
echo "is not empty!";
}
``````

### Fetch

Fetch操作符将PHP中的一个常见操作简化为一条指令:

``````<?php

if (isset(\$myArray[\$key])) {
\$value = \$myArray[\$key];
echo \$value;
}
``````

``````if fetch value, myArray[key] {
echo value;
}
``````

‘Fetch’只返回`true`，只有在’key’是数组中的有效项的情况下进行’value’填充。

### Isset

``````let someArray = ["a": 1, "b": 2, "c": 3];
if isset someArray["b"] { // check if the array has an index "b"
echo "yes, it has an index 'b'\n";
}
``````

``````return isset this->{someProperty};
``````

Note that `isset` in Zephir works more like PHP’s function array_key_exists, `isset` in Zephir returns true even if the array index or property is null.

### Typeof

``````if (typeof str == "string") { // or !=
echo str;
}
``````

``````return typeof str;
``````

Be careful, if you want to check whether an object is ‘callable’, you always have to use `typeof` as a comparison operator, not a function.

### 类型提示

Zephir总是试图检查一个对象是否实现了方法和属性，这些方法和属性在一个被推断为对象的变量上被调用/访问:

``````let o = new MyObject();

// Zephir checks if "myMethod" is implemented on MyObject
o->myMethod();
``````

``````// Tell the compiler that "o"
// is an instance of class MyClass
let o = <MyClass> this->_myObject;
o->myMethod();
``````

``````// 始终检查属性是否为实例
// 在使用前检查
let o = <MyClass!> this->_myObject;
o->myMethod();
``````

### 分支预测提示

``````let allPaths = [];
for path in this->_paths {
if path->isAllowed() == false {
throw new App\Exception("Some error message here");
} else {
let allPaths[] = path;
}
}
``````

``````let allPaths = [];
for path in this->_paths {
if unlikely path->isAllowed() == false {
throw new App\Exception("Some error message here");
} else {
let allPaths[] = path;
}
}
``````