有这个方法:
/**
* @param array $data
* @return bool
* @throws \yii\base\Exception
*/
public function trySave($data = [])
{
if (
$this->load($data) &&
$this->validate() &&
$this->unique_id = $this->getUniqueId() &&
$this->password_hash =
Yii::$app->security->generatePasswordHash($this->password) &&
$this->save(false)
) {
return true;
}
return false;
}
保存时会$this->save(false)抛出一个异常,unique_id并且password_hash没有默认值,即它们是null.
为了调试这种情况,我重写了这样的方法:
/**
* @param array $data
* @return bool
* @throws \yii\base\Exception
*/
public function trySave($data = [])
{
if ($this->load($data)) {
if ($this->validate()) {
if ($this->unique_id = $this->getUniqueId()) {
if (
$this->password_hash =
Yii::$app->security->generatePasswordHash(
$this->password
)
) {
if ($this->save(false)) {
return true;
}
}
}
}
}
return false;
}
我很惊讶第二个选项奏效了。
我不明白为什么unique_id在password_hash第一种情况下也没有设置属性?
目前,我发现在第一种情况下,yii2/db/BaseActiveRecord::__set($name, $value)尝试将值写入指定属性时没有调用该方法:
// ...
$this->unique_id = $this->getUniqueId() &&
$this->password_hash =
Yii::$app->security->generatePasswordHash($this->password) &&
// ...
看起来这是运算符优先级和关联性的问题。显然,使用 && 您的代码被解释器感知如下:
因此,unique_id 和 password_hash 没有设置,因为 要计算它们,您必须首先执行
$this->save(). Yand的优先级低于 y=(与 不同&&),如链接中的表所示,这可能会导致执行顺序发生变化。但是,我无法在我的机器上重现这个 - && 正确划分执行,并且所有分支都为我依次执行(也许这完全是关于解释器版本的差异)。如上所述,如果您没有尝试将与此无关的事物置于这种状态,这一切都不会发生。使用提前终止会容易得多:
一切都与操作员有关
&&:如果将其替换为and,则第一个选项开始起作用。操作人员
&&和工作上and有细微差别。如果有人解释得更详细,那么“不客气”;但就目前而言,这至少是某种答案。