目录
回复内容:
首页 后端开发 php教程 php是如何找到要实例的对象的

php是如何找到要实例的对象的

Jun 06, 2016 pm 08:23 PM
php

比如我有个test对象,首先先实例对象,然后对象在实例化的后面,这个时候为什么还会找的到对象?

<code>$test = new Test();
echo $test->run();

class Test{
    public function run(){
        return 'run---';
    }
}
</code>
登录后复制
登录后复制

上面代码是怎么运行的,php怎么找的到test对象的?

回复内容:

比如我有个test对象,首先先实例对象,然后对象在实例化的后面,这个时候为什么还会找的到对象?

<code>$test = new Test();
echo $test->run();

class Test{
    public function run(){
        return 'run---';
    }
}
</code>
登录后复制
登录后复制

上面代码是怎么运行的,php怎么找的到test对象的?

你应该明白任何解释器都不是直接解释源代码的(虽然你可以这么做),而是经过"预处理",之后,在执行这个预处理的结果.虽然说是解释器
比如你写

<code>echo "Hello world";
exit;
!#$%^&*()error</code>
登录后复制

按照你理解的逻辑,可能php的解释器是现在才开始扫描这个源码,它会打印出Hello world的,但却给你一个PHP Parse error: syntax error, 的异常.
奇怪,可见,源代码在执行前经过了一次检查,这些检查包括但不限于语法检测,php的源码是经过处理的,你所定义的Test已经存在了.也就是说,所谓的解释器,基本上都存在"伪编译"的过程,所谓动态是指,你每一次请求都需要经过这样的处理,对Java而言,这些工作需要你手动指定,编译OK的class,继续交给虚拟机执行.

下面是在鸟哥的博客里面找到的执行流程简化,解释器其实是在解释Opcode(这也是APC存在的基础):

  1. 词法分析, 去掉注释, 空白, 得到TOKEN

  2. 语法分析, 在这个过程中生成Opcode array (op_array)

  3. 解释执行, 执行op_array, 一条一条的解释执行Opline(SWITCH, CALL, GOTO)

PHP 解释器是个 C 程序。
它是解释型语言,所以无需编译,但这个编译指的是『编译成二进制文件』。
但是从脚本到结果,中间还是有一系列过程的。

语言本身只是为了更符合人的习惯,PHP 解释器最终执行的是 opcode。

从从 php 脚本到 opcodes 的的过程在 PHP5 中是:

Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,在此阶段生成 op arrays。

PHP7 中在语法分析阶段不再直接生成 op arrays,而是先生成 AST,所以过程多了一步:

Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,从 token 流生成抽象语法树;
Compilation:从抽象语法树生成 op arrays。

上面的 lexing,也就是词法分析,PHP 用的是 re2c,parsing 也就是语法分析,PHP 用的是bison。
lexing 做一些符号替换,状态记录的东西。
parsing 会去扫描语法,然后调用相应的处理函数,比如 zend_do_begin_class_declaration 之类的函数。当然这是 PHP5,PHP7 它会先去调 zend_ast_create 之类的。

接下来 PHP5 中 parsing 调的相应的处理函数就会将语句转换成 opcode,将变量存在内存中,函数名、类名存在符号表中。
PHP7 中会有 compile 相关的函数去分析抽象语法树,然后得到和上面相同的结果。

这样你的变量、类、函数都在内存中准备就绪了,你的赋值语句、函数调用语句都已经变成了顺序排列的一条一条的 opcode array了。

然后就是执行了。会有一个 excute 相关的函数来一条一条的执行 opcode,得到的就是你要的结果。

所以你的类虽然写在下面,但是完全可以被找到的。

上面说的这些过程,对应的 PHP 解释器中的文件分别是:

zend_language_scanner.l
zend_language_parser.y
zend_ast.c (PHP7)
zend_compile.c
zend_excute.c

如果有 C 语言的底子,尝试从另外一个层面去了解会更简单。

php是解释型语言, 不用像编译型语言(c)那样提前声明函数定义。

运行之前电脑会把整个php代码加载到内存中吧。然后再去查找调用。。
我是才学一个月的小白。。不知道对不对

代码会放在内存中的代码区,程序运行的时候调用,所以在你代码中的顺序没有关系,但建议便于阅读,实例放在前面。

别高兴得太早,如果它继承另一个类(include),就要放在下面了,php是个奇葩

我觉得大家解释的都仅仅是原理,没有解释道这题的根本,这道问题的意思是问为什么把类定义到调用类的后面也可以,按照常理来说是类定义在要调用的前面才能查找得到。
我来解释一下这个问题吧,首先,定义了类,不调用,是没有意义的,要调用,就必须要实例化,上面提到的opcode执行机制,这个是对的,那么我说的原因基于这个,也就是说php在执行的时候进行预编译,那么编译的时候把执行的数据放到内存,其存放方式和我们写代码的时候是不一样的,php把每种类型的数据放到不同的位置,比如把类放到堆,也就是说,你这个类,不管定义在前面和后面,执行程序的时候,相当于是忽略你的定义的(因为在预编译阶段被移动到了堆),那么只有在执行到实例化具体的类的时候,才会去堆里查找有没有定义这个类,定义了按照堆里定义的类数据进行实例化,然后执行。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

我后悔之前不知道的 7 个 PHP 函数 我后悔之前不知道的 7 个 PHP 函数 Nov 13, 2024 am 09:42 AM

如果您是一位经验丰富的 PHP 开发人员,您可能会感觉您已经在那里并且已经完成了。您已经开发了大量的应用程序,调试了数百万行代码,并调整了一堆脚本来实现操作

您如何在PHP中解析和处理HTML/XML? 您如何在PHP中解析和处理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

php程序在字符串中计数元音 php程序在字符串中计数元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? 什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。

See all articles