PHP如何知道使用的变量类型(还是它并不知道)?

10

我在许多编程语言中没有做过太多的编程,但我知道在C(++)中,您必须声明变量类型(intchar等)。

当然,在PHP中,您不必这样做。您可以从$str =“something”; 开始,然后稍后 $str =array(“something”=>“smells”); ,并且它能正常工作。

PHP如何编译?它如何知道变量类型将是什么?它是否甚至在意变量类型?

这个问题与我正在做的任何事情都没有关系。我只是好奇。

编辑:

我需要澄清一下这个问题。

在C中,如果我说:

int y;

它为y保留了x个字节。如果y溢出,那就糟糕了。

PHP没有这种特性(至少我认为没有)。

$i = "a number";
$i = 8;
$i = 1000000000000000000;

对于编程语言来说,它们并没有区分。它怎么知道需要保留多少空间呢?或者我是在比较苹果和橙子吗?如果我的做法不正确,你有没有任何好的主题可以推荐我阅读以更好地理解呢?


1
值得注意的是,有些编程语言如Haskell,你可以写出这样的代码 x = f 1000,它会推断x的类型,根据f的类型等信息计算出它的数据类型。在编译时,它看起来更像C语言;在声明时,它看起来更像PHP语言。当然,PHP的工作方式就像theatrus所说的那样。 - Antal Spector-Zabusky
6个回答

8

既然您有C语言的经验,那么可以将PHP变量类比为以下内容:

typedef struct {
 int varType;
 void* data;
} variable_t;

当您创建一个新变量时,它将创建一个variable_t,给它一个类型标签(比如说1代表int,2代表string),并将其存储在某个列表中(按范围命名引用)。实际内容将存储在* data中。当再次访问该变量时,可以从int varType中确定类型,并对void* data采取适当的操作,例如将其用作int或string。
想象一下PHP代码片段:
 $data = 12;
 $data2 = $data + 1;
 $data = "Hello";

生成类似以下指令(伪C语言)的指令:
Line 1:
variable_t* var = new_variable(TYPE_INT, data);
store_variable("data", var);

Line 2:
variable_t* var = get_variable("data2");
if (var->varType == TYPE_INT)
   int value = 1 + *(int*)var->data);
else
   error("Can't add non int");
var = new_variable(TYPE_INT, value);
store_variable("data2", var);

Line 3:
variable_t* var = get_variable("data");
if (var)
  destroy_variable(var);
// Do like line 1, but for TYPE_STRING

这种增强型数据适用于字节码、编译或直接解释语言。

关于不同虚拟机实现(本地分配、堆分配、寄存器VM等)有更多细节。如果您真的想了解虚拟机的工作原理,最好的参考是Lua。语言非常干净,字节码非常干净,虚拟机也非常干净。PHP可能是您应该查看的最后一个实现。


2
这是一个很好的答案,正是我在寻找的。谢谢! - Jason

1
我知道这是一个旧问题,但以下是有关PHP如何处理OP提出的问题的更具体信息。
这是您要开始阅读的PHP参考页面: 变量介绍 我知道链接不是首选,但该链接应该是稳定的,我不想完全复制PHP参考文档。以下是亮点。
OP:PHP如何知道它使用的变量类型(或是否使用)?
PHP是用C编写的,并使用称为 zval 的C结构typedef以及称为 zval_value 的C union typedef来表示所有变量。
typedef struct _zval_struct {
    zvalue_value value;        /* variable value */
    zend_uint refcount__gc;    /* reference counter */
    zend_uchar type;           /* value type */
    zend_uchar is_ref__gc;     /* reference flag */
} zval;

"The engine provides a set of macros that are uniform and intuitive for accessing the various fields of a structure, in order to simplify the concept of a variable that can be of any type. PHP is a dynamic language that is loosely typed and uses reference counting and copy-on-write (COW). The engine's preference for converting or coercing variables into the required type at execution time is implicit in weak typing. Reference counting allows the engine to determine when a variable no longer has any references in the user's code, so it can free the structures associated with the variable. The zval_value is a union that can represent all the types a variable may hold. If a variable is of a single type, the appropriate field in the zval_value union represents the variable data. The zval itself holds the type, reference count, and a flag indicating whether a variable is a reference. "
"编译"是一个广义的词,可以有不同的含义,而PHP并不是以传统意义上的编译方式运行。它做了一种预编译,将源代码转换为可由处理器执行的指令(opcode)。这些opcode被缓存,防止PHP频繁解析调用的脚本。

