广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP底层内核源码之变量的示例分析
  • 878
分享到

PHP底层内核源码之变量的示例分析

2023-06-15 11:06:15 878人浏览 八月长安
摘要

小编给大家分享一下PHP底层内核源码之变量的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!PHP变量的四个基本特征:1.变量命名变量命名上,php继承了P

小编给大家分享一下PHP底层内核源码之变量的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

PHP变量的四个基本特征:

1.变量命名

变量命名上,php继承了Perl的语法风格,变量以美元符号开始,后面跟变量名。 一个有效的变量名由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。 按照正常的正则表达式,它将被表述为:'^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$’

注意: $this 是一个特殊的变量,它不能被赋值

变量默认总是传值赋值。那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量。这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。有关这种类型的赋值操作,以后的文章也会深度讲解 主要涉及到指针和写时拷贝

PHP 也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。改动新的变量将影响到原始变量,反之亦然。使用引用赋值,简单地将一个 & 符号加到将要赋值的变量前(源变量) (关于变量赋值以后也会深度去探讨)

PHP还支持复合变量 也叫可变变量 。也就是类似$$a的变量,它会进行两次的解释。这给PHP带来了非常灵活的动态特性。一个变量的变量名可以动态的设置和使用。一个普通的变量通过声明来设置

数组使用可变变量

为了使用数组的可变变量名,你需要解决一个歧义问题。就是,如果你写$$a[1],解析器需要明白究竟你的意思是要把$a[1]当成一个变量,还是要把$$a当成变量、[1]指的是这个变量的索引。解决这个歧义问题的语法是:第一种情况使用${$a[1]},第二种情况使用${$a}[1]

类属性也可以通过可变属性名来访问。可变属性名从产生调用所在的变量的访问范围内获取。例如,如果你的表达式是这样的:$foo->$bar,那么运行时将会在本地变量范围内寻找变量$bar,它的值将会做为$foo对象的一个属性名。如果$bar是个数组也可以使用。

可变变量名不能用于PHP函数和类里的超级全局数组变量上。变量$this也是一个不能动态取名的特殊变量。

2.变量的类型

在很多静态语言中,变量在定义时就指定了,在程序运行过程中都不允许进行变更,PHP就是这样,属于弱类型语言,可以随便赋予它任何类型的值。PHP本身的变量低层存储结构是怎么样的?弱类型系统的实现的方式? 以及这些类型之间的是怎么相互转换的? 这将是本文的主要剖析内容。

要想深入了解PHP底层源码 必须要下载PHP的源码包

我在Docker环境下 下载了PHP 的源码包 同时安装了 GCc gcc-c++ 等环境 为了后续的 代码跟踪debug。

[root@2890cf458ee2 cui-php]# lsphp-7.4.15  php-7.4.15.tar.gz[root@2890cf458ee2 cui-php]#[root@2890cf458ee2 cui-php]# cd php-7.4.15[root@2890cf458ee2 php-7.4.15]# lscoding_STANDARDS.md  Makefile.objects    UPGRADING.INTERNALS  buildconf      configure.ac  main           testsCONTRIBUTING.md      NEWS                Zend                 buildconf.bat  docs          modules        tmp-php.iniEXTENSioNS           README.REDIST.BINS  appveyor             config.log     ext           pear           travisLICENSE              README.md           Azure                config.nice    include       run-tests.php  win32Makefile             TSRM                azure-pipelines.yml  config.status  libs          sapiMakefile.fragments   UPGRADING           build                configure      libtool       scripts

这里有必要讲一下 PHP源码的目录结构

Zend :Zend 引擎的实现目录。包括词法语法解析,OPCODE,提供语言运行环境。

TSRM :线程安全资源管理器。

build:放置一些和源码编译相关的一些文件。

ext  :官方扩展目录。包括array系列,pdo系列,spl系列等函数的实现。

main :实现PHP的基本设施。其实包含主要的 PHP 宏和定义。

pear :PHP 扩展与应用仓库。

sapi :各种服务器抽象层的代码。例如apache的mod_php,cgi,fastcgi以及fpm等等接口。

tests:PHP的测试脚本集合

scripts:linux 下的脚本目录。

win32:windows平台相关的一些实现。

PHP的 变量定义在Zend目录下的 zend_types.h 文件

我们cd 到Zend目录下

