php - 当小数前面没有数值时, Twig 假设标点符号/字符串?

标签 php symfony types twig

考虑以下因素:

A) {{ form.vars.attr.dimensions.width * .1875 }}
B) {{ form.vars.attr.dimensions.width * 0.1875 }}

其中 form.vars.attr.dimensions.width 是一个整数。

以下是 form.vars.attr.dimensions 的转储。

array:2 [
  "width" => 1600
  "height" => 478
]

示例 A 将抛出以下异常:

Unexpected token "punctuation" of value ".".

示例 B 工作正常并输出 300.0

我知道它很可能将值解释为字符串,但我的问题是为什么?我认为,由于它没有被引用,所以它不应该被视为字面意思。我意识到我可以用 number_format、前面的零等来解决这个问题。我真的很好奇为什么 Twig 不能正确识别该小数。或者也许我还遗漏了其他东西。

此外,在普通 PHP 中应用相同的逻辑不会产生这种情况:

<?php
  $val = 1600;
  var_dump($val * .1875);
  // float(300)
?>

最佳答案

.1875中的.在模板渲染的第一步中已经被识别为标点符号。

Twig 文档在 Twig Internals 中介绍了此过程。 。第一步:

The lexer tokenizes a template source code into a token stream

在文档部分The Lexer ,它展示了一种将某些源代码转换为 token 流的方法。如果我们用你的两个例子来做到这一点:

$ex1 = '{{ form.vars.attr.dimensions.width * 0.1875 }}';
$ex2 = '{{ form.vars.attr.dimensions.width * .1875 }}';

$stream1 = $twig->tokenize(new Twig_Source($ex1, 'example1'));
$stream2 = $twig->tokenize(new Twig_Source($ex2, 'example2'));

输出如下:

Example 1:               Example 2:

VAR_START_TYPE()         VAR_START_TYPE()
NAME_TYPE(form)          NAME_TYPE(form)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(vars)          NAME_TYPE(vars)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(attr)          NAME_TYPE(attr)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(dimensions)    NAME_TYPE(dimensions)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(width)         NAME_TYPE(width)
OPERATOR_TYPE(*)         OPERATOR_TYPE(*)
NUMBER_TYPE(0.1875)      PUNCTUATION_TYPE(.)     <----
VAR_END_TYPE()           NUMBER_TYPE(1875)
EOF_TYPE()               VAR_END_TYPE()
                         EOF_TYPE()

在该过程的下一步中,解析器尝试将标记流转换为树,并且标点符号标记在运算符之后没有意义,这会导致您看到的错误。

至于为什么 Twig 词法分析器在第一步中以这种方式工作,如果您检查 the source ,表达式词法分析器逐步遍历输入字符串,依次应用各种正则表达式。数字正则表达式是

'/[0-9]+(?:\.[0-9]+)?/A'

.1875 不匹配,在后续步骤中,. 被识别为标点符号。

如果您试图找出一种方法让它使用不带前导零的十进制数字,那么这个答案没有帮助,但听起来您更感兴趣的是了解它是如何工作的,所以希望这个会有帮助的。

关于php - 当小数前面没有数值时, Twig 假设标点符号/字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47042126/

相关文章:

php - 拖放文件上传不起作用

php - 上传图片时调整图片大小

php - 使用错误的表别名生成查询的原则

haskell - 类型族实例的类型类约束

javascript - TypeScript 第二个参数类型基于第一个参数类型

php - 如何解决 Moodle 3.8.4 上的 ddl 执行错误?

php - 如何从带有嵌入 JS 代码的 PHP 变量的 PHP 文件输出 Javascript?

php - 使用 symfony4 和 doctrine 设置多个数据库时如何修复在两个数据库上运行的迁移

php - 将类继承与容器感知的抽象基类结合使用

list - 在 Dart 中,List.from 和 .of、Map.from 和 .of 之间有什么区别?