PHP中关键字与魔术方法介绍
在php中魔术方法与关键字都是我们常用的,关键字有final、static 、const,魔术方法__call()、__toString() 、_clone() 、__autoload() 等等。
PHP中常用的关键字
final
1、final只能修饰类和方法,不能修饰成员属性,作用:使用修饰的类不能被继承,修饰的方法不能被覆盖,PHP 5 新增了一个 final 关键字,如果父类中的方法被声明为final,则子类无法覆盖该方法;如果一个类被声明为final,则不能被继承。
方法示例一,代码如下:
- <?php
- class BaseClass {
- public function test() {
- echo "BaseClass::test() called\n";
- }
- final public function moreTesting() {
- echo "BaseClass::moreTesting() called\n";
- }
- }
- class ChildClass extends BaseClass {
- public function moreTesting() {
- echo "ChildClass::moreTesting() called\n";
- }
- }
- // 产生 Fatal error: Cannot override final method BaseClass::moreTesting()
- ?>
方法实例二:
- <?php
- final class BaseClass {
- public function test() {
- echo "BaseClass::test() called\n";
- }
- // 这里无论你是否将方法声明为final,都没有关系
- final public function moreTesting() {
- echo "BaseClass::moreTesting() called\n";
- }
- }
- class ChildClass extends BaseClass {
- }
- // 产生 Fatal error: Class ChildClass may not inherit from final class (BaseClass)
- ?>
1.使用static可以修饰成员属性和成员方法,不能修饰类
2.用static修饰的成员属性,可以被同一个类的所有对象共享
3.静态的数据是存在于内存中的数据段中(初使化静态段)
4.静态的数据是在类第一次加载时分配到内存中的,后面用到时就可以直接使用了
5.只要在程序中有这个类名出现,即是类被加载,静态数据就会被分配到内存中了 注:静态的成员都要使用类名访
问:不用创建对象,不要用对象去访问静态成员,访问方法,类名::静态成员,如果在类中使用静态成员,可以使用self代表本类访问方法 self::静态成员
6.静态方法不能访问非静态成员,非静态方法可以访问静态成员,因为非静态成员必须用对象来访问,而静态成员不需要
例1代码如下:
- <?php
- function test()
- {
- static $var1=1;
- $var1+=2;
- echo $var1.' ';
- }
- test();
- test();
- test();
- ?>
例2代码如下:
- <?php
- Class Person{
- // 定义静态成员属性
- public static $country = "中国";
- // 定义静态成员方法
- public static function myCountry() {
- // 内部访问静态成员属性
- echo "我是".self::$country."人<br />";
- }
- }
- class Student extends Person {
- function study() {
- echo "我是". parent::$country."人<br />";
- }
- }
- // 输出成员属性值
- echo Person::$country."<br />"; // 输出:中国
- $p1 = new Person();
- //echo $p1->country; // 错误写法
- // 访问静态成员方法
- Person::myCountry(); // 输出:我是中国人
- // 静态方法也可通过对象访问:
- $p1->myCountry();
- // 子类中输出成员属性值
- echo Student::$country."<br />"; // 输出:中国
- $t1 = new Student();
- $t1->study(); // 输出:我是中国人
- ?>
运行该例子,输出:
中国
我是中国人
我是中国人
中国
我是中国人
首先,我们知道PHP中调用实例方法都是通过如:someobj->someFun()调用,那么我们调用静态函数是否也能像C#那样,通过SomeClass->someFun()调用呢?答案是否定的,在PHP中,对静态成员的调用只能通过::的方式进行,如:SomeClass::someFun(),代码如下:
- <?php
- class TestC
- {
- public static $var1=1;
- public $var2=1;
- function t1()
- {
- self::$var1+=2;
- echo self::$var1.' ';
- echo $this->var2.' ';
- }
- public static function t2()
- {
- self::$var1+=2;
- echo self::$var1.' ';
- }
- }
- $t=new TestC();
- $t->t1();
- TestC::t2();
- ?>
const
1.const只能修饰成员属性
2.类中使用const声明常量
3.用法类似定义一般常量
4.访问方式和静态成员是一样的(在类外 类名::常量名,类内 self::常量名)
5.常量一定要在声明时就给初值
语法:const constant = "value";
例子代码如下:
- <?php
- Class Person{
- // 定义常量
- const country = "中国";
- public function myCountry() {
- //内部访问常量
- echo "我是".self::country."人<br />";
- }
- }
- // 输出常量
- echo Person::country."<br />";
- // 访问方法
- $p1 = new Person();
- $p1 -> myCountry();
- ?>
运行该例子输出:
中国
我是中国人
PHP中小常用魔术方法:
__call() 在调用对象中不存在的方法时,就会调用此方法。就会出现系统报错,然后程序会退出。声明此方法来对错误进行操作,阻止程序崩溃。
__toString() 直接输出对象引用时调用,用来快速获取对象的字符串表示的最便捷的方式,代码如下:
- <?php
- // Declare a simple class
- class TestClass
- {
- public $foo;
- public function __construct($foo)
- {
- $this->foo = $foo;
- }
- public function __toString() {
- return $this->foo;
- }
- }
- $class = new TestClass('Hello');
- echo $class;
- ?>
void __clone(void)
当复制完成时,如果定义了__clone()方法,则新创建的对象(复制生成的对象)中的__clone()方法会被调用,可用于修改属性的值(如果有必要的话),代码如下:
- <?php
- class SubObject
- {
- static $instances = 0;
- public $instance;
- public function __construct() {
- $this->instance = ++self::$instances;
- }
- public function __clone() {
- $this->instance = ++self::$instances;
- }
- }
- class MyCloneable
- {
- public $object1;
- public $object2;
- function __clone()
- {
- // 强制复制一份this->object, 否则仍然指向同一个对象
- $this->object1 = clone $this->object1;
- }
- }
- $obj = new MyCloneable();
- $obj->object1 = new SubObject();
- $obj->object2 = new SubObject();
- $obj2 = clone $obj;
- print("Original Object:\n");
- print_r($obj);
- print("Cloned Object:\n");
- print_r($obj2);
- ?>
__autoload()其它的魔术方法都是在类中添加起作用,这个是唯一一个不在类中添加的方法,只要在页面中使用到一个类,只要用到类名就会自动传进此方法,代码如下:
- <?php
- session_start();
- require_once 'MyClass.php';
- $obj = new MyClass;
- $_SESSION['obj'] = $obj;
- ?>
运行正常,然后在后续页面加载,代码如下:
- <?php
- session_start();
- require_once 'MyClass.php';
- $_SESSION['obj']->callSomeMethod();
- ?>
致命错误:脚本试图执行一个方法或访问一个不完整的对象的属性,请确保对象的类定义“MyClass”你想操作被加载 _before_ unserialize()调用或提供一个__autoload()函数来加载类定义,但是如果你这样做,它将正常工作,代码如下:
- <?php
- require_once 'MyClass.php';
- session_start();
- $_SESSION['obj']->callSomeMethod();
- ?>
对象串行化:将一个对象转化为二进制串
1.将对象长时间存储在数据库或文件中时
2.将对象在多个PHP文件中传输时,serialize():参数是一个对象,返回的是一个二进制串 unserialize():参数是对象的二进制串,返回的就是新生成的对象,__sleep() 在序列化时自动调用的方法(serialize)
作用:可以将一个对象部分序列化,只要这个方法中返回一个数据组,数组中有几个成员属性就序列化几个成员属性,如果不加,所有成员属性都被序列化
__wakeup() 在反序列化时自动调用的方法(unserialize) 也就是对象重新诞生的一个过程
注意事项:PHP把所有以__(两个下划线)开头的类方法当成魔术方法。所以当你定义类方法时,除了上述魔术方法,建议不要以 __为前缀。