[root@2890cf458ee2 php-7.4.15]# cd Zend/[root@2890cf458ee2 Zend]# lltotal 22404-rwxrwxrwx  1 root root    2803 Feb  2 14:20 LICENSE-rwxrwxrwx  1 root root    2008 Feb  2 14:20 Makefile.frag-rwxrwxrwx  1 root root    4607 Feb  2 14:20 README.md-rwxrwxrwx  1 root root   14168 Feb  2 14:20 Zend.m4-rwxrwxrwx  1 root root    7634 Feb  2 14:20 bench.php-rwxrwxrwx  1 root root    7226 Feb  2 14:20 micro_bench.phpdrwxrwxrwx 29 root root   73728 Feb  2 14:20 tests-rwxrwxrwx  1 root root   50788 Feb  2 14:20 zend.c-rwxrwxrwx  1 root root   13913 Feb  2 14:20 zend.h-rwxrwxrwx  1 root root     308 Feb 22 08:45 zend.lo-rwxrwxrwx  1 root root  255768 Feb 22 08:45 zend.o-rwxrwxrwx  1 root root  132287 Feb  2 14:20 zend_API.c-rwxrwxrwx  1 root root   71109 Feb  2 14:20 zend_API.h-rwxrwxrwx  1 root root     320 Feb 22 08:45 zend_API.lo-rwxrwxrwx  1 root root  821976 Feb 22 08:45 zend_API.o-rwxrwxrwx  1 root root   91551 Feb  2 14:20 zend_alloc.c-rwxrwxrwx  1 root root   19213 Feb  2 14:20 zend_alloc.h-rwxrwxrwx  1 root root     326 Feb 22 08:45 zend_alloc.lo-rwxrwxrwx  1 root root  523816 Feb 22 08:45 zend_alloc.o-rwxrwxrwx  1 root root    2629 Feb  2 14:20 zend_alloc_sizes.h-rwxrwxrwx  1 root root    6071 Feb  2 14:20 zend_arena.h-rwxrwxrwx  1 root root   60172 Feb  2 14:20 zend_ast.c-rwxrwxrwx  1 root root   11697 Feb  2 14:20 zend_ast.h-rwxrwxrwx  1 root root     320 Feb 22 08:46 zend_ast.lo-rwxrwxrwx  1 root root  545136 Feb 22 08:46 zend_ast.o-rwxrwxrwx  1 root root    6877 Feb  2 14:20 zend_bitset.h-rwxrwxrwx  1 root root    1626 Feb  2 14:20 zend_build.h-rwxrwxrwx  1 root root   75458 Feb  2 14:20 zend_builtin_functions.c-rwxrwxrwx  1 root root    1505 Feb  2 14:20 zend_builtin_functions.h-rwxrwxrwx  1 root root     362 Feb 22 08:45 zend_builtin_functions.lo-rwxrwxrwx  1 root root  323432 Feb 22 08:45 zend_builtin_functions.o-rwxrwxrwx  1 root root   26952 Feb  2 14:20 zend_closures.c-rwxrwxrwx  1 root root    2209 Feb  2 14:20 zend_closures.h-rwxrwxrwx  1 root root     335 Feb 22 08:46 zend_closures.lo-rwxrwxrwx  1 root root  132304 Feb 22 08:46 zend_closures.o-rwxrwxrwx  1 root root  268218 Feb  2 14:20 zend_compile.c-rwxrwxrwx  1 root root   43638 Feb  2 14:20 zend_compile.h-rwxrwxrwx  1 root root     332 Feb 22 08:45 zend_compile.lo-rwxrwxrwx  1 root root 1189024 Feb 22 08:45 zend_compile.o-rwxrwxrwx  1 root root      32 Feb 22 08:39 zend_config.h-rwxrwxrwx  1 root root    2612 Feb  2 14:20 zend_config.w32.h-rwxrwxrwx  1 root root   17607 Feb  2 14:20 zend_constants.c-rwxrwxrwx  1 root root    6302 Feb  2 14:20 zend_constants.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_constants.lo-rwxrwxrwx  1 root root   86680 Feb 22 08:45 zend_constants.o-rwxrwxrwx  1 root root    4571 Feb  2 14:20 zend_cpuinfo.c-rwxrwxrwx  1 root root    7225 Feb  2 14:20 zend_cpuinfo.h-rwxrwxrwx  1 root root     332 Feb 22 08:46 zend_cpuinfo.lo-rwxrwxrwx  1 root root   12416 Feb 22 08:46 zend_cpuinfo.o-rwxrwxrwx  1 root root    1684 Feb  2 14:20 zend_default_classes.c-rwxrwxrwx  1 root root     356 Feb 22 08:46 zend_default_classes.lo-rwxrwxrwx  1 root root   34040 Feb 22 08:46 zend_default_classes.o-rwxrwxrwx  1 root root    4083 Feb  2 14:20 zend_dtrace.c-rwxrwxrwx  1 root root    2180 Feb  2 14:20 zend_dtrace.d-rwxrwxrwx  1 root root    1937 Feb  2 14:20 zend_dtrace.h-rwxrwxrwx  1 root root     329 Feb 22 08:45 zend_dtrace.lo-rwxrwxrwx  1 root root   31808 Feb 22 08:45 zend_dtrace.o-rwxrwxrwx  1 root root    2050 Feb  2 14:20 zend_errors.h-rwxrwxrwx  1 root root   34809 Feb  2 14:20 zend_exceptions.c-rwxrwxrwx  1 root root    3853 Feb  2 14:20 zend_exceptions.h-rwxrwxrwx  1 root root     341 Feb 22 08:46 zend_exceptions.lo-rwxrwxrwx  1 root root  331592 Feb 22 08:46 zend_exceptions.o-rwxrwxrwx  1 root root  148148 Feb  2 14:20 zend_execute.c-rwxrwxrwx  1 root root   16926 Feb  2 14:20 zend_execute.h-rwxrwxrwx  1 root root     332 Feb 22 08:46 zend_execute.lo-rwxrwxrwx  1 root root 6034440 Feb 22 08:46 zend_execute.o-rwxrwxrwx  1 root root   47231 Feb  2 14:20 zend_execute_API.c-rwxrwxrwx  1 root root     344 Feb 22 08:45 zend_execute_API.lo-rwxrwxrwx  1 root root  245224 Feb 22 08:45 zend_execute_API.o-rwxrwxrwx  1 root root   10174 Feb  2 14:20 zend_extensions.c-rwxrwxrwx  1 root root    6070 Feb  2 14:20 zend_extensions.h-rwxrwxrwx  1 root root     341 Feb 22 08:45 zend_extensions.lo-rwxrwxrwx  1 root root   50720 Feb 22 08:45 zend_extensions.o-rwxrwxrwx  1 root root    1796 Feb  2 14:20 zend_float.c-rwxrwxrwx  1 root root   15438 Feb  2 14:20 zend_float.h-rwxrwxrwx  1 root root     326 Feb 22 08:46 zend_float.lo-rwxrwxrwx  1 root root   32656 Feb 22 08:46 zend_float.o-rwxrwxrwx  1 root root   40057 Feb  2 14:20 zend_gc.c-rwxrwxrwx  1 root root    2867 Feb  2 14:20 zend_gc.h-rwxrwxrwx  1 root root     317 Feb 22 08:46 zend_gc.lo-rwxrwxrwx  1 root root  142080 Feb 22 08:46 zend_gc.o-rwxrwxrwx  1 root root   38819 Feb  2 14:20 zend_generators.c-rwxrwxrwx  1 root root    7349 Feb  2 14:20 zend_generators.h-rwxrwxrwx  1 root root     341 Feb 22 08:46 zend_generators.lo-rwxrwxrwx  1 root root  213744 Feb 22 08:46 zend_generators.o-rwxrwxrwx  1 root root    7767 Feb  2 14:20 zend_globals.h-rwxrwxrwx  1 root root    2810 Feb  2 14:20 zend_globals_Macros.h-rwxrwxrwx  1 root root   71887 Feb  2 14:20 zend_hash.c-rwxrwxrwx  1 root root   36430 Feb  2 14:20 zend_hash.h-rwxrwxrwx  1 root root     323 Feb 22 08:45 zend_hash.lo-rwxrwxrwx  1 root root  579040 Feb 22 08:45 zend_hash.o-rwxrwxrwx  1 root root    5905 Feb  2 14:20 zend_highlight.c-rwxrwxrwx  1 root root    2268 Feb  2 14:20 zend_highlight.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_highlight.lo-rwxrwxrwx  1 root root   54368 Feb 22 08:45 zend_highlight.o-rwxrwxrwx  1 root root   92179 Feb  2 14:20 zend_inheritance.c-rwxrwxrwx  1 root root    2027 Feb  2 14:20 zend_inheritance.h-rwxrwxrwx  1 root root     344 Feb 22 08:46 zend_inheritance.lo-rwxrwxrwx  1 root root  444648 Feb 22 08:46 zend_inheritance.o-rwxrwxrwx  1 root root   17816 Feb  2 14:20 zend_ini.c-rwxrwxrwx  1 root root    9823 Feb  2 14:20 zend_ini.h-rwxrwxrwx  1 root root     320 Feb 22 08:45 zend_ini.lo-rwxrwxrwx  1 root root  114864 Feb 22 08:45 zend_ini.o-rwxrwxrwx  1 root root   62412 Feb  2 14:20 zend_ini_parser.c-rwxrwxrwx  1 root root    2400 Feb  2 14:20 zend_ini_parser.h-rwxrwxrwx  1 root root     341 Feb 22 08:45 zend_ini_parser.lo-rwxrwxrwx  1 root root  144960 Feb 22 08:45 zend_ini_parser.o-rwxrwxrwx  1 root root   21408 Feb  2 14:20 zend_ini_parser.output-rwxrwxrwx  1 root root   12077 Feb  2 14:20 zend_ini_parser.y-rwxrwxrwx  1 root root  102668 Feb  2 14:20 zend_ini_scanner.c-rwxrwxrwx  1 root root    1873 Feb  2 14:20 zend_ini_scanner.h-rwxrwxrwx  1 root root   17171 Feb  2 14:20 zend_ini_scanner.l-rwxrwxrwx  1 root root     344 Feb 22 08:45 zend_ini_scanner.lo-rwxrwxrwx  1 root root  225064 Feb 22 08:45 zend_ini_scanner.o-rwxrwxrwx  1 root root     187 Feb  2 14:20 zend_ini_scanner_defs.h-rwxrwxrwx  1 root root   19678 Feb  2 14:20 zend_interfaces.c-rwxrwxrwx  1 root root    4266 Feb  2 14:20 zend_interfaces.h-rwxrwxrwx  1 root root     341 Feb 22 08:46 zend_interfaces.lo-rwxrwxrwx  1 root root   95608 Feb 22 08:46 zend_interfaces.o-rwxrwxrwx  1 root root    1537 Feb  2 14:20 zend_istdiOStream.h-rwxrwxrwx  1 root root    3205 Feb  2 14:20 zend_iterators.c-rwxrwxrwx  1 root root    3404 Feb  2 14:20 zend_iterators.h-rwxrwxrwx  1 root root     338 Feb 22 08:46 zend_iterators.lo-rwxrwxrwx  1 root root   36896 Feb 22 08:46 zend_iterators.o-rwxrwxrwx  1 root root  252766 Feb  2 14:20 zend_language_parser.c-rwxrwxrwx  1 root root    5095 Feb  2 14:20 zend_language_parser.h-rwxrwxrwx  1 root root     356 Feb 22 08:45 zend_language_parser.lo-rwxrwxrwx  1 root root  345328 Feb 22 08:45 zend_language_parser.o-rwxrwxrwx  1 root root 1356436 Feb  2 14:20 zend_language_parser.output-rwxrwxrwx  1 root root   49261 Feb  2 14:20 zend_language_parser.y-rwxrwxrwx  1 root root  186767 Feb  2 14:20 zend_language_scanner.c-rwxrwxrwx  1 root root    2732 Feb  2 14:20 zend_language_scanner.h-rwxrwxrwx  1 root root   69753 Feb  2 14:20 zend_language_scanner.l-rwxrwxrwx  1 root root     359 Feb 22 08:45 zend_language_scanner.lo-rwxrwxrwx  1 root root  475576 Feb 22 08:45 zend_language_scanner.o-rwxrwxrwx  1 root root     267 Feb  2 14:20 zend_language_scanner_defs.h-rwxrwxrwx  1 root root    9245 Feb  2 14:20 zend_list.c-rwxrwxrwx  1 root root    3470 Feb  2 14:20 zend_list.h-rwxrwxrwx  1 root root     323 Feb 22 08:45 zend_list.lo-rwxrwxrwx  1 root root   63872 Feb 22 08:45 zend_list.o-rwxrwxrwx  1 root root    6837 Feb  2 14:20 zend_llist.c-rwxrwxrwx  1 root root    3790 Feb  2 14:20 zend_llist.h-rwxrwxrwx  1 root root     326 Feb 22 08:45 zend_llist.lo-rwxrwxrwx  1 root root   22848 Feb 22 08:45 zend_llist.o-rwxrwxrwx  1 root root    4298 Feb  2 14:20 zend_long.h-rwxrwxrwx  1 root root    3165 Feb  2 14:20 zend_map_ptr.h-rwxrwxrwx  1 root root    4790 Feb  2 14:20 zend_modules.h-rwxrwxrwx  1 root root    7322 Feb  2 14:20 zend_multibyte.c-rwxrwxrwx  1 root root    4862 Feb  2 14:20 zend_multibyte.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_multibyte.lo-rwxrwxrwx  1 root root   56144 Feb 22 08:45 zend_multibyte.o-rwxrwxrwx  1 root root    9837 Feb  2 14:20 zend_multiply.h-rwxrwxrwx  1 root root   57901 Feb  2 14:20 zend_object_handlers.c-rwxrwxrwx  1 root root   13505 Feb  2 14:20 zend_object_handlers.h-rwxrwxrwx  1 root root     356 Feb 22 08:46 zend_object_handlers.lo-rwxrwxrwx  1 root root  310384 Feb 22 08:46 zend_object_handlers.o-rwxrwxrwx  1 root root    9778 Feb  2 14:20 zend_objects.c-rwxrwxrwx  1 root root    1807 Feb  2 14:20 zend_objects.h-rwxrwxrwx  1 root root     332 Feb 22 08:46 zend_objects.lo-rwxrwxrwx  1 root root   59976 Feb 22 08:46 zend_objects.o-rwxrwxrwx  1 root root    6724 Feb  2 14:20 zend_objects_API.c-rwxrwxrwx  1 root root    4683 Feb  2 14:20 zend_objects_API.h-rwxrwxrwx  1 root root     344 Feb 22 08:46 zend_objects_API.lo-rwxrwxrwx  1 root root   46120 Feb 22 08:46 zend_objects_API.o-rwxrwxrwx  1 root root   34033 Feb  2 14:20 zend_opcode.c-rwxrwxrwx  1 root root     329 Feb 22 08:45 zend_opcode.lo-rwxrwxrwx  1 root root  120352 Feb 22 08:45 zend_opcode.o-rwxrwxrwx  1 root root   83363 Feb  2 14:20 zend_operators.c-rwxrwxrwx  1 root root   34148 Feb  2 14:20 zend_operators.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_operators.lo-rwxrwxrwx  1 root root  506096 Feb 22 08:45 zend_operators.o-rwxrwxrwx  1 root root   20146 Feb  2 14:20 zend_portability.h-rwxrwxrwx  1 root root    3030 Feb  2 14:20 zend_ptr_stack.c-rwxrwxrwx  1 root root    4306 Feb  2 14:20 zend_ptr_stack.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_ptr_stack.lo-rwxrwxrwx  1 root root   13104 Feb 22 08:45 zend_ptr_stack.o-rwxrwxrwx  1 root root    3000 Feb  2 14:20 zend_range_check.h-rwxrwxrwx  1 root root   13032 Feb  2 14:20 zend_signal.c-rwxrwxrwx  1 root root    4082 Feb  2 14:20 zend_signal.h-rwxrwxrwx  1 root root     329 Feb 22 08:46 zend_signal.lo-rwxrwxrwx  1 root root   29320 Feb 22 08:46 zend_signal.o-rwxrwxrwx  1 root root    5672 Feb  2 14:20 zend_smart_str.c-rwxrwxrwx  1 root root    5530 Feb  2 14:20 zend_smart_str.h-rwxrwxrwx  1 root root     338 Feb 22 08:46 zend_smart_str.lo-rwxrwxrwx  1 root root   18552 Feb 22 08:46 zend_smart_str.o-rwxrwxrwx  1 root root    1279 Feb  2 14:20 zend_smart_str_public.h-rwxrwxrwx  1 root root    4389 Feb  2 14:20 zend_smart_string.h-rwxrwxrwx  1 root root    1392 Feb  2 14:20 zend_smart_string_public.h-rwxrwxrwx  1 root root   10852 Feb  2 14:20 zend_sort.c-rwxrwxrwx  1 root root    1636 Feb  2 14:20 zend_sort.h-rwxrwxrwx  1 root root     323 Feb 22 08:45 zend_sort.lo-rwxrwxrwx  1 root root   28488 Feb 22 08:45 zend_sort.o-rwxrwxrwx  1 root root    3983 Feb  2 14:20 zend_stack.c-rwxrwxrwx  1 root root    2360 Feb  2 14:20 zend_stack.h-rwxrwxrwx  1 root root     326 Feb 22 08:45 zend_stack.lo-rwxrwxrwx  1 root root   13312 Feb 22 08:45 zend_stack.o-rwxrwxrwx  1 root root    7212 Feb  2 14:20 zend_stream.c-rwxrwxrwx  1 root root    3542 Feb  2 14:20 zend_stream.h-rwxrwxrwx  1 root root     329 Feb 22 08:46 zend_stream.lo-rwxrwxrwx  1 root root   24776 Feb 22 08:46 zend_stream.o-rwxrwxrwx  1 root root   12740 Feb  2 14:20 zend_string.c-rwxrwxrwx  1 root root   17347 Feb  2 14:20 zend_string.h-rwxrwxrwx  1 root root     329 Feb 22 08:46 zend_string.lo-rwxrwxrwx  1 root root   77697 Feb 23 09:51 zend_string.o-rwxrwxrwx  1 root root   92649 Feb  2 14:20 zend_strtod.c-rwxrwxrwx  1 root root    1854 Feb  2 14:20 zend_strtod.h-rwxrwxrwx  1 root root     329 Feb 22 08:46 zend_strtod.lo-rwxrwxrwx  1 root root  117472 Feb 22 08:46 zend_strtod.o-rwxrwxrwx  1 root root    3499 Feb  2 14:20 zend_strtod_int.h-rwxrwxrwx  1 root root    8172 Feb  2 14:20 zend_ts_hash.c-rwxrwxrwx  1 root root    5731 Feb  2 14:20 zend_ts_hash.h-rwxrwxrwx  1 root root     332 Feb 22 08:45 zend_ts_hash.lo-rwxrwxrwx  1 root root   42888 Feb 22 08:45 zend_ts_hash.o-rwxrwxrwx  1 root root    3091 Feb  2 14:20 zend_type_info.h-rwxrwxrwx  1 root root   40632 Feb 23 03:41 zend_types.h-rwxrwxrwx  1 root root    4739 Feb  2 14:20 zend_variables.c-rwxrwxrwx  1 root root    3273 Feb  2 14:20 zend_variables.h-rwxrwxrwx  1 root root     338 Feb 22 08:45 zend_variables.lo-rwxrwxrwx  1 root root   43816 Feb 22 08:45 zend_variables.o-rwxrwxrwx  1 root root   43224 Feb  2 14:20 zend_virtual_cwd.c-rwxrwxrwx  1 root root   12734 Feb  2 14:20 zend_virtual_cwd.h-rwxrwxrwx  1 root root     344 Feb 22 08:46 zend_virtual_cwd.lo-rwxrwxrwx  1 root root   80456 Feb 22 08:46 zend_virtual_cwd.o-rwxrwxrwx  1 root root    1952 Feb  2 14:20 zend_vm.h-rwxrwxrwx  1 root root  271416 Feb  2 14:20 zend_vm_def.h-rwxrwxrwx  1 root root 2025584 Feb  2 14:20 zend_vm_execute.h-rwxrwxrwx  1 root root    3616 Feb  2 14:20 zend_vm_execute.skl-rwxrwxrwx  1 root root  146220 Feb  2 14:20 zend_vm_gen.php-rwxrwxrwx  1 root root   87968 Feb  2 14:20 zend_vm_handlers.h-rwxrwxrwx  1 root root    8522 Feb  2 14:20 zend_vm_opcodes.c-rwxrwxrwx  1 root root   12080 Feb  2 14:20 zend_vm_opcodes.h-rwxrwxrwx  1 root root     341 Feb 22 08:45 zend_vm_opcodes.lo-rwxrwxrwx  1 root root   17408 Feb 22 08:45 zend_vm_opcodes.o-rwxrwxrwx  1 root root    3212 Feb  2 14:20 zend_vm_trace_handlers.h-rwxrwxrwx  1 root root    2654 Feb  2 14:20 zend_vm_trace_map.h-rwxrwxrwx  1 root root    6578 Feb  2 14:20 zend_weakrefs.c-rwxrwxrwx  1 root root    1445 Feb  2 14:20 zend_weakrefs.h-rwxrwxrwx  1 root root     335 Feb 22 08:46 zend_weakrefs.lo-rwxrwxrwx  1 root root   66704 Feb 22 08:46 zend_weakrefs.o

