php面向对象 $this关键字用法详解

 更新时间:2016年11月25日 15:01  点击:2011
本文章来给各位同学介绍在php类中我们会常用到this 关键字了,下面我简单的分析一下在php面向对象 $this关键字用法希望此教程对各位同学会有所帮助呀。

在前面我们知道,在对象外部访问对象成员属性和方法,使用对象的引用来完成。而在对象内部中,成员方法访问自己对象中的其它成员属性或者成员方法,要使用特殊的对象引用"$this->值"的形式来访问,成员属于哪个对象,$this引用就代表哪个对象,并且只能在对象的成员方法中使用。

为了解决php类和对象中变量与属性的命名冲突和不确定性问题,引入了”$this”关键字来调用当前的对象。

在类中调用当前对象的属性和方法,必须使用”$this->”关键字;$this在构造函数中指该构造函数所创建的新对象;方法内的局部变量不属于对象,不使用$this关键字取值。使用$this关键字,我们可以在类中调用对象属性或者方法。

1、调用变量

实例:

 代码如下 复制代码
<?php
 class user{
  private $n;
  function __construct(){
   $name="Mike";
   echo $this->n=$name;
  }
 }
 $p=new user();
?>

2、调用方法

实例:

 代码如下 复制代码

<?php
 class cal{
  public function sum($a,$b){
   return $a+$b;
  }
  public function prt($a,$c){
   return $a*$c;
  }
  public function result($a,$b,$c){
   $a=$this->sum($a,$b);
   return $this->prt($a,$c);
  }
 }
 $c=new cal();
 echo "(2+3)*10= " .$c->result('2','3','10');
?>


我们来看一下下面的例子,$this在做了什么?

 代码如下 复制代码
