PHP-为什么对象在代码中的不同位置会产生不同的结果?
请注意PHP-为什么对象在代码中的不同位置会产生不同的结果?,php,class,instantiation,Php,Class,Instantiation,请注意include_once语句在以下所有示例中的位置: 这项工作: include_once __DIR__ . '/vendor/autoload.php'; use Symfony\Component\HttpFoundation\Request; $request = Request::createFromGlobals(); echo $request->getMethod(); 我以为这不管用,但它确实管用: use Symfony\Component\Htt
include_once
语句在以下所有示例中的位置:
这项工作:
include_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
echo $request->getMethod();
我以为这不管用,但它确实管用:
use Symfony\Component\HttpFoundation\Request;
include_once __DIR__ . '/vendor/autoload.php';
$request = Request::createFromGlobals();
echo $request->getMethod();
但这失败了:
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
include_once __DIR__ . '/vendor/autoload.php';
echo $request->getMethod();
这也是:
include_once __DIR__ . '/vendor/autoload.php';
$request = Request::createFromGlobals();
use Symfony\Component\HttpFoundation\Request;
echo $request->getMethod();
我猜只要在类被使用/实例化之前代码中有use
和include\u一次
,代码就可以正常工作
是这样吗
非常感谢对流程的详细解释。use语句不调用自动加载程序,也不检查类是否存在,它只是将该“名称”拉入当前名称空间。在您尝试使用它之前,不会调用autoloader,PHP也不会查找该类以查看它是否存在。use语句不会调用autoloader,也不会检查该类是否存在,它只是将该“名称”拉入当前名称空间。在您尝试使用它之前,不会调用自动加载程序,PHP也不会查找该类以查看它是否存在。PHP脚本的执行分两个阶段进行:首先编译脚本,如果没有语法错误,编译器将生成一系列所谓的“操作码”。然后,解释器开始执行脚本;这意味着它将一个接一个地获取操作码,解释它们并执行它们编码的操作 在开始执行之前只编译主脚本,包括的文件(使用其中一个函数)在执行期间编译 让我们看看你的脚本会发生什么 包括一次 这些语句生成的代码告诉解释器:“在此处停止当前脚本的执行,加载并编译此文件,如果它不包含语法错误,则在继续此脚本之前执行其代码” 也就是说,在主脚本的编译阶段不会读取包含的文件,只有在运行时需要时才会读取。在这段代码中:
if (false) {
include 'a.php';
}
从不读取文件a.php
的内容;更重要的是,解释器甚至不关心文件是否存在。只有当include
语句即将执行时,它才开始关心a.php
,但由于if(false)
测试,这种情况从未发生
使用
该语句用于创建别名。这样的别名只是程序员和编译器之间的协议,编译器不会为它生成任何代码
通过使用以下语句:
use Symfony\Component\HttpFoundation\Request;
程序员告诉编译器:“嘿,我想让您知道,稍后在这个文件中,当您找到令牌请求
时,我的意思是\Symfony\Component\HttpFoundation\Request
,但是我更喜欢只使用请求
,因为它比较短。”
use
语句不允许在生成的代码中进行任何跟踪。它们在运行时不存在。守则:
use Symfony\Component\HttpFoundation\Request;
$request = new Request();
同:
$request = new \Symfony\Component\HttpFoundation\Request();
为它们生成相同的代码;在汇编过程中,第一种形式被“转换”为第二种形式
自动装弹机
文件vendor/autoload.php
的内容(可能)是由Composer生成的自动加载器。是使用注册的可调用(函数或类方法),当代码到达对未知类的引用时,解释器将执行该方法。自动加载程序接收完整的类名(带有名称空间),其目的是使该类可用。它通常知道在哪里可以找到类(在文件中)。可以注册多个自动加载程序,解释器逐个调用它们,直到类可用或所有自动加载程序都失败
它是如何运行的
让我们替换代码变体中的别名,看看我们得到了什么
变体#1和#2产生相同的代码:
include_once __DIR__ . '/vendor/autoload.php';
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
echo $request->getMethod();
在运行期间:
语句加载并注册自动加载器李>include_once
-类$request=\Symfony\Component\HttpFoundation\request::createFromGlobals()
未知,解释器调用包含声明该类的文件的自动加载程序;然后执行类的方法\Symfony\Component\HttpFoundation\request
,并返回类型为createFromGlobals
的对象李>\Symfony\Component\HttpFoundation\Request
不是$request
,它的类实现了方法null
;方法被调用,它返回的值通过getMethod()
显示,每个人都很高兴echo
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
include_once __DIR__ . '/vendor/autoload.php';
echo $request->getMethod();
include_once __DIR__ . '/vendor/autoload.php';
$request = Request::createFromGlobals();
echo $request->getMethod();
运行方式:
$request=\Symfony\Component\HttpFoundation\request::createFromGlobals()代码>-尚未声明类
,并且没有注册自动加载程序-解释器找不到该类,无法继续 PHP致命错误:找不到类“Symfony\Component\HttpFoundation\Request”\Symfony\Component\HttpFoundation\Request
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
include_once __DIR__ . '/vendor/autoload.php';
echo $request->getMethod();
include_once __DIR__ . '/vendor/autoload.php';
$request = Request::createFromGlobals();
echo $request->getMethod();
别名不会被替换,因为它是在使用后声明的
在运行期间:
语句加载并注册自动加载器李>include_once
$request=request::createFromGlobals()代码>-尚未定义类
;解释器调用自动加载器,但自动加载器找不到;口译员无法继续 致命错误:找不到类“请求”请求
- PHP脚本的执行分为两个阶段:首先编译脚本,如果没有语法错误,编译器将生成一系列所谓的“操作码”。然后,解释器开始执行脚本;这意味着它将一个接一个地获取操作码,解释它们并执行它们编码的操作
只编译主脚本