对于没有C语言基础的同学 看到这么多 .c .lo .o.h是发懵的 不像PHP 只有一个 .php格式

我先介绍下 c语言中的文件类型 和后缀

c文件:主要每个模块的原代码都在c文件中。

h文件:每个c文件都跟着一个h文件,h文件的作用是放着c文件中函数的声明,结构体的定义,宏的定义等。

o文件:目标文件。每个文件经过编译都会形成一个目标文件(二进制文件),多个目标文件链接后才能形成可执行文件。

o文件如何形成: gcc -c a.c (gcc 以后会用到 再说)

.so文件

.so文件就不一样了,它不是简单的.o文件打了一个包,它是一个ELF格式的文件,也就是linux的可执行文件。

.so文件可以用于多个进程的共享使用(位置无关的才行),所以又叫共享库文件。程序在使用它的时候,会在运行时把它映射到自己进程空间的某一处,其不在使用它的程序中。

.lo文件 libtool生成的文件,被libtool用来生成共享库的. libtool隐藏了PIC的flag的复杂性,而采用了分离的库对象文件,以“.lo”代替“.o”结尾。在不需要共享库的系统上,这些库文件等同于标准的目标文件

所有以 我们只需要看 .h 和.c就行了 其他的 文件我们想看也看不懂

其中变量的结构体定义和宏定义 在 zend_types.h 中