它如何知道变量类型会是什么?它关心吗?

正如上面引用的那样,这是PHP引擎在执行时“优先将变量转换或强制转换为所需类型”的结果。基本上,PHP总是在创建变量时存储其确定的类型,但当引用变量时,PHP根据使用上下文再次确定其类型。

"PHP是弱类型的,因此引擎提供API函数来将变量从一种类型转换为另一种类型。"

引擎有一组宏用于处理zval以转换变量的类型,因此通常你不必处理这个问题。

如果您想看到zval的实际效果,可以使用以下命令进行转储:

debug_zval_dump($variableName);

1

PHP并不真正编译——它是解释执行的(转换成操作码)。

如果您尝试对某种数据类型执行无法完成的操作,它会给您一个错误。没有类型检查。


我知道我可以使用像is_numeric()这样的东西,但他是怎么知道的呢?数据类型是如何自然保持一致的?它们总是字符串,而is_numeric()在函数中通过开关进行处理吗?还是它查看大小。那更像是我要找的答案。除了有一个变量$c$c =“something”之外,PHP如何知道任何东西? - Jason
让我稍微澄清一下我的问题。 - Jason
你可以使用 gettype 来获取它。 - cambraca
@Jason 哈哈,是的,我没有注意到... 我想那里的想法是隐藏实现。 - cambraca
十六进制在哪里啊!唉,哈哈。 - Jason
显示剩余5条评论

1

即使是JS,如果我对一个未声明的变量进行操作,它也会变得不高兴。如果PHP还没有声明它,它会自动声明吗? - Jason
关于整个问题。我相信这个页面会很有帮助。 - cambraca
@cambraca - 这就是我想要的。太棒了。 - Jason
是的,http://www.php.net/manual/en/language.types.type-juggling.php,我已经链接了http://php.net/manual/en/,这是手册的主页 :) - Lajos Arpad
这是你对此的说法:“PHP.net没有讨论PHP的工作原理,只有实现。我想了解电气工程师(或计算机工程师)的水平(因为我就是这样的人)。" - Lajos Arpad
显示剩余2条评论

0
“PHP是如何编译的?它如何知道变量类型将会是什么?它是否关心?
这个问题与我正在做的任何事情都没有关系。我只是好奇。”
PHP是一种解释性语言,它不需要编译。
PHP不知道变量的类型将会是什么,因为变量的类型是由上次分配给该变量的值的类型确定的。
你可以这样做:”
$foo = 5;
var_dump($foo);
$foo = "5";
var_dump($foo);
$foo = array();
$foo[] = 0;
$foo[] = 1;
$foo[] = 2;
var_dump($foo);

正如您所看到的,每当将值分配给foo时,类型可能会更改。

PHP不关心您的变量类型,因为它是一种编程语言,没有感情。

编辑:

“我是在比较苹果和橙子吗?”

是的,您是。 在这里 您可以了解更多有关该语言的信息。

编辑2:

PHP是一种带有解释器但没有编译器的脚本语言。这意味着在PHP中,您只能获得运行时错误。如果我们考虑类型,它是一种自由的语言,因为您有权对变量进行任何操作,并且它们的类型将根据使用方式进行修改。

这些链接可能对您有用:

http://www.gidforums.com/t-11866.html

http://www.webmaster-talk.com/coding-forum/186350-fundamental-differences-between-php-c-c.html

PHP和C之间的变量作用域区别:块作用域不完全相同?

请注意,PHP是在服务器上执行的,如果您想创建客户端事件,则建议使用Javascript。


哈哈。编程语言是有讲究的。曾经忘记过分号吗?PHP.net并不会详细介绍PHP的运作方式,只会涉及实现。我希望了解更深入电气工程师(或计算机工程师)层面上的知识(因为我就是这个专业的)。 - Jason
最后一句话不必要。我不想比较JS和PHP。 我知道JS是客户端,而PHP是服务器端。感谢您挖掘这些链接。 - Jason

-1

PHP现在支持类型提示,您可以在函数定义中包含像“string”或“array”这样的内容,当脚本被解析时捕获它们以指示存在类型不匹配。


我并不是在寻找如何查找变量类型,而是想了解PHP如何知道数据类型。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接