当用户在PHP中调用一个函数或者类的方法时,内核会创建一个新的符号表并激活之,这也就是为什么我们无法在函数中使用在函数外定义的变量的原因(因为它们分属两个符号表,一个当前作用域的,一个全局作用域的)。如果不是在一个函数里,则全局作用域的符号表处于激活状态。
我们现在打开Zend/zend_globals.h文件,看一下_zend_execution_globals结构体,会在其中发现这么两个element:
struct _zend_executor_globals {
...
HashTable symbol_table;
HashTable *active_symbol_table;
...
};
其中的 symbol_table元素可以通过EG宏来访问,它代表着PHP的全局变量,如$GLOBALS,其实从根本上来讲,$GLOBALS不过是EG(symbol_table)的一层封装而已。EG宏在Zend\zend_globals_macros在被定义:
/* Executor */
#ifdef ZTS
# define EG(v) TSRMG(executor_globals_id, zend_executor_globals *, v)
#else
# define EG(v) (executor_globals.v)
extern ZEND_API zend_executor_globals executor_globals;
#endif
symbol_table和active_symbol_table在_zend_executor_globals里虽然都代表HashTable,但一个是真正的HashTable,而另一个是一个指针。当
我们在对HashTable进行操作的时候,往往是把它的地址传递给一些函数。所以,如果我们要对EG(symbol_table)的结果进行操作,往往
需要对它进行求址操作然后用它的地址作为被调用函数的参数。
下面我们用一段例子来解释下上面说的理论:
<?php
$foo = 'bar';
?>
上面是一段PHP语言的例子,我们创建了一个变量,并把它的值设置为'bar',在以后的代码中我们便可以使用$foo变量。相同的功能我们怎样在内核中实现呢?我们可以先构思一下步骤:
- 创建一个zval结构,并设置其类型。
- 设置值为'bar'。
- 将其加入当前作用域的符号表,只有这样用户才能在PHP里使用这个变量。
具体的代码为:.
{
zval *fooval;
MAKE_STD_ZVAL(fooval);
ZVAL_STRING(fooval, "bar", 1);
ZEND_SET_SYMBOL( EG(active_symbol_table) , "foo" , fooval);
}
首先,我们声明一个zval指针,并申请一块内存。然后通过ZVAL_STRING宏将值设置为‘bar’,最后一行的作用就是将这个zval加入到当前的符号表里去,并将其label定义成foo,这样用户就可以在代码里通过$foo来使用它了。
以下是用的宏:
#define MAKE_STD_ZVAL(zv) \
ALLOC_ZVAL(zv); \
INIT_PZVAL(zv);
/* fast cache for zval's */
#define ALLOC_ZVAL(z) \
(z) = (zval *) emalloc(sizeof(zval))
#define INIT_PZVAL(z) \
(z)->refcount__gc = 1; \
(z)->is_ref__gc = 0;
#define ZVAL_STRING(z, s, duplicate) do { \
const char *__s=(s); \
zval *__z = (z); \
Z_STRLEN_P(__z) = strlen(__s); \
Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(char*)__s);\
Z_TYPE_P(__z) = IS_STRING; \
} while (0)
#define ZEND_SET_SYMBOL(symtable, name, var) \
{ \
char *_name = (name); \
\
ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0); \
}
#define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref) \
{ \
zval **orig_var; \
\
if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS \
&& PZVAL_IS_REF(*orig_var)) { \
Z_SET_REFCOUNT_P(var, Z_REFCOUNT_PP(orig_var)); \
Z_SET_ISREF_P(var); \
\
if (_refcount) { \
Z_SET_REFCOUNT_P(var, Z_REFCOUNT_P(var) + _refcount - 1); \
} \
zval_dtor(*orig_var); \
**orig_var = *(var); \
FREE_ZVAL(var); \
} else { \
Z_SET_ISREF_TO_P(var, _is_ref); \
if (_refcount) { \
Z_SET_REFCOUNT_P(var, _refcount); \
} \
zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL); \
} \
}
分享到:
相关推荐
理解并熟练使用PHP变量是进行Web开发的基础,尤其是在构建iOS和Android应用程序的后端服务时。本文将深入探讨PHP变量的使用,以及它们在不同应用场景中的作用。 PHP变量的声明非常简单,不需要提前声明变量类型,只...
在深入探讨PHP变量的特性和使用时,我们可以从以下几个关键点来理解: 1. **声明与赋值**:在PHP中,无需预先声明变量类型,可以直接赋值创建变量。例如,`$var = "Hello, World!";` 这行代码就创建了一个字符串...
在这个环境中,我们将讨论如何配置PHP 5.5的环境变量,以便在Windows系统上能够顺利运行PHP程序。 首先,我们需要下载并安装PHP 5.5。这通常涉及到从官方PHP网站获取合适的二进制发行版,对于Windows系统,可能是预...
下面将详细介绍这些关键的PHP变量。 1. 预定义变量: 预定义变量是PHP为开发者提供的内置变量,可以直接在代码中使用,无需预先声明。以下是一些常见的预定义变量: - **$_SERVER**:这个超级全局数组包含了服务器...
### PHP 创建和使用 Session Cookie 变量 #### Session 基础 Session 是一种服务器端技术,用于在用户的浏览器与服务器之间保持用户的状态信息。它通过一个唯一标识符(通常是 `session_id`)来跟踪用户的活动,这...
【PHP变量和运算符教程】 在PHP编程语言中,变量是存储数据的容器,而运算符则是用于操作这些数据的符号。本教程将深入讲解PHP中的变量和运算符,帮助初学者更好地理解和运用这两个关键概念。 ### PHP变量 1. **...
1. **$GLOBALS**: 存储所有全局变量的一个数组。自 PHP 3 开始引入。 - 示例:访问全局变量 `$a` 可以通过 `$GLOBALS['a']`。 - 作用:提供了对所有全局变量的引用,方便在函数内外进行数据传递。 2. **$_SERVER*...
在PHP编程语言中,数据类型是非常基础且重要的概念,它定义了变量可以存储的数据种类。了解和熟练掌握PHP的数据类型,对于编写高效、稳定的代码至关重要。这篇博客文章将深入探讨PHP中的数据类型以及如何判断变量的...
在 HTML 标签上添加 `data-*` 属性来存储 PHP 数据,然后在 JavaScript 中通过选择器获取这些属性值。 **示例代码**: ```html <!-- 视图模板 --> ('模块/控制器/方法')}"> <script src="/public/js/app.js"></...
综上所述,PHP文件操作提供了灵活的方式来管理和修改存储在.php文件中的全局变量。通过合理的设计和规范的编程习惯,我们可以高效且安全地处理这类任务。同时,结合错误处理和版本控制,可以进一步增强系统的稳定性...
这意味着所有类的实例共享同一份静态变量的副本,它们在内存中只存储一次。静态变量可以通过`self::`关键字来访问,无需创建类的实例。例如: ```php class Counter { private static $count = 0; public ...
JS变量转PHP变量的情况通常出现在需要在用户交互后更新服务器端数据时,例如用户填写表单或者进行其他动态操作。标题"js变量利用ajax转php变量"所涉及的核心知识点包括: 1. **JavaScript(JS)变量**:JavaScript...
在这个例子中,`$txt`变量存储了一个字符串,而`$number`变量则存储了一个整数。PHP是一种松散类型的编程语言,这意味着在声明变量时,我们不需要显式地指定其数据类型。PHP会根据所赋的值自动推断变量的类型。这与...
PHP变量的类型是动态的,这意味着变量的类型是在赋值时确定的。主要的变量数据类型包括: 1. 布尔型(boolean):只有两个值,TRUE或FALSE,大小写不敏感。 2. 整型(integer):用于存储整数值,超出范围会自动转换...
#### 三、PHP变量作用域概述 PHP中的变量作用域主要包括以下几种类型: 1. **全局作用域**:在整个脚本文件范围内都可被访问的变量。 2. **局部作用域**:仅在特定区域内可被访问的变量,如在函数内部定义的变量。 ...
在PHP编程中,变量是程序中存储数据的基本单元。它们在代码执行过程中起到承载和传递信息的作用。...需要注意的是,变量名是区分大...理解并熟练掌握这些PHP变量和数据类型的概念,对于编写高效、可靠的PHP代码至关重要。
在PHP中,变量是用于存储数据值的容器。PHP是一种弱类型语言,这意味着你无需声明变量的数据类型,PHP会根据赋给变量的值自动确定其类型。变量的命名遵循一定的规则:必须以美元符号($)开头,后跟一个或多个字母、...
1. **定义**:PHP变量是用来存储数据的容器,它的值可以随时改变。在PHP中,不需要预先声明变量,可以直接使用`$`符号后跟变量名来创建变量。例如: ```php $myVariable = "Hello, World!"; ``` 2. **类型**:PHP...
Session是一种用于保存客户端状态的技术,它可以存储在服务器端,使得在同一个用户的多个请求之间能够共享数据。Session非常适合于需要在多页面间持久化数据的场景。 **示例代码**: 1. **设置Session页面(test6....
在 phpcms 中,变量被用来存储和传递特定的信息,如网站标题、版权信息、联系方式等。这些变量可以在模板中直接调用,实现动态内容的展示。变量分为全局变量、栏目变量和内容变量,每种类型的变量有不同的应用场景...