设为首页 收藏本站
查看: 860|回复: 0

[经验分享] .NET程序员学PHP:static关键字

[复制链接]

尚未签到

发表于 2015-8-24 12:36:43 | 显示全部楼层 |阅读模式
  学习PHP也有一段时间了,有些东西觉得还是需要总结一些,对于.NET程序员来说,PHP中有很多概念都跟以前的理解不一样,这里我们将重点分析下static关键字。
  static关键字在C#编程中非常常见,它用来修饰符声明属于类型本身而不是属于特定对象的静态成员。static 修饰符可用于类、字段、方法、属性、运算符、事件和构造函数,但不能用于索引器、析构函数或类以外的类型。声明为static的类、函数和变量将不能引用实例方法或变量,另外在C#中一旦类被添加了static修饰符,则其内部所有变量和方法都必须是静态的。静态变量和方法必须通过类名进行引用而不能通过实例对象引用。
  那么static关键字在php中与C#中都有些什么不同呢?

声明范围。
  相对C#来说,PHP中static变量的使用范围要更广一些,我们不仅可以在类,方法或变量前面添加static修饰符,我们甚至还能给函数内部变量添加static关键字。添加了static修饰符的变量即使在该函数执行完毕值仍然不会丢失,也就是说,在下一次调用这个函数时,变量仍然记得原来的值。如:





<?php
function test(){
    static $var1=1;
    $var1+=2;
    echo $var1.'&nbsp';
}
test();
test();
test();
?>
  代码会输出:3 5 7
  这里有一点需要注意的是,变量的赋值操作只会在变量第一次初始化时会被调用,在之后函数的执行过程中,这个操作不会被调用。
  由于PHP中函数同样是一等公民,所以不同于C#,我们可以直接定义函数,并直接在代码的任何地方调用,这一点跟javascript倒是有些相似。因此这时候函数静态变量会比定义全局变量更加有用,它可以避免变量重复定义导致冲突。而由于C#中函数无法直接定义和调用,它必须寄宿在类中,所以如果函数需要静态变量,我们只需要在类中定义便能达到相同效果。

调用方式
  C#中,我们调用静态成员的方式非常简单和一致,因为静态成员不属于实例对象,所以无论是方法还是变量,C#对其静态成员的访问方式一律是通过类名.方法(变量)进行。并且在C#中,静态函数是不能被设置为虚方法或者覆盖的。而PHP对此则提供了更为灵活多样的支持。
  首先,我们知道PHP中调用实例方法都是通过如:someobj->someFun()调用,那么我们调用静态函数是否也能像C#那样通过SomeClass->someFun()调用呢?答案是否定的,在PHP中,对静态成员的调用只能通过::的方式进行,如:SomeClass::someFun()。



DSC0000.gif DSC0001.gif 代码



<?php
class TestC{
    public static $var1=1;
    public $var2=1;
    function t1(){
        self::$var1+=2;
        echo self::$var1.'&nbsp';
        echo $this->var2.'&nbsp';
    }
    public static function t2(){
        self::$var1+=2;
        echo self::$var1.'&nbsp';
    }
}
$t=new TestC();
$t->t1();
TestC::t2();
  结果输出为:3 1 5
  另外一点和C#中不同的是,在类中的方法中,如果我们需要调用静态变量,必须通过self::$somVar静态变量(注意变量前面的$符号,实例变量不需要),而调用静态方法则为self::someFun()(这里不需要$符号)。如上例。
  另外,与C#最大的不同之处就是,PHP中,子类是可以覆盖父类的静态函数或变量的,不仅如此,(站在C#程序员的角度来看,我觉得PHP这点反而将事情搞复杂了),由于默认self::staticFun()调用的是子类的静态函数,这个时候如果我们想调用父类的静态变量怎么办呢?这里PHP提供了额外的parent来调用基类的静态成员。如:


代码



<?php
class Test1{
    public static $var1=1;
    public static function t2(){
        self::$var1+=2;
        echo self::$var1.'&nbsp';
    }
}
class Test2 extends Test1{
    static $var1=‘Hello’;
    static function t2(){
        parent::t2();
        echo self::$var1.'&nbsp';
    }
}
Test1::t2();
Test2::t2();
?>
  结果输出为:3 5 Hello
  最好,根据上面的例子我们很容易想到,子类访问父类可以使用parent关键字,那么父类如何访问子类的静态方法呢?这里给出static的另外一个用法,这里如果将调用的静态方法前面的作用域换成static的话,PHP会根据该类的继承层次来计算最终的静态方法。如:



代码



<?php
class Test1{
    function t1(){
        static::t2();
    }
    public static function t2(){
        echo self::'Test1&nbsp';
    }
}
class Test2 extends Test1{
    static function t2(){
        echo self::'Test2&nbsp';
    }
}
$t=new Test2();
$t->t1();
Test2::t2();
?>
  结果输出为:Test2 Test2。
  这里t实例在t1方法调用t2静态方法时,会根据其实例找到最终的静态方法并输出Test2。

生命周期
  由于.NET和PHP本质的不同,所以static在两种语言中运行时会有明显的不同,在.NET中,static是伴随程序生命周期而存在的,也就是说任何.NET程序,不管是ASP.NET Web程序还是普通的WinForm程序,只要程序启动之后,static的值就会被一直保留,比如我们访问一个Web站点时,如果里面有个int的访问计数的静态变量表示访问人数,只要IIS和该进程没有停止,静态变量值就不会被重置。但在PHP中,static值仅在用户的一次访问过程中存在,也就是说,static的生命周期为从用户发送请求到服务器端返回最终视图结果的整个过程,在这之后,所有的静态变量都会被服务器释放掉,直到下次用户发送新的请求重新初始化。

总结
  从上面的分析,我们不难看出,对于静态成员的使用,PHP提供了比C#更为强大的功能或灵活性,但从我的角度来看,这种灵活性不见得就更好,从某种角度来看,如果类的继承层次过于复杂,它可能会让我产生混淆。当然,同样的工具不同人使用效果会完全不一样,既然PHP提供了更多样的选择,那么相信如果使用恰当的话,PHP中的static可能会提供比C#中更为强大而简便的使用方式。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-103499-1-1.html 上篇帖子: windows下php实现在线预览附件(pdf) 下篇帖子: php的session和cookie
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表