10

我没有用很多语言做过很多编程,但我知道在 C(++) 中,你必须声明一个变量类型(int,char等)。

当然,在 PHP 中,您不必这样做。你可以$str = "something";稍后再开始$str = array("something" => "smells");,她很高兴。

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

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

编辑。

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

在 C 中,如果我说:

int y;

它为 保留 x 个字节数y。如果y溢出,坏消息。

PHP 没有这种性质(至少我不认为它有)。

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

这对语言来说都是一样的。它怎么知道要预留多少?还是我将苹果与橙子进行比较?如果我说错了,您有什么好的主题可以阅读以更好地理解吗?

4

6 回答 6

8

由于您有 C 经验,因此请考虑如下所示的 PHP 变量:

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

当你创建一个新变量时,它会创建一个variable_t,给它一个类型标签(比如说 1 代表 int,2 代表字符串),并将它存储在某个地方的列表中(按范围,按名称引用)。实际内容将存储在*data. 当再次访问该变量时,可以从 确定类型int varType,并对 采取适当的操作void* data,例如将其用作 int 或 string。

想象一下 PHP 片段:

 $data = 12;
 $data2 = $data + 1;
 $data = "Hello";

产生如下指令(伪 Cish):

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

这种类型的增强数据以字节编码、编译或直接解释语言工作。

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

于 2010-10-28T03:58:36.873 回答
1

PHP 并没有真正编译——它被解释(成操作码)。

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

于 2010-10-28T03:37:39.353 回答
1

它不编译。它是一种解释性语言,如 Javascript。

于 2010-10-28T03:38:33.977 回答
1

我意识到这是一个老问题,但这里有一些关于 PHP 如何处理 OP 提出的问题的更具体信息。

这是您想要开始的 PHP 参考页面:

变量简介

我知道链接不是首选,但该链接应该是稳定的,我不想批发复制 PHP 参考文档。以下是重点。

OP:PHP 是如何知道它使用什么类型的变量(或者确实知道)?

PHP 是用 C 语言编写的,使用 C struct typedef 调用zval以及 C union typedef 调用zval_value来表示所有变量。

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;

该引擎试图通过提供一组统一且直观的宏来访问各种字段的结构,从而掩盖可以是任何类型的变量概念的复杂性。”

“PHP 是一种动态的、松散类型的语言,它使用写时复制和引用计数。” 引用计数和写时复制 (COW) 是 PHP 使用的两个强大的概念,我不会在这里讨论,但值得一读。

弱类型隐含了引擎在执行时将变量转换或强制转换为所需类型的偏好。引用计数是当变量在用户代码中不再有任何引用时引擎可以推断的方法,因此也是能够释放与变量关联的结构。”

" zval_value 是一个联合,它可以表示一个变量可能包含的所有类型。 "

“ ...变量可以是一种类型,变量数据由 zval_value 联合中的适当字段表示。zval 本身包含类型、引用计数和一个标志,以指示变量是否为引用。

PHP是如何编译的?

“编译”是一个宽泛的词,可以有不同的含义,而 PHP 不是传统意义上的编译。它确实进行了一种预编译,将源代码转换为操作码,这些操作码是可以由处理器执行的指令。这些操作码被缓存,以防止 PHP 必须解析频繁调用的脚本。

它如何知道变量类型将是什么?它甚至在乎吗?

正如上面已经引用的那样,它是 PHP 引擎“在执行时将变量转换或强制转换为所需类型的偏好”。Baiscally PHP 确实总是存储它在创建变量时确定变量的类型,但是当引用变量时,PHP 会根据使用它的上下文再次确定类型是什么。

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

该引擎有一组宏,用于与 zval 一起转换变量的类型,因此您通常不必处理它。

如果你想看看 zvals 在行动中的样子,可以用以下方式倾倒它们:

debug_zval_dump($variableName);
于 2016-04-07T21:54:08.303 回答
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-cc.html

PHP和C的变量作用域区别:块作用域不完全一样?

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

于 2010-10-28T03:57:04.380 回答
-1

PHP 现在支持类型提示,您可以在函数定义中包含诸如“字符串”或“数组”之类的内容,这些内容在解析脚本时被捕获以指示存在类型不匹配。

于 2010-10-28T03:39:11.067 回答