类 CaseStatementExpression
用流式 API 表示 SQL case 语句
属性摘要
-
$_typeMap protected
Cake\Database\TypeMap|null
-
$else protected
Cake\Database\ExpressionInterface|object|scalar|null
else 部分的结果值。
-
$elseType protected
string|null
else 部分的结果类型。
-
$isSimpleVariant protected
bool
是否是一个简单的 case 表达式。
-
$returnType protected
string|null
返回类型。
-
$validClauseNames protected
list<string>
可用于
clause()
方法的子句名称列表。 -
$value protected
Cake\Database\ExpressionInterface|object|scalar|null
case 值。
-
$valueType protected
string|null
case 值类型。
-
$when protected
arrayCake\Database\Expression\WhenThenExpression>
WHEN ... THEN ...
表达式。 -
$whenBuffer protected
array|null
用于
then()
的值和类型缓冲区。
方法摘要
-
__clone() public
克隆内部表达式对象。
-
__construct() public
构造函数。
-
_castToExpression() protected
如果类型类实现了 ExpressionTypeInterface,则有条件地将传递的值转换为 ExpressionInterface 对象。 否则,返回未修改的值。
-
_requiresToExpressionCasting() protected
返回一个数组,其中包含需要将值转换为表达式的类型,这些类型来自作为参数传递的类型名称列表。
-
clause() public
返回给定子句的可用数据。
-
compileNullableValue() protected
将可空值编译为 SQL。
-
else() public
设置
ELSE
结果值。 -
getDefaultTypes() public
获取当前类型映射的默认类型。
-
getReturnType() public
返回此表达式将返回的抽象类型。
-
getTypeMap() public
返回现有的类型映射。
-
inferType() protected
推断给定值的抽象类型。
-
setDefaultTypes() public
覆盖实现对象中字段的默认类型映射。
-
setReturnType() public
设置此表达式将返回的抽象类型。
-
setTypeMap() public
如果 $typeMap 是一个数组,则创建一个新的 TypeMap,否则用给定的 TypeMap 交换它。
-
sql() public
将节点转换为 SQL 字符串片段。
-
then() public
设置最后一个使用
when()
打开的WHEN ... THEN ...
语句的THEN
结果值。 -
traverse() public
递归地遍历表达式的每个部分,并对表达式树的每一层执行回调,将当前正在迭代的表达式的实例作为第一个参数传递。
-
when() public
设置
WHEN ... THEN ...
表达式的WHEN
值,或者设置一个包含WHEN
值和THEN
值的自包含表达式。
方法详情
__construct() ¶ public
__construct(Cake\Database\ExpressionInterface|object|scalar|null $value = null, string|null $type = null)
构造函数。
当设置值时,生成的语法为 CASE case_value WHEN when_value ... END
(简单 case),其中 when_value
与 case_value
进行比较。
当没有设置值时,生成的语法为 CASE WHEN when_conditions ... END
(搜索 case),其中条件包含比较。
注意 null
是一个有效的 case 值,因此只有在您确实想要创建简单的 case 表达式变体时才应传递它!
参数
-
Cake\Database\ExpressionInterface|object|scalar|null
$value optional case 值。
-
string|null
$type optional case 值类型。 如果没有提供类型,则将尝试从值中推断类型。
_castToExpression() ¶ protected
_castToExpression(mixed $value, string|null $type = null): mixed
如果类型类实现了 ExpressionTypeInterface,则有条件地将传递的值转换为 ExpressionInterface 对象。 否则,返回未修改的值。
参数
-
mixed
$value 要转换为 ExpressionInterface 的值
-
string|null
$type optional 类型名称
返回
mixed
_requiresToExpressionCasting() ¶ protected
_requiresToExpressionCasting(array $types): array
返回一个数组,其中包含需要将值转换为表达式的类型,这些类型来自作为参数传递的类型名称列表。
参数
-
array
$types 类型名称列表
返回
array
clause() ¶ public
clause(string $clause): Cake\Database\ExpressionInterface|object|arrayCake\Database\Expression\WhenThenExpression>|scalar|null
返回给定子句的可用数据。
可用的子句
以下子句名称可用
value
:CASE case_value WHEN ...
表达式的 case 值。when
:WHEN ... THEN ...
表达式数组。else
:ELSE
结果值。
参数
-
string
$clause 要获取的子句名称。
返回
Cake\Database\ExpressionInterface|object|arrayCake\Database\Expression\WhenThenExpression>|scalar|null
抛出
InvalidArgumentException
如果给定的子句名称无效。
compileNullableValue() ¶ protected
compileNullableValue(Cake\Database\ValueBinder $binder, Cake\Database\ExpressionInterface|object|scalar|null $value, string|null $type = null): string
将可空值编译为 SQL。
参数
-
Cake\Database\ValueBinder
$binder 要使用的值绑定器。
-
Cake\Database\ExpressionInterface|object|scalar|null
$value 要编译的值。
-
string|null
$type optional 值类型。
返回
string
else() ¶ public
else(Cake\Database\ExpressionInterface|object|scalar|null $result, string|null $type = null): $this
设置 ELSE
结果值。
参数
-
Cake\Database\ExpressionInterface|object|scalar|null
$result 结果值。
-
string|null
$type optional 结果类型。 如果没有提供类型,则将尝试从值中推断类型。
返回
$this
抛出
LogicException
如果在调用此方法之前需要关闭 `then()` 调用。
InvalidArgumentException
如果 `$result` 参数既不是标量值,也不是对象,也不是 `\Cake\Database\ExpressionInterface` 的实例,也不是 `null`。
getDefaultTypes() ¶ public
getDefaultTypes(): array<int|string, string>
获取当前类型映射的默认类型。
返回
array<int|string, string>
getReturnType() ¶ public
getReturnType(): string
返回此表达式将返回的抽象类型。
如果未通过 setReturnType()
显式设置类型,则此方法将尝试从 then()
和 else()
调用的结果类型中获取类型。所有类型必须相同才能正常工作,否则类型将默认为 string
。
返回
string
另请参阅
inferType() ¶ protected
inferType(mixed $value): string|null
推断给定值的抽象类型。
参数
-
mixed
$value 推断类型的值。
返回
string|null
setDefaultTypes() ¶ public
setDefaultTypes(array<int|string, string> $types): $this
覆盖实现对象中字段的默认类型映射。
如果您需要设置在查询中的多个函数/表达式之间共享的类型映射,则此方法很有用。
要添加默认值而不会覆盖现有值,请使用 getTypeMap()->addDefaults()
参数
-
array<int|string, string>
$types 要设置的类型数组。
返回
$this
另请参阅
setReturnType() ¶ public
setReturnType(string $type): $this
设置此表达式将返回的抽象类型。
如果没有通过此方法显式设置类型,则 getReturnType()
方法将尝试从 then()
和 else()
调用的结果类型中推断类型。
参数
-
string
$type 要使用的类型名称。
返回
$this
setTypeMap() ¶ public
setTypeMap(Cake\Database\TypeMap|array $typeMap): $this
如果 $typeMap 是一个数组,则创建一个新的 TypeMap,否则用给定的 TypeMap 交换它。
参数
-
Cake\Database\TypeMap|array
$typeMap 如果为数组,则创建 TypeMap,否则设置给定的 TypeMap
返回
$this
sql() ¶ public
sql(Cake\Database\ValueBinder $binder): string
将节点转换为 SQL 字符串片段。
参数
-
Cake\Database\ValueBinder
$binder
返回
string
then() ¶ public
then(Cake\Database\ExpressionInterface|object|scalar|null $result, string|null $type = null): $this
设置最后一个使用 when()
打开的 WHEN ... THEN ...
语句的 THEN
结果值。
基于顺序的语法
此方法只能在之前使用 when()
方法使用除闭包或 \Cake\Database\Expression\WhenThenExpression
实例以外的值调用时调用。
$case
->when(['Table.column' => true])
->then('Yes')
->when(['Table.column' => false])
->then('No')
->else('Maybe');
以下所有操作都会导致异常
$case
->when(['Table.column' => true])
->when(['Table.column' => false])
// ...
$case
->when(['Table.column' => true])
->else('Maybe')
// ...
$case
->then('Yes')
// ...
$case
->when(['Table.column' => true])
->then('Yes')
->then('No')
// ...
参数
-
Cake\Database\ExpressionInterface|object|scalar|null
$result 结果值。
-
string|null
$type optional 结果类型。 如果没有提供类型,则将尝试从值中推断类型。
返回
$this
抛出
LogicException
如果
when()
之前没有使用除闭包或 \Cake\Database\Expression\WhenThenExpression
实例以外的值调用。traverse() ¶ public
traverse(Closure $callback): $this
递归地遍历表达式的每个部分,并对表达式树的每一层执行回调,将当前正在迭代的表达式的实例作为第一个参数传递。
参数
-
Closure
$callback
返回
$this
when() ¶ public
when(Cake\Database\ExpressionInterfaceClosure|object|array|scalar $when, array<string, string>|string|null $type = null): $this
设置 WHEN ... THEN ...
表达式的 WHEN
值,或者设置一个包含 WHEN
值和 THEN
值的自包含表达式。
基于顺序的语法
当传递除自包含 \Cake\Database\Expression\WhenThenExpression
实例以外的值时,WHEN ... THEN ...
语句必须使用 then()
调用关闭,然后再再次调用 when()
或 else()
。
$queryExpression
->case($query->identifier('Table.column'))
->when(true)
->then('Yes')
->when(false)
->then('No')
->else('Maybe');
自包含表达式
当传递 \Cake\Database\Expression\WhenThenExpression
实例时,无论是直接传递还是通过可调用对象传递,都不需要使用 then()
关闭此对象,而是使用 \Cake\Database\Expression\WhenThenExpression::then()
关闭 \Cake\Database\Expression\WhenThenExpression
对象上的语句。
可调用对象将接收 \Cake\Database\Expression\WhenThenExpression
实例,并且必须返回一个实例,无论是同一个对象还是自定义对象。
$queryExpression
->case()
->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
return $whenThen
->when(['Table.column' => true])
->then('Yes');
})
->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
return $whenThen
->when(['Table.column' => false])
->then('No');
})
->else('Maybe');
类型处理
通过 $type
参数提供的类型将与为该表达式设置的类型映射合并。当使用 $when
的可调用对象时,可调用对象接收到的 \Cake\Database\Expression\WhenThenExpression
实例将继承该类型映射,但是在此处传递的类型不会在使用可调用对象的情况下合并,而是必须在 \Cake\Database\Expression\WhenThenExpression::when()
中传递类型。
$queryExpression
->case()
->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
return $whenThen
->when(['unmapped_column' => true], ['unmapped_column' => 'bool'])
->then('Yes');
})
->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
return $whenThen
->when(['unmapped_column' => false], ['unmapped_column' => 'bool'])
->then('No');
})
->else('Maybe');
用户数据安全
当传递用户数据时,请注意允许传递用户定义的数组是一个潜在的 SQL 注入漏洞,因为它允许原始 SQL 泄露!
以下是必须避免的不安全用法
$case
->when($userData)
上述内容的安全变体是为该值定义单个类型
$case
->when($userData, 'integer')
这样,当为该值传递数组时,就会触发异常,从而防止原始 SQL 泄露,并且所有其他类型的值都将强制绑定为整数。
另一种安全传递用户数据的方法是在使用条件数组时,只在数组条目值的左侧传递用户数据,这会导致它们被绑定。
$case
->when([
'Table.column' => $userData,
])
最后,数据也可以手动绑定
$query
->select([
'val' => $query->newExpr()
->case()
->when($query->newExpr(':userData'))
->then(123)
])
->bind(':userData', $userData, 'integer')
参数
-
Cake\Database\ExpressionInterfaceClosure|object|array|scalar
$when WHEN
值。当使用条件数组时,它必须与\Cake\Database\Query::where()
兼容。请注意,此参数并不完全适合与用户数据一起使用,因为用户提供的数组将允许原始 SQL 泄露!如果您打算使用用户数据,请为$type
参数传递单个类型(这会强制$when
值为非数组,然后始终绑定数据)、使用条件数组(其中用户数据仅在数组条目值的左侧传递),或者使用自定义绑定!-
array<string, string>|string|null
$type 可选 when 值类型。当使用数组样式条件时,它是一个关联数组,否则它是一个字符串。如果未提供类型,则将尝试从该值中推断类型。
返回
$this
抛出
LogicException
在这种情况下,在调用此方法之前需要关闭
then()
调用。LogicException
如果可调用对象未返回
\Cake\Database\Expression\WhenThenExpression
实例。