`
swincle
  • 浏览: 78049 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

PHP变量的存储方式

    博客分类:
  • PHP
 
阅读更多

当用户在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的变量应用

    理解并熟练使用PHP变量是进行Web开发的基础,尤其是在构建iOS和Android应用程序的后端服务时。本文将深入探讨PHP变量的使用,以及它们在不同应用场景中的作用。 PHP变量的声明非常简单,不需要提前声明变量类型,只...

    PHP经典实例--变量

    在深入探讨PHP变量的特性和使用时,我们可以从以下几个关键点来理解: 1. **声明与赋值**:在PHP中,无需预先声明变量类型,可以直接赋值创建变量。例如,`$var = "Hello, World!";` 这行代码就创建了一个字符串...

    php5.5环境变量配置

    在这个环境中,我们将讨论如何配置PHP 5.5的环境变量,以便在Windows系统上能够顺利运行PHP程序。 首先,我们需要下载并安装PHP 5.5。这通常涉及到从官方PHP网站获取合适的二进制发行版,对于Windows系统,可能是预...

    js变量利用ajax转php变量

    JS变量转PHP变量的情况通常出现在需要在用户交互后更新服务器端数据时,例如用户填写表单或者进行其他动态操作。标题"js变量利用ajax转php变量"所涉及的核心知识点包括: 1. **JavaScript(JS)变量**:JavaScript...

    PHP创建和使用session cookie变量

    ### PHP 创建和使用 Session Cookie 变量 #### Session 基础 Session 是一种服务器端技术,用于在用户的浏览器与服务器之间保持用户的状态信息。它通过一个唯一标识符(通常是 `session_id`)来跟踪用户的活动,这...

    去来php教程之变量也运算符

    【PHP变量和运算符教程】 在PHP编程语言中,变量是存储数据的容器,而运算符则是用于操作这些数据的符号。本教程将深入讲解PHP中的变量和运算符,帮助初学者更好地理解和运用这两个关键概念。 ### PHP变量 1. **...

    php 超全局变量

    1. **$GLOBALS**: 存储所有全局变量的一个数组。自 PHP 3 开始引入。 - 示例:访问全局变量 `$a` 可以通过 `$GLOBALS['a']`。 - 作用:提供了对所有全局变量的引用,方便在函数内外进行数据传递。 2. **$_SERVER*...

    PHP 数据类型和判断变量类型

    在PHP编程语言中,数据类型是非常基础且重要的概念,它定义了变量可以存储的数据种类。了解和熟练掌握PHP的数据类型,对于编写高效、稳定的代码至关重要。这篇博客文章将深入探讨PHP中的数据类型以及如何判断变量的...

    thinkphp5 js中显示php变量.docx

    在 HTML 标签上添加 `data-*` 属性来存储 PHP 数据,然后在 JavaScript 中通过选择器获取这些属性值。 **示例代码**: ```html &lt;!-- 视图模板 --&gt; ('模块/控制器/方法')}"&gt; &lt;script src="/public/js/app.js"&gt;&lt;/...

    PHP文件操作,方便的修改存在.php文件里的网站变量

    综上所述,PHP文件操作提供了灵活的方式来管理和修改存储在.php文件中的全局变量。通过合理的设计和规范的编程习惯,我们可以高效且安全地处理这类任务。同时,结合错误处理和版本控制,可以进一步增强系统的稳定性...

    PHP面向对象之旅深入理解static变量与方法

    这意味着所有类的实例共享同一份静态变量的副本,它们在内存中只存储一次。静态变量可以通过`self::`关键字来访问,无需创建类的实例。例如: ```php class Counter { private static $count = 0; public ...

    WEB开发 之 PHP 变量.docx

    在这个例子中,`$txt`变量存储了一个字符串,而`$number`变量则存储了一个整数。PHP是一种松散类型的编程语言,这意味着在声明变量时,我们不需要显式地指定其数据类型。PHP会根据所赋的值自动推断变量的类型。这与...

    PHP中的变量作用域

    #### 三、PHP变量作用域概述 PHP中的变量作用域主要包括以下几种类型: 1. **全局作用域**:在整个脚本文件范围内都可被访问的变量。 2. **局部作用域**:仅在特定区域内可被访问的变量,如在函数内部定义的变量。 ...

    PHP编程基础--PHP变量.ppt

    在PHP编程中,变量是程序中存储数据的基本单元。它们在代码执行过程中起到承载和传递信息的作用。...需要注意的是,变量名是区分大...理解并熟练掌握这些PHP变量和数据类型的概念,对于编写高效、可靠的PHP代码至关重要。

    PHP的变量、常量学习笔记

    在PHP中,变量是用于存储数据值的容器。PHP是一种弱类型语言,这意味着你无需声明变量的数据类型,PHP会根据赋给变量的值自动确定其类型。变量的命名遵循一定的规则:必须以美元符号($)开头,后跟一个或多个字母、...

    PHP变量和常量的作用003

    1. **定义**:PHP变量是用来存储数据的容器,它的值可以随时改变。在PHP中,不需要预先声明变量,可以直接使用`$`符号后跟变量名来创建变量。例如: ```php $myVariable = "Hello, World!"; ``` 2. **类型**:PHP...

    第3章PHP中的常量与变量

    PHP变量的类型是动态的,这意味着变量的类型是在赋值时确定的。主要的变量数据类型包括: 1. 布尔型(boolean):只有两个值,TRUE或FALSE,大小写不敏感。 2. 整型(integer):用于存储整数值,超出范围会自动转换...

    php中页面之间传递变量方法总结

    Session是一种用于保存客户端状态的技术,它可以存储在服务器端,使得在同一个用户的多个请求之间能够共享数据。Session非常适合于需要在多页面间持久化数据的场景。 **示例代码**: 1. **设置Session页面(test6....

    phpcms 自动添加变量

    在 phpcms 中,变量被用来存储和传递特定的信息,如网站标题、版权信息、联系方式等。这些变量可以在模板中直接调用,实现动态内容的展示。变量分为全局变量、栏目变量和内容变量,每种类型的变量有不同的应用场景...

Global site tag (gtag.js) - Google Analytics