PHP中静态(static)调用非静态方法详解
1.PHP中可以静态调用非静态方法么?
今天我被问到PHP中可不可以使用 className::methodName() 的方法来调用一个没有声明static的方法。在我的印象中,我好像是见过这种用法,但又有些不确定。大家都知道,在手册或者教程里,方法被分为静态方法 和非静态方法,通常我们静态调用的方法,肯定是静态方法。
那如果我们调用了非静态方法会怎么样呢?首先做测试。
<?php
class test{
function test() {
echo 'it works';
}
}
test::test();
?>
执行以下,返回错误如下:
Fatal error: Non-static method test::test() cannot be called statically in /home/×××/test.php
on line 7 Call Stack: 0.0002 332548 1. {main}() /home/×××/test.php:0
这个时候,可能大家就会认为静态调用非静态方法是行不通的了,但其实,结论下的过早了,因为test()这个方法比较特殊,与类同名,是构造方法。 我们继续测试。
<?php
class test {
function test() {
echo 'it works';
}
function test2() {
echo 'it works too';
}
}
test::test2();
?>
执行结果:
it works too
这说明,静态调用非静态方法是可行的,但是静态调用构造方法是不可以的。为了验证这个结论,我又做了如下测试:
<?php
class test{
static function test() {
echo 'it works';
}
}
test::test();
?>
执行的结果如下:
Fatal error: Constructor test::test() cannot be static in /home/xxx/test.php on line 9
构造方法不能声明静态,所以上面的推论正确。
但这个结果的确是很特殊的,因为可能只有PHP可以静态调用非静态方法,我用Java做了实验,如果静态调用非静态方法会报如下错误:
Cannot make a static reference to the non-static method showString() from the type HelloWorldApp
其他语言我没有一一尝试,但这已经足够来说明PHP的特殊之处,关于为什么PHP会有这样的情况我暂时没有找到相关说明。
2.静态调用非静态方法是否应该被应用?
那我们是不是可以使用这种方法来代替static方法呢? 首先在代码的可读性上来看,静态调用非静态方法当然是不被推荐的,这会让维护者产生疑惑。
接下来我们再做一些实验,来看一下静态调用非静态方法在效率上是否会有一定的优势。
<?php
class test{
function test2() { }
} for ($k=0; $k<10000; $k++) {
test::test2();
}
?>
上面代码在我这里的执行时间是18到28毫秒,我们再来测试标准的写法。
<?php
class test{
static function test2(){ }
} for ($k=0; $k<10000; $k++) {
test::test2();
}
?>
上面的代码执行时间在5到10毫秒之间,这样看来,静态调用非静态方法的效率要比标准的静态方法调用低的多,所以在效率上也不推荐静态调用非静态方法。
发现WordPress中居然在用这么诡异的调用方式:
class-wp.php 第 206-207行:// Substitute the substring matches into the query.
$query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
这里用的静态调用,而实际的成员函数却不是静态的。
注意:PHP不能静态调用非静态属性
<?php
class test{
var $id = '123';
function test2() {
echo 'it works';
}
}
echo test::$id;
?>
报错:
Fatal error: Access to undeclared static property: test::$id in D:phpxampphtdocs est.php on line 8
PHP中静态(static)调用非静态方法详解的更多相关文章
- PHP中静态(static)调用非静态方法详解--调用!!!
来源:https://www.cnblogs.com/yolo-bean/p/7739265.html 这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么 ...
- Java 中的 static 使用之静态方法
与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法.其实之前我们一直写的 main 方法就是静态方法.静态方法的使用如: 运行结果: 需要注意: 1. 静态方法中可以直接调用 ...
- Static、Final关键字详解
1.Static 详情见下面代码讲解 点击查看代码 package com.Tang.oop.demo07; public class Student { private static int age ...
- PHP中静态方法(static)与非静态方法的使用及区别
今天再次学习这个内容,总是糊里糊涂的,想弄明白!!! static关键字用来修饰属性.方法,称这些属性.方法为静态属性.静态方法.static关键字声明一个属性或方法是和类相关的,而不是和类的某个特定 ...
- java中静态方法中为什么不能使用this、super和直接调用非静态方法
这个要从java的内存机制去分析,首先当你New 一个对象的时候,并不是先在堆中为对象开辟内存空间,而是先将类中的静态方法(带有static修饰的静态函数)的代码加载到一个叫做方法区的地方,然后再在堆 ...
- php静态调用非静态方法
<?php /** * php静态调用非静态方法 * author: 百里 * Date: 2019/7/18 * Time: 17:28 */ function dump(...$var) { ...
- PHP 类中静态方法调用非静态方法
静态方法调用非静态方法: 在类中静态方法中,需要实例化对象,然后再调用类中的方法 非静态方法调用静态方法: 可以self 或者 类名加::的形式调用 如下面的案例: <?php class A{ ...
- JAVA Main方法中调用非静态方法
在JAVA中静态方法中只能调用其他,静态方法.main方法都是静态方法,如果想调用其它的方法,要么只能是其它的静态方法.还有一种方法就是将当前类实例化在调用它的非静态方法 public class t ...
- java中静态属性和和静态方法的继承问题 以及多态的实质
首先结论是:java中静态属性和和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏. 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成的,不需继承机制就可以调用如果子类里 ...
随机推荐
- Tomcat7服务器删除后重新安装失败问题
学习JSP时,需要修改conf下的配置文件,确发现无论如何修改权限都无法保存,所以决定卸载重装到D盘,卸载时又弹出一个对话框,具体内容没看,但是就是卸载不了,所以打算手动删除. 删除后,重装时安装失败 ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- Slam(即时定位与地图构建) 知识篇
Slam即时定位与地图构建 技术解释 同步定位与地图构建(SLAM或Simultaneous localization and mapping)是一种概念:希望机器人从未知环境的未知地点出发,在运动过 ...
- mysql utf8编码
做微信项目,报错 "Incorrect string value: '\\xF0\\x9F\\x98\\x8B' for column 'nickname' at row 1" 原 ...
- ASP.NET WebForm中异步请求防止XSRF攻击的方法
在ASP.NET MVC中微软已经提供了如何防止跨域攻击的方法.对于传统Webfrom中使用Handler来接受ajax的Post请求数据,如何来防止XSRF攻击呢.这里给大家提供一个简单地方法,和M ...
- title与alt的区别
html中的title属性和alt属性让人有些混淆. 以前不知道有title这个属性,第一次用到它时,就和alt产生了混淆.一位朋友告诉我说,alt是图片img标签里用的,title是超链接里用的, ...
- Linq to Xml读取复杂xml(带命名空间)
前言:xml的操作方式有多种,但要论使用频繁程度,博主用得最多的还是Linq to xml的方式,觉得它使用起来很方便,就用那么几个方法就能完成简单xml的读写.之前做的一个项目有一个很变态的需求:C ...
- SDN与NFV技术在云数据中心的规模应用探讨
Neo 2016-1-29 | 发表评论 编者按:以云数据中心为切入点,首先对SDN领域中的叠加网络.SDN控制器.VxLAN 3种重要技术特点进行了研究,接下来对NFV领域中的通用服务器性能.服务链 ...
- python基础-RE正则表达式
re 正则表示式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写 ...
- C#嵌入dll到资源释放的问题
有些程序运行的时候,可能调用外部的dll,用户使用时可能会不小心丢失这些dll,导致程序无法正常运行,因此可以考虑将这些dll嵌入到资源中,启动时自动释放.对于托管的dll,我们可以用打包软件合成一个 ...