至于什么是结构体 什么是宏 一会再讲

[root@2890cf458ee2 Zend]# vim zend_types.h

其中前部分代码是这样的

   1   21  22 #ifndef ZEND_TYPES_H  23 #define ZEND_TYPES_H  24  25 #include "zend_portability.h"  26 #include "zend_long.h"  27  28 #ifdef __SSE2__  29 # include <mmintrin.h>  30 # include <emmintrin.h>  31 #endif  32  33 #ifdef WordS_BIGENDIAN  34 # define ZEND_ENDIAN_LOHI(lo, hi)          hi; lo;  35 # define ZEND_ENDIAN_LOHI_3(lo, mi, hi)    hi; mi; lo;  36 # define ZEND_ENDIAN_LOHI_4(a, b, c, d)    d; c; b; a;  37 # define ZEND_ENDIAN_LOHI_C(lo, hi)        hi, lo  38 # define ZEND_ENDIAN_LOHI_C_3(lo, mi, hi)  hi, mi, lo,  39 # define ZEND_ENDIAN_LOHI_C_4(a, b, c, d)  d, c, b, a  40 #else  41 # define ZEND_ENDIAN_LOHI(lo, hi)          lo; hi;  42 # define ZEND_ENDIAN_LOHI_3(lo, mi, hi)    lo; mi; hi;  43 # define ZEND_ENDIAN_LOHI_4(a, b, c, d)    a; b; c; d;  44 # define ZEND_ENDIAN_LOHI_C(lo, hi)        lo, hi  45 # define ZEND_ENDIAN_LOHI_C_3(lo, mi, hi)  lo, mi, hi,  46 # define ZEND_ENDIAN_LOHI_C_4(a, b, c, d)  a, b, c, d  47 #endif  48  49 typedef unsigned char zend_bool;  50 typedef unsigned char zend_uchar;  51  52 typedef enum {  53   SUCCESS =  0,  54   FAILURE = -1,           55 } ZEND_RESULT_CODE;  56  57 #ifdef ZEND_ENABLE_ZVAL_LONG64  58 # ifdef ZEND_WIN32  59 #  define ZEND_SIZE_MAX  _UI64_MAX  60 # else  61 #  define ZEND_SIZE_MAX  SIZE_MAX  62 # endif  63 #else  64 # if defined(ZEND_WIN32)  65 #  define ZEND_SIZE_MAX  _UI32_MAX  66 # else  67 #  define ZEND_SIZE_MAX SIZE_MAX  68 # endif  69 #endif  70  71 typedef intptr_t zend_intptr_t;  72 typedef uintptr_t zend_uintptr_t;  73  74 #ifdef ZTS  75 #define ZEND_TLS static TSRM_TLS  76 #define ZEND_EXT_TLS TSRM_TLS  77 #else  78 #define ZEND_TLS static  79 #define ZEND_EXT_TLS  80 #endif  81  82 typedef struct _zend_object_handlers zend_object_handlers;  83 typedef struct _zend_class_entry     zend_class_entry;  84 typedef uNIOn  _zend_function        zend_function;  85 typedef struct _zend_execute_data    zend_execute_data;  86  87 typedef struct _zval_struct     zval;  88  89 typedef struct _zend_refcounted zend_refcounted;  90 typedef struct _zend_string     zend_string;  91 typedef struct _zend_array      zend_array;  92 typedef struct _zend_object     zend_object;  93 typedef struct _zend_resource   zend_resource;  94 typedef struct _zend_reference  zend_reference;  95 typedef struct _zend_ast_ref    zend_ast_ref;  96 typedef struct _zend_ast        zend_ast;  97  98 typedef int  (*compare_func_t)(const void *, const void *);  99 typedef void (*swap_func_t)(void *, void *); 100 typedef void (*sort_func_t)(void *, size_t, size_t, compare_func_t, swap_func_t); 101 typedef void (*dtor_func_t)(zval *pDest); 102 typedef void (*copy_ctor_func_t)(zval *pElement);

