公共、私有和受保护之间有什么区别?使用反射剖析爷爷班 常见误解:

2022-08-30 05:45:17

何时以及为何应在类中使用 、 和 函数和变量?它们之间有什么区别?publicprivateprotected

例子:

// Public
public $variable;
public function doSomething() {
  // ...
}

// Private
private $variable;
private function doSomething() {
  // ...
}

// Protected
protected $variable;
protected function doSomething() {
  // ...
}

答案 1

您可以使用:

  • publicscope,使该属性/方法可从任何位置、对象的其他类和实例使用。

  • private范围,当您希望您的属性/方法仅在其自己的类中可见时。

  • protectedscope(当您希望使属性/方法在扩展当前类(包括父类)的所有类中可见时。

如果不使用任何可见性修饰符,则属性/方法将是公共的。

更多: (全面信息)


答案 2

dd

公共:

将方法(函数)或属性(变量)声明为 时,可以通过以下方式访问这些方法和属性:public

  • 声明它的同一类。
  • 继承上述声明类的类。
  • 此类之外的任何外来元素也可以访问这些内容。

例:

<?php

class GrandPa
{
    public $name='Mark Henry';  // A public variable
}

class Daddy extends GrandPa // Inherited class
{
    function displayGrandPaName()
    {
        return $this->name; // The public variable will be available to the inherited class
    }

}

// Inherited class Daddy wants to know Grandpas Name
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

// Public variables can also be accessed outside of the class!
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry'

保护:

将方法(函数)或属性(变量)声明为 时,这些方法和属性可通过以下方式访问protected

  • 声明它的同一类。
  • 继承上述声明类的类。

外部成员无法访问这些变量。“Outsiders”的意思是它们不是声明类本身的对象实例。

例:

<?php

class GrandPa
{
    protected $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

确切的错误将是这样的:

PHP 致命错误:无法访问受保护的属性祖父::$name


私人:

将方法(函数)或属性(变量)声明为 时,可以通过以下方式访问这些方法和属性:private

  • 声明它的同一类。

外部成员无法访问这些变量。局外人,因为它们不是声明类本身的对象实例,甚至不是继承声明类的类。

例:

<?php

class GrandPa
{
    private $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Results in a Notice 

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

确切的错误消息将是:

注意:未定义的属性:爸爸::$name
致命错误:无法访问私有属性 爷爷::$name


使用反射剖析爷爷班

这个主题并不是真正超出范围,我在这里添加它只是为了证明反思真的很强大。正如我在上面三个示例中所述,成员(属性和方法)不能在类外部访问。protectedprivate

但是,通过反思,您甚至可以访问类外的受保护成员和私人成员,从而实现非凡的工作!

那么,什么是反射?

反射增加了对类、接口、函数、方法和扩展进行反向工程的能力。此外,它们还提供了检索函数,类和方法的文档注释的方法。

序言

我们有一个名为的类,并说我们有三个属性。为了便于理解,考虑有三个爷爷的名字:Grandpas

  • 马克·亨利
  • 约翰·克拉什
  • 威尔·琼斯

让我们分别使它们(分配修饰符)和。您非常清楚这一点,并且不能在类外访问成员。现在,让我们使用反射来反驳该语句。publicprotectedprivateprotectedprivate

代码

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected  modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}


# Scenario 1: without reflection
$granpaWithoutReflection = new GrandPas;

# Normal looping to print all the members of this class
echo "#Scenario 1: Without reflection<br>";
echo "Printing members the usual way.. (without reflection)<br>";
foreach($granpaWithoutReflection as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

echo "<br>";

#Scenario 2: Using reflection

$granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class
$granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private)


echo "#Scenario 2: With reflection<br>";
echo "Printing members the 'reflect' way..<br>";

foreach($granpaNames as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

输出:

#Scenario 1: Without reflection
Printing members the usual way.. (Without reflection)
The name of grandpa is Mark Henry and he resides in the variable name1

#Scenario 2: With reflection
Printing members the 'reflect' way..
The name of grandpa is Mark Henry and he resides in the variable name1
The name of grandpa is John Clash and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3

常见误解:

请不要与以下示例混淆。如您所见,如果不使用反射,则无法在类外部访问 and 成员privateprotected

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}

$granpaWithoutReflections = new GrandPas;
print_r($granpaWithoutReflections);

输出:

GrandPas Object
(
    [name1] => Mark Henry
    [name2:protected] => John Clash
    [name3:GrandPas:private] => Will Jones
)

调试函数

print_r,并且是调试器函数。它们以人类可读的形式显示有关变量的信息。这三个函数将揭示 PHP 5 对象的和属性。将显示静态类成员。var_exportvar_dumpprotectedprivate


更多资源:



推荐