首页 >php教程 >php手册 >PHP中关键字与魔术方法介绍

PHP中关键字与魔术方法介绍

WBOY
WBOY原创
2016-05-25 16:55:111002浏览
在php中魔术方法与关键字都是我们常用的,关键字有final、static 、const,魔术方法__call()、__toString() 、_clone() 、__autoload() 等等。

PHP中常用的关键字

final  

1、final只能修饰类和方法,不能修饰成员属性   作用:使用修饰的类不能被继承,修饰的方法不能被覆盖

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为final,则子类无法覆盖该方法; 如果一个类被声明为

final,则不能被继承。

Example #1 Final 方法示例

 代码如下 复制代码
 代码如下 复制代码

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()
?>
Example #2 Final 类示例

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)
?>

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()

?>Example #2 Final 类示例

 代码如下 复制代码

function test()
{
static $var1=1;
$var1 =2;
echo $var1.' ';
}

test();
test();
test();
?>

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)<🎜>?>
static  1.使用static可以修饰成员属性和成员方法,不能修饰类  2.用static修饰的成员属性,可以被同一个类的所有对象共享  3.静态的数据是存在于内存中的数据段中(初使化静态段)  4.静态的数据是在类第一次加载时分配到内存中的,后面用到时就可以直接使用了  5.只要在程序中有这个类名出现,即是类被加载,静态数据就会被分配到内存中了   注:静态的成员都要使用类名访问,不用创建对象,不要用对象去访问静态成员。   访问方法 类名::静态成员   如果在类中使用静态成员,可以使用self代表本类   访问方法 self::静态成员  6.静态方法不能访问非静态成员,非静态方法可以访问静态成员,因为非静态成员必须用对象来访问,而静态成员不需要例1
 代码如下 复制代码
function test()<🎜>{<🎜>    static $var1=1;<🎜>    $var1 =2;<🎜>    echo $var1.' ';<🎜>}<🎜><🎜>test();<🎜>test();<🎜>test();<🎜>?>

例2

例子:

 代码如下 复制代码
 代码如下 复制代码

Class Person{
// 定义静态成员属性
public static $country = "中国";
// 定义静态成员方法
public static function myCountry() {
// 内部访问静态成员属性
echo "我是".self::$country."人
";
    }
}
class Student extends Person {
    function study() {
        echo "我是". parent::$country."人
";
    }
}
// 输出成员属性值
echo Person::$country."
";  // 输出:中国
$p1 = new Person();
//echo $p1->country;   // 错误写法
// 访问静态成员方法
Person::myCountry();   // 输出:我是中国人
// 静态方法也可通过对象访问:
$p1->myCountry();

// 子类中输出成员属性值
echo Student::$country."
"; // 输出:中国
$t1 = new Student();
$t1->study();    // 输出:我是中国人
?>

Class Person{

    // 定义静态成员属性

    public static $country = "中国";
    // 定义静态成员方法
    public static function myCountry() {
        // 内部访问静态成员属性
        echo "我是".self::$country."人
";

    }

}
class Student extends Person {

    function study() {

        echo "我是". parent::$country."人
";

    }

}

// 输出成员属性值

echo Person::$country."
";  // 输出:中国

$p1 = new Person();
 代码如下 复制代码
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();
?>
//echo $p1->country;   // 错误写法

// 访问静态成员方法
Person::myCountry();   // 输出:我是中国人
// 静态方法也可通过对象访问:
$p1->myCountry();

// 子类中输出成员属性值

echo Student::$country."
"; // 输出:中国

$t1 = new Student();

$t1->study();    // 输出:我是中国人

?>

运行该例子,输出:
 代码如下 复制代码

Class Person{
    // 定义常量
    const country = "中国";

    public function myCountry() {
        //内部访问常量
        echo "我是".self::country."人
";
    }
}

// 输出常量
echo Person::country."
";

// 访问方法
$p1 = new Person();
$p1 -> myCountry();
?>

中国我是中国人我是中国人中国我是中国人首先,我们知道PHP中调用实例方法都是通过如:someobj->someFun()调用,那么我们调用静态函数是否也能像C#那样通过SomeClass->someFun()调用呢?答案是否定的,在PHP中,对静态成员的调用只能通过::的方式进行,如:SomeClass::someFun()。 
 代码如下 复制代码
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";例子:
 代码如下 复制代码
";    }}// 输出常量echo Person::country."
";// 访问方法$p1 = new Person();$p1 -> myCountry();?>

运行该例子输出:

中国
我是中国人


PHP中小常用魔术方法:

__call()   在调用对象中不存在的方法时,就会调用此方法。就会出现系统报错,然后程序会退出。声明此方法来对

错误进行操作,阻止程序崩溃。

__toString()   直接输出对象引用时调用,用来快速获取对象的字符串表示的最便捷的方式

 代码如下 复制代码
 代码如下 复制代码

// 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;
?>


 

// Declare a simple class
class TestClass

{

    public $foo;

    public function __construct($foo)

    {
代码如下 复制代码

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);

?>

        $this->foo = $foo;

    }

    public function __toString() {

        return $this->foo;
 代码如下 复制代码

session_start();
require_once 'MyClass.php';
$obj = new MyClass;
$_SESSION['obj'] = $obj;
?>

    }

}

 代码如下 复制代码

session_start();
require_once 'MyClass.php';
$_SESSION['obj']->callSomeMethod();
?>

$class = new TestClass('Hello');echo $class;?>  void __clone ( void )当复制完成时, 如果定义了__clone()方法, 则新创建的对象(复制生成的对象)中的__clone()方法会被调用, 可用于修改属性的值(如果有必要的话)。 
 代码如下 复制代码
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()   其它的魔术方法都是在类中添加起作用,这个是唯一一个不在类中添加的方法   只要在页面中使用到一个类,只要用到类名就会自动传进此方法
 代码如下 复制代码
session_start();<🎜>require_once 'MyClass.php';<🎜>$obj = new MyClass;<🎜>$_SESSION['obj'] = $obj;<🎜>?>
Works fine.  Then on a subsequent page load:
 代码如下 复制代码
session_start();<🎜>require_once 'MyClass.php';<🎜>$_SESSION['obj']->callSomeMethod();?>

致命错误:脚本尝试执行方法或访问不完整对象的属性。请

确保您尝试操作的对象的类定义“MyClass”已加载

_before_ unserialize() 被调用或提供 __autoload() 函数来加载类定义.

但是如果你这样做,效果很好:

新生成的对象    __sleep()   在序列化时自动调用的方法(serialize)   作用:可以将一个对象部分返回序列化  只要
这个方法中一个数据组,数据库中有几个成员属性就序列化几个成员属性,如果不加,所有成员属性都被序列化
 代码如下
 代码如下 复制代码

require_once 'MyClass.php';
session_start();
$_SESSION['obj']->callSomeMethod();
?>

复制代码


require_once 'MyClass.php';session_start();

$_SESSION['obj']->callSomeMethod();

?>

对象串联化:将一个对象转化为二进制串   1.将对象长时间存储在数据库或文件中时   2.将对象在多个PHP文件中传输

输出时serialize():参数是一个对象,返回是一个二进制串 unserialize():参数是对象的二进制串,返回的就是

__wakeup()   在反序列化时自动调用的方法(unserialize)   聪对象重新诞生的一个过程

建议不要以 __ 为远处。

教程链接:轻松转载~但请保留教程地址★
声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn