PHP作用域$GLOBALS &单例


PHP Scope, $GLOBALS & Singletons

我很难得到几个非常基本的PHP问题的答案。我看过的视频教程都是关于使用 PHP编写服务器端脚本的基础知识,但实际上很少解释PHP的工作原理。

假设我们有两个用户同时从世界不同的地方连接到同一个LAMP服务器,并且都请求Widget.php.

(a) Apache/PHP如何有效地"复制2个实例"的Widget.php脚本&它的依赖关系,以便2个HTTP请求分别处理?

(b)根据上面(a)部分,PHP如何划分用户请求以保持它们的分离?如果Widget.php使用一个名为$_SESSION['cheese']的会话变量,PHP如何为这两个用户分别保持cheese的值?

(c) PHP $GLOBALS是用户级还是应用级?意思是,对于全局变量$GLOBALS['bread'],用户1和2都共享相同的引用,或者PHP保持它们分开,因为它与会话变量在上面(b)?

(d) PHP $GLOBALS变量和实现单例设计的对象之间有什么区别?如果应用程序只能访问单例的一个实例,那么它不是全局的吗?是否需要考虑性能方面的因素?

将php应用程序看作是每次服务器请求时都执行的脚本,而不是存在于服务器内存中的应用程序。当一个HTTP请求进入脚本时,$_SESSION['cheese']对于请求它的用户来说是唯一的,因为会话id存储在客户端浏览器的cookie中。

全局变量只是具有脚本范围的变量,因此对于发送HTTP请求的用户来说是相同的。单例类是一种只能有一个实例的类,与全局类不同。

PHP脚本是无状态的,因为当脚本完成执行时,对象持有的所有值将丢失。让对象在两次执行之间持久化的唯一方法是序列化到数据库、会话或文件系统。

(a) PHP像大多数其他CGI实现一样运行。当web服务器接收到一个特定URL的请求,而这个URL恰好是一个.cgi/.php脚本,那么解释器就会被引用的脚本调用。PHP解释器运行它,并将输出发送回web服务器/客户端。完成后,CGI解释器终止并带走所有运行时数据。

这解释了为什么变量不能在两个不同的PHP脚本或调用之间持久化或共享。它与普通mod_php处理程序的工作原理相同。只有在那里,它是简单的进程分叉(复制)和终止。

(b) $_SESSION数组由PHP处理。它可以使用唯一的cookie密钥识别每个用户的存储。而且由于每个CGI或mod_php进程都有一个单独的变量池,所以实际上没有问题。当同一个用户同时请求两个脚本时,PHP只需要一点文件锁定来防止两个脚本覆盖会话存储。

(c)"全局"变量也只存在于每个进程中。当PHP脚本完成后,它们会像其他所有东西一样消失。

(d)这是两个不同的概念。我明白你说的用法相似是什么意思。但全局变量只是一个共享作用域,可能更接近于值对象。您可以使用全局标识符访问两者,但这是相似之处。

a)你在问apache/php是如何工作的??那太有野心了……长话短说:php将对每个请求编译Widget.php, apache将通过Http协议

发送响应。

b)你的服务器将保存SESSION数据在一个数据库或文件或神奇的地方(我真的不知道在哪里和如何做到的,我只关心它被保存)。对于每个请求,浏览器将发送一个包含会话id的会话cookie, PHP将使用该会话id将适当的信息加载到$_SESSION变量中。(类似于数据库表上的主键)

c)它是用户范围的(脚本端),但它不会像会话一样保存在页面之间。

d) $GLOBALS是一个变量,单例是一个对象,它有属性,方法,访问器,可以被继承,覆盖,等等

祝你好运!

对于B,用户持有一个唯一的ID,称为UUID,它存储在cookie中。这样服务器就可以通过读取这个唯一的id来区分用户,并返回相应的session值。

$GLOBALS是应用范围的

单例对象在某种程度上是全局的,但你不一定有一个实例,存在于具体的时刻…