class Person{
//下面是人的成员属性
var $name; //人的名子
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
function __construct($name="", $sex="", $age=""){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say() {
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
//对象克隆时自动调用的方法, 如果想在克隆后改变原对象的内容,需要在__clone()中重写原本
的属性和方法
function __clone(){
//$this指的复本p2, 而$that是指向原本p1,这样就在本方法里,改变了复本的属性。
$this->name="我是假的$that->name";
$this->age=30;
}
}
$p1=new Person("张三", "男", 20);
$p2=clone $p1;
$p1->say();
$p2->say();
?>

上例输出:

执行结果
我的名子叫:张三性别:男我的年龄是:20
我的名子叫:我是假的张三性别:男我的年龄是:30

我们来看一下上面的代码中$this做了什么:

1、访问对象内部的成员,如$this->name

2、访问对象的其它方法,如在say()方法内部访问了其之外的$this->run()和$this->eat("apple")方法。

另外还有一点值得注意的是,局部变量和成员属性可以同名,但作用范围和访问方式不一样,如在eat()方法体内的$name相当于局部变量,其作用范围只限于eat方法内部,而Person的成员属性声明部分的 $name,则相当于全局变量,可以其它方法中使用$this->name的形式访问。

 代码如下 复制代码

< ?php  
class UserName 
{  
//定义属性  
private $name; 
//定义构造函数 
function __construct( $name ) 

$this->name = $name;
//这里已经使用了this指针 

//析构函数 
function __destruct(){}  
//打印用户名成员函数 
function printName() 

print( $this->name );
//又使用了PHP关键字this指针 

}  
//实例化对象 
$nameObject = new UserName
( "heiyeluren" );  
//执行打印 
$nameObject->printName();
 //输出: heiyeluren 
//第二次实例化对象 
$nameObject2 = new UserName( "PHP5" ); 
//执行打印 
$nameObject2->printName(); //输出:PHP5 
?>

在php中如果我们要定义常量有很多方法,但在类中我们要定义常量多半会用到const常量修饰符来定义了,下面小编来给各位同学介绍一下操作办法。

在PHP中定义常量是通过define()函数来完成的,但在类中定义常量不能使用define(),而需要使用const修饰符。类中的常量使用const定义后,其访问方式和静态成员类似,都是通过类名或在成员方法中使用self访问,但在PHP 5.3.0之后也可以使用对象来访问。被const定义的常量不能重新赋值,如果在程序中试图改变它的值将会出现错误。

 代码如下 复制代码

<?php 

     class MyClass { 

           const CONSTANT = 'CONSTANT value' ; //使用const声明一个常量,并直接赋上初使值 

              function showConstant() {                

                   echo  self ::CONSTANT ."<br>" ;//使用self访问常量,注意常量前不要加“$” 

             } 

      } 

      echo MyClass:: CONSTANT . "<br>" ; //在类外部使用类名称访问常量,也不要加”$” 

      $class = new MyClass();                      

     $class->showConstant();                       

      echo $class ::CONSTANT;  // PHP 5.3.0之后 

?>

关注细节:使用const定义的常量名称前不需要使用“$“符号,且常量名称通常都是大写的。

试图为const定义的常量赋值,将会出现错误。

 代码如下 复制代码

<?php 

  class MyClass { 

           const CONSTANT = 'CONSTANT value' ;   

               function setCONSTANT(){ 

                self ::CONSTANT  = 'news CONSTANT' ;//程序运行结果将会出错。 

     }                                                                                  

      } 

      echo MyClass:: CONSTANT ;                                                     

?>

程序运行结果将会出错。


使用const修饰的常量更其它的常量 有点不同的地方就是:常量名前不要使用”$”,切记!当然这个常量值也是不能修改的,一旦定义就不能程序的任何地方进行“人为”的修改。这跟使用 define定义是一样,还有就是使用const来定义当然也遵守其它常量的命名规则


扩展阅读:

常量前面没有美元符号($);
常量只能用 define() 函数定义,而不能通过赋值语句;
常量可以不用理会变量范围的规则而在任何地方定义和访问;
常量一旦定义就不能被重新定义或者取消定义;
常量的值只能是标量;
常量只能包含标量数据(boolean,integer,float 和 string),不要定义 resource常量.
可以用函数 constant() 来读取常量的值.get_defined_constants()可以获得所有已定义的常量列表.
如果使用了一个未定义的常量,PHP 假定想要的是该常量本身的名字,如同用字符串调用它一样(CONSTANT 对应 “CONSTANT”),此时将发出一个 E_NOTICE 级的错误.
PHP 的“魔术常量”.

名称

说明

__LINE__

文件中的当前行号。

__FILE__

文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。

__FUNCTION__

函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

__CLASS__

类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

__METHOD__

类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

本文章来给各位同学介绍一下关于php面向对象__toString() 用法详解,, __toString() 方法是自动被调用的,是在直接输出对象引用时自动调用的


我们前面说过在类里面声明“--”开始的方法名的方法(PHP给我们提供的),都是在某一时刻不同情况下自动调用执行的方法,“__toString()”方法也是一样自动被调用的,是在直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,比如说:“$p=new Person()“中,$p就是一个引用,我们不能使用echo 直接输出$p, 这样会输出”Catchable fatal error: Object of class Person could not be converted to string“这样的错误,如果你在类里面定义了“__toString()”方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用了”__toString()”方法, 输出“__toString()”方法中返回的字符,所以“__toString()”方法一定要有个返回值(return 语句).

代码

 代码如下 复制代码

<?php
    // Declare a simple class
    class TestClass
    {
        public $foo;

        public function __construct($foo) {
        $this->foo = $foo;
        }
       //定义一个__toString方法,返加一个成员属性$foo
        public function __toString() {
        return $this->foo;
        }
    }

    $class = new TestClass('Hello');

    //直接输出对象
    echo $class;
?>

似曾相识,在php面向对象编程之魔术方法__set,曾经介绍了什么是魔术方法,这一章又介绍一个魔术方法__tostring()。


__toString()是快速获取对象的字符串信息的便捷方式,似乎魔术方法都有一个“自动“的特性,如自动获取,自动打印等,__toString()也不例外,它是在直接输出对象引用时自动调用的方法。


__toString()的作用

当我们调试程序时,需要知道是否得出正确的数据。比如打印一个对象时,看看这个对象都有哪些属性,其值是什么,如果类定义了toString方法,就能在测试时,echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。

下面我们来看一个__toString()的实例

 

 代码如下 复制代码

<?php 

02 class Person{ 

03     private $name = ""; 

04     function __construct($name = ""){ 

05                    

06         $this->name = $name; 

07     } 

08     function say(){ 

09                    

10         echo "Hello,".$this->name."!<br/>";   

11     } 

12     function __tostring(){//在类中定义一个__toString方法 

13         return  "Hello,".$this->name."!<br/>";     

14     } 

15 } 

16 $WBlog = new Person('WBlog'); 

17 echo $WBlog;//直接输出对象引用则自动调用了对象中的__toString()方法 

18 $WBlog->say();//试比较一下和上面的自动调用有什么不同 

19 ?>


程序输出:

Hello,WBlog!

Hello,WBlog!


如果不定义“__tostring()”方法会怎么样呢?例如在上面代码的基础上,把“ __tostring()”方法屏蔽掉,再看一下程序输出结果:


Catchable fatal error: Object of class Person could not be converted to string


由此可知如果在类中没有定义“__tostring()”方法,则直接输出以象的引用时就会产生误法错误,另外__tostring()方法体中需要有一个返回值。

本文章来给大家介绍一下关于在php面向对象__call处理错误调用技巧吧,call在以前很少用,今天就来给大家测试一下。


在提到__call之前,先来看一个实例的测试结果,以便更好地去了解__call方法的作用。上代码:

在调用对象中不存在的方法时就会出现系统报错,然后程序退出不能继续执行。如果在类中添加一个“魔术”方法__call(),则调用对象中不存在的方法时就会自动调用该方法,并且程序可以继续向下执行。可以通过在__call()方法中的设置,提示用户调用的方法及需要的参数列表内容不存在。__call()方法需要两个参数,第一个参数是调用不存在的方法时,接受这个不存在的方法的方法名,并将这个不存在的方法中,使用的参数列表形成数组传给__call()方法中的第二个参数。

代码

 代码如下 复制代码

 <?php

    //这是一个测试的类,里面没有属性和方法
    class Test
    {
    }


    //产生一个Test类的对象

    $test=new Test();


    //调用对象里不存在的方法

    $test->demo("one", "two", "three");


    //程序不会执行到这里

    echo "this is a test<br>";


?>

运行结果:Fatal error: Call to undefined method Test::demo()

我们知道,程序的运行结果抛出了错误提示,在运行的过程中抛出错误后就已经中断了,以致”$Person->say();“这个正确的方法也不能再继续运行。看一下上面的代码就知道,Person类并没有代码错误,错就错在实例化Person类的过程中调用了Person类中并不存在的方法,如run()和eat()。

  在程序的运行中,出现如上抛出的的错误是致命性的,整个程序将崩溃。为了处理这种错误的同时让程序继续执行,我们可以在类中添加一个魔术方法__call,来调用对象中不存在的方法时自动调用该方法,并且使程序可以继续向下执行。

下面将在上面的代码的基础上多添加一个__call方法并调试,代码如下:
代码

 代码如下 复制代码

 <?php

    //这是一个测试的类,里面没有属性和方法
    class Test
    {

        //调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数

        function __call($function_name, $args)
        { 

            print "你所调用的函数:$function_name(参数:"; 

            print_r($args); 

            echo "不存在!<br>n";

        }

    }


    //产生一个Test类的对象

    $test=new Test();


    //调用对象里不存在的方法

    $test->demo("one", "two", "three");


    //程序不会退出可以执行到这里

    echo "this is a test<br>";

?>

运行结果:

你所调用的函数:run(参数:Array ( [0] => teacher ) )不存在!

你所调用的函数:eat(参数:Array ( [0] => child [1] => apple ) )不存在!

Hello, wblog!

这次程序的运行结果不再抛出致命性错误,在调用不存在的方法时自动调用了__call方法捕捉处理不存在的方法并提示给用户,而调用存在的方法时程序正常执行。


总结:在类中添加一个魔术方法__call,在调用对象中不存在的方法时就会自动调用该方法,并且程序可以继续向下执行。

本文章来给大家简单的介绍一下关于php自动加载类__autoload()的方法,希望此方法对各位同学会有所帮助哦。

作用:当在程序中需要实例化一个类,刚好这这类又不是在本文件中,则需要用包含函数将外部文件包含进来。但是,当要用的外部类很多后,就会发现用包含函数会显得十分的繁琐,这是就可以用__autoload()全局函数自动加载类。

当在index.php中要使用前面三个类时,就需要写三个例如include("name.class.php") 这样的方法,效率会十分低,但如果使用了__autoload()函数就不用这样麻烦了,只需要写这样一个函数方法就可以了:

在 PHP 5 中,不再需要这样了。可以定义一个 __autoload() 函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

在下例中将通过实例来说明 __autoload() 是如何使用的。


首先定义一个类ClassA,文件名为ClassA.class.php

 代码如下 复制代码

 class ClassA{ 

 public  function funa(){ 

   echo "classA  loaded successfully!<br>"; 

  } 

}

然后在相同目录下再定义另一个类ClassB,文件名为ClassB.class.php,ClassB继承ClassA

 <?php 

 代码如下 复制代码

 class ClassB extends ClassA { 

 public function funb(){ 

                                                       

   echo "classB also loaded successfully!<br>"; 

  } 

 }

最后在与上面两个文件相同目录下再定义一个autoload.php(这个文件名随便取)

 代码如下 复制代码

 <?php 

function __autoload($class_name) { 

    require_once ("./".ucfirst($class_name).'.class.php');//ucfirst使类名首字母转换为大写 

 $obj = new ClassB(); 

$obj->funa(); 

$obj->funb(); 

?>

运行autoload.php的程序,看结果:

classA loaded successfully!

classB also loaded successfully!


例子: 文件夹下有这样几个文件:

User.class.php;
Person.class.php;
Message.class.php;
index.php;


我们就可以这样操作

 代码如下 复制代码

index.php

function __autoload($className){     //ucfirst() 将字符串首字母变为大写

include("ucfirst($className)".class.".php"); }

/**************

*例如:在index.php文件中实例化User.class.php中的User类,如果不存在则自动调用__autoload()函数

 代码如下 复制代码

*,将类名User作为参数传入

*************/

$user=new User();

//通过自动加载类调用User.class.php文件

$person=new Person();

//通过自动加载类调用Person.class.php文件

$Message=new Message();

//通过自动加载类调用Message.classphp文件 function="" message="new" person="new" user="new">

[!--infotagslink--]

相关文章

  • java8如何用Stream查List对象某属性是否有重复

    这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
  • R语言 如何删除指定变量或对象

    这篇文章主要介绍了R语言删除指定变量或对象的操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
  • JavaScript预解析,对象详解

    这篇文章主要介绍了JavaScript预解析,对象的的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助...2021-11-10
  • C# 中的var关键字详细介绍

    这篇文章主要介绍了C# 中的var关键字详细介绍的相关资料,需要的朋友可以参考下...2020-06-25
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • 牛叉的Jquery――Jquery与DOM对象的互相转换及DOM的三种操作

    只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的dom操作。这就需要我们知道如何将jQuery对象和DOM的相互转换的方法。1...2015-10-30
  • C#中的yield关键字的使用方法介绍

    yield这个关键字是和迭代器挂钩的,而且是与return一起以yield return的形式合用的,用来返回迭代器中的条目。...2020-06-25
  • js如何打印object对象

    js调试中经常会碰到输出的内容是对象而无法打印的时候,光靠alert只能打印出object标示,却不能打印出来里面的内容,甚是不方便,于是各方面整理总结了如下一个函数,能够将数组或者对象这类的结果一一打印出来,具体代码如下: fu...2015-10-21
  • javascript self对象使用详解

    这篇文章主要介绍了javascript self对象使用详解的相关资料,需要的朋友可以参考下...2016-10-20
  • 替换json对象中的key最佳方案

    本文给大家介绍如何替换json对象中的key,通过实例代码给大家介绍key的替换方法,代码也很简单,需要的朋友参考下吧...2021-06-02
  • 详解Javascript中的Object对象

    这篇文章主要介绍了详解Javascript中的Object对象,需要的朋友可以参考下...2016-03-01
  • Spring Data JPA 关键字Exists的用法说明

    这篇文章主要介绍了Spring Data JPA 关键字Exists的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-10
  • php关键字仅替换一次的实现函数

    对于批量替换关键字的问题,仅替换而言没什么可说的,但这里需要的是每个关键字仅需要替换一次就可以了。查阅了php相关函数文档,发现php本身是没有函数实现这个功能的,所以不得不自己解决了。总结了几种可行方法,小记一下! (1...2015-10-30
  • c# volatile 关键字的拾遗补漏

    这篇文章主要介绍了c# volatile 关键字的相关资料,帮助大家更好的理解和学习c#的相关知识,感兴趣的朋友可以了解下...2020-12-08
  • Bootstrap媒体对象的实现

    在web页面中,图片居左,内容居右排列,是非常常见的效果,它也就是媒体对象,它是一种抽象的样式,可以用来构建不同类型的组件。本文给大家介绍Bootstrap媒体对象的实现,感兴趣的朋友一起学习吧...2016-05-04
  • 用python获取txt文件中关键字的数量

    这篇文章主要介绍了如何用python获取txt文件中关键字的数量,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下...2020-12-24
  • ActiveX部件不能创建对象:dm.dmsoft代码:800A01AD

    vbs调用插件报:ActiveX部件不能创建对象,代码:800A01AD,一般是因为病毒导致dll文件丢失或者64系统问题导致,需要的朋友可以参考下...2020-06-30
  • 理解JavaScript事件对象

    这篇文章主要为大家介绍了JavaScript事件对象,了解JavaScript事件...2016-01-26
  • 对象题目的一个坑 理解Javascript对象

    这篇文章主要介绍了Javascript对象,特别为大家分享了对象题目的一个坑,提供了解题思路,感兴趣的小伙伴们可以参考一下...2015-12-24
  • Xml中使用foreach遍历对象实现代码

    这篇文章主要介绍了Xml中使用foreach遍历对象实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-04