这个#开始的内容并不是注释 只需要大概了解下 以下内容

#空指令,无任何效果#include开头 -------包含一个源代码文件#define开头 -------定义宏#undef开头 -------取消已定义的宏#if开头 -------如果给定条件为真,则编译下面代码#ifdef开头 -------如果宏已经定义,则编译下面代码#ifnde开头 -------f如果宏没有定义,则编译下面代码#elif开头 -------如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif开头 -------结束一个#if……#else条件编译块#error开头 -------停止编译并显示错误信息

其实就是头文件 无实际寓意 比如#ifdef WORDS_BIGENDIAN 这是大小端的 判断

 196 struct _zval_struct { 197         zend_value        value;                         198         union { 199                 struct { 200                         ZEND_ENDIAN_LOHI_3( 201                                 zend_uchar    type,                      202                                 zend_uchar    type_flags, 203                                 union { 204                                         uint16_t  extra;         205                                 } u) 206                 } v; 207                 uint32_t type_info; 208         } u1; 209         union { 210                 uint32_t     next;                  211                 uint32_t     cache_slot;            212                 uint32_t     opline_num;            213                 uint32_t     lineno;                214                 uint32_t     num_args;              215                 uint32_t     fe_pos;                216                 uint32_t     fe_iter_idx;           217                 uint32_t     access_flags;          218                 uint32_t     property_guard;        219                 uint32_t     constant_flags;        220                 uint32_t     extra;                 221         } u2; 222 };

这部分是 变量 的核心 代码

C语言结构体(Struct)从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由 int、char、float 等基本类型组成的。你可以认为结构体是一种聚合类型。在实际开发中,我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如,在校学生有姓名、年龄、身高、成绩等属性,学了结构体后,我们就不需要再定义多个变量了,将它们都放到结构体中即可。 有点类似于 PHP里的对象?

结构体里面用;进行 分割 每个子变量

可以看出来 _zval_struct 结构体 包括三个变量部分 (以单下划线(_)表明是标准库的变量

双下划线(__) 开头表明是编译器的变量)

分别为 value u1 u2

(你要这样 理解 197行中 zend_value value; 这行代码中 zend_value是变量类型 value 是名字 )

结构体里第一个值类型名为 zend_value 这应该不是一个变量 我们搜一下

/zend_value

代码在176处定义了 zend_value

 176 typedef union _zend_value { 177         zend_long         lval;                          178         double            dval;                          179         zend_refcounted  *counted; 180         zend_string      *str; 181         zend_array       *arr; 182         zend_object      *obj; 183         zend_resource    *res; 184         zend_reference   *ref; 185         zend_ast_ref     *ast; 186         zval             *zv; 187         void             *ptr; 188         zend_class_entry *ce; 189         zend_function    *func; 190         struct { 191                 uint32_t w1; 192                 uint32_t w2; 193         } ww; 194 } zend_value;

联合体 / union

union使用方法和struct非常相似,唯一的不同是struct变量所占内存长度是各成员的内存之和,而union内存长度则是占内存最大的成员的长度,也就是说union的几个成员变量是共用一块内存的。

简单点来说就是

假如

struct a里面 包含 变量a1 内存占用为1 a2 内存占用为2 那么 struct a 总占用内存为1+2=3

union b里面 包含 变量b1 内存占用为1 b2 内存占用为2 那么 union b 总占用内存为2

继续看 zend_value

zend_long         lval;          //整型double            dval;          //浮点型zend_refcounted  *counted;     //获取不同类型结构的gc头部的指针zend_string      *str;        //string字符串 的指针zend_array       *arr;        //数组指针zend_object      *obj;        //object 对象指针zend_resource    *res;         ///资源类型指针zend_reference   *ref;       //引用类型指针   比如你通过&$c  定义的zend_ast_ref     *ast;     // ast 指针  线程安全 相关的 内核使用的  zval             *zv;   // 指向另外一个zval的指针  内核使用的void             *ptr;   //指针  ,通用类型  内核使用的zend_class_entry *ce;    //类 ,内核使用的zend_function    *func;   // 函数 ,内核使用的struct { uint32_t w1;//自己定义的。 无符号的32位整数 uint32_t w2;//同上} ww;

