PHP的Calling Scope(::调用非静态方法)

摘要:
在PHP中,当调用方法时,$this指针指向的对象是调用方法时的调用范围?phpclassA{publicfunctiontest(){Foo::bar();}}$a=新a();$a-˃test();当调用bar方法时,它在$a对象的上下文中,也就是说,callingscope是$a对象,所以这不是静态调用。要验证这个结论,请参阅以下示例:˂?事实上,它更可能是由误用引起的,因为您在调用范围的上下文中以“静态形式”调用类的非静态方法。那么为什么PHP是这样设计的呢?

今天在群里发现有人说,PHP可以用::调用非静态方法,一致没这么试过,发现了鸟哥的blog写了这个问题的具体解释,就搬过来:

这个问题乍看, 确实很容易让人迷惑, 但实际上, 造成这样的误解的根本原因在于: 在PHP中, 判断静态与否不是靠”::”(PAAMAYIM_NEKUDOTAYIM)符号, 而是靠calling scope.

那么, 什么是calling scope?

在PHP中, 调用一个方法的时候, $this指针指向的对象就是这个方法被调用时刻的calling scope. 对于下面的例子:

<?php
Foo::bar();
?>

在调用bar方法的时候, 处于一个没有calling scope域的上下文中, 所以这个是静态调用.

而对于如下的例子:

<?php
class A {
     public function test() {
         Foo::bar();
     }
 }
$a  = new A();
$a->test();

在调用bar方法的时候, 处于一个$a对象的上下文中, 也就是说, 此时的calling scope是$a对象, 所以这个其实不是静态调用.

为了验证这一个结论, 请看下面的一个实际例子:

<?php
 class Foo {
     public function bar() {
         var_dump($this);
     }
 }
 class A {
     public function test() {
         Foo::bar();
     }
 }
 $a  = new A();
 $a->test();
?>

输出什么呢?

object(A)#1 (0) {
}

在调用bar的时候, 这个看似”静态”调用的调用, $this指针却是被赋值的, 指向的是$a对象, 那么这个还算静态调用么?

我举这个例子是为了说明这个问题, 但大家在实际的应用中, 大家尽量要避免使用”::”来调用一个非静态的方法, PHP也会对于这种调用给出一个Strict 警告:

也许有人会说这个应该算bug吧? 其实不然, 更多的应该是错误使用造成的, 因为你在一个有calling scope的上下文中采用”静态的形式”调用了一个类的非静态方法所致.

那么PHP为什么要这么设计呢? 考虑下面的例子:

<?php
 class A {
    public function __construct() {
    }
 }
 class B extends A {
    public function __construct() {
        parent::__construct();
   }
 }

当我们调用父类的构造函数的时候, 我们是有意的要把当前的scope传递给父类的构造函数作为calling scope的.

免责声明:文章转载自《PHP的Calling Scope(::调用非静态方法)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇019C#中使用移位运算符获取汉字编码值亮剑.NET的系列文章之.NET详解(开端)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

zabbix准备:php安装

一.安装php依赖库 ftp://xmlsoft.org/libxml2/libxml2-2.9.3.tar.gz yum install python-devel -y cd /download/ wget -c ftp://xmlsoft.org/libxml2/libxml2-2.9.3.tar.gz tar xf libxml2-2.9.3...

php Array

1. 创建数组 创建一个包含指定范围的数组   array range( mixed low, mixed high [, number step]); 基于变量创建一个数组   array compact( mixed varname [, mixed…]);   extract(array &array) 将数组解析为变量 2. 计算数组大小...

静态资源文件自动压缩并替换成压缩版本(大型网站优化技术)

  这一次,我总结和分享一项大型网站优化技术,那就是在项目中自动压缩静态资源文件(css、js),并让网站自动加载压缩后的资源文件。当然,这项技术在雅虎35条前端优化建议里也有记载,但它那只是给出一个理论的方案而已,并且采用的是外部压缩工具去压缩,而在我的项目中,是直接通过自己的程序自动化去压缩所有css、js文件,然后让页面直接加载所压缩后的资源,接下来...

php 图片操作类 Intervention Image

官方网址:http://image.intervention.io/ 1,安装composer require intervention/image (如果使用1.*的版本 ,要安装 "intervention/image": "1.*") 2,使用并初始化对象 require 'vendor/autoload.php'; useIntervention...

PHP安全

php如何做到安全 14 November 2013 0 一、概念和原则 所有的输入数据都是不安全的 我们不能信任任何外来的数据,例如用户的表单提交数据、请求字符串、甚至是RSS种子,都不能信任。这些数据都可以被伪造。 这些数据中可能故意包含某些字符,破坏程序的运行环境,例如可能包含有害的javascript代码。 因此,PHP预定义全局数组中的...

PHP控制语句之“switch”语句

前面给大家讲解了一种多重选择elseif语句,虽然这种语句可以进行多种判断,但是使用的时候,需要写很多的if语句,给我们程序的可读性带来不便,为了避免if语句过多和提高我们程序的可读性,可以使用switch多重判断语句,本章我们就给大家介绍“switch语句”。大理石平台精度等级 switch语句的语法: 1 2 3 4 5 6 7 8 9 10 11...