lval 和 dval 分别为 整型和 浮点型 剩下的 为* 开头的 指针

什么是指针?

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

  int    *ip;            } u)      } v;     //一个无符号的整型 记录 变量类型的    uint32_t type_info;} u1;

其实v 里面就是一个宏 (你可以理解为PHP里面的构造方法 )是为了兼容大小字节序,小字节序就是下面的顺序 大字节序是下面的4个顺序翻转

type_info是用来记录变量的类型 占用4个字节 每个字节对于v中一个成员

所以 u1占用 4个字节 加上 value 8个字节 4+8=12个字节

value 本来应该占 8 个字节,但是由于内存对齐,哪怕只增加一个字节,实际上也是占用 16 个字节(使用一个字节就意味着需要额外的 8 个字节)。但是显然我们并不需要 8 个字节来存储一个 type 字段,所以我们在 u1 的后面增加了了一个名为 u2 的联合体。默认情况下是用不到的,需要使用的时候可以用来存储 4 个字节的数据。这个联合体可以满足不同场景下的需求。

什么是内存对齐?

将每一个数据的起始位置,在内存的对其位置处。

为什么要内存对齐?

无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。

原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。

这个u2 是扩展用的 一般不会用到

比如 next 在散列表里解决哈希冲突会用到 (现在给你说hash冲突你会懵)

再比如 fe_pos 会在 foreach遍历时候用到

  union {  uint32_t     next;                   uint32_t     cache_slot;             uint32_t     opline_num;             uint32_t     lineno;                 uint32_t     num_args;               uint32_t     fe_pos;                 uint32_t     fe_iter_idx;            uint32_t     access_flags;           uint32_t     property_guard;         uint32_t     constant_flags;         uint32_t     extra;                  } u2;

所以 PHP7 以上的 zval_struct 占用16个字节 非常小了!

以上是“PHP底层内核源码之变量的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网PHP编程频道!

--结束END--

本文标题: PHP底层内核源码之变量的示例分析

本文链接: https://www.lsjlt.com/news/279911.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP底层内核源码之变量的示例分析
    小编给大家分享一下PHP底层内核源码之变量的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!PHP变量的四个基本特征:1.变量命名变量命名上,PHP继承了P...
    99+
    2023-06-15
  • PHP底层内核源码之变量zend_string的示例分析
    这篇文章主要介绍PHP底层内核源码之变量zend_string的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!我们主要通读了_zval_struct  来深入了解 PHP7以上版本的 变量实现和内存...
    99+
    2023-06-15
  • PHP底层内核源码之变量zend_zval结构体的示例分析
    小编给大家分享一下PHP底层内核源码之变量zend_zval结构体的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!zend_string的 结构体 的源码...
    99+
    2023-06-15
  • PHP常量和变量之变量引用的示例分析
    小编给大家分享一下PHP常量和变量之变量引用的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!关于PHP常量和变量之变量引用分别写两段代码,如下所示:<php$fo =8;//$fo的值为8,将8赋值...
    99+
    2023-06-15
  • Linux五大模块内核源码以及内核整体架构设计的示例分析
    小编给大家分享一下Linux五大模块内核源码以及内核整体架构设计的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言本文是“Linux内核源码分析”系...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作