可以通过反射类访问的公共,私有,受保护类有啥用? [复制]

Posted

技术标签:

【中文标题】可以通过反射类访问的公共,私有,受保护类有啥用? [复制]【英文标题】:what is the use of public, private, protected class where it can be access via reflection class? [duplicate]可以通过反射类访问的公共,私有,受保护类有什么用? [复制] 【发布时间】:2014-09-14 04:35:36 【问题描述】:

出于安全目的和封装我们有 Public,Private, Protected 类的东西,但一个问题仍然在脑海中浮现,如果我们仍然可以访问或知道这些类的所有成员,这意味着什么是Public, Private 还是Protected??

例如:

<?php

 class GrandPas   // The Grandfather's class
  
   public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
   protected  $name2 = 'John ***';  // This grandpa is mapped to a protected  modifier
   private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
  
#Scenario: 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 "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 Using 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 *** and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3

我们可以看到该类的所有成员是否为Private, Protected or Public。那么这里的OOP是什么概念呢?

PS:示例来自 Shankar Damodaran。

【问题讨论】:

“反射通常用作软件测试的一部分,例如用于模拟对象的运行时创建/实例化。”来自wikipedia。 设计以后肯定会通过反射使用的类不是一种设计方式。您出于自己的应用程序的目的对类使用反射,例如一套测试服,而不是相反。 您说它们是出于“安全目的”,但事实并非如此。访问说明符旨在防止您在意外中做一些愚蠢的事情,而不是针对坚定的攻击者提供任何安全措施。 我需要同意@WaleedKhan ...任何可以实例化你的类的人,已经有了它的源代码并知道它的属性 为了好的设计、好看的代码和以后的重用。使用公共是不好的。想象一下,您的班级中有public $x。稍后在您的应用程序中执行echo $yourClassObject-&gt;x。稍后你去这个班,把$x改成$y。那么,回声不起作用。这就是为什么例如引入访问器并将字段设置为私有是更好的做法的原因 【参考方案1】:

TL;DR;

如果你可以做某事 - 这并不意味着你应该去做

反思

这是旨在提供有关实体的元信息的东西,但它的实际用例是有争议的,而且几乎总是可以用某些东西代替。重点不是说它不好,而是说——如果你想在你的架构中使用它,那么你可能有一个缺陷。

一种“去”的方式..

实际上,您可以在 PHP 中访问受保护/私有属性,而无需使用 Reflection。例如,Closure::bindTo() 喜欢:

class Test

   private $x = 'foo';


$z = new Test();

$y = function()

   return $this->x;
;
$y = $y->bindTo($z, $z);

echo $y(); //foo

然后.. 那又怎样?每种语言功能都可能用于好或坏。我们称其为“良好实践”和“不良实践”(老实说,我很难记住 PHP 中 global 之类的“良好实践”,但这不在这个问题范围内)。此外,在 PHP 中,您可能会以错误的方式使用很多东西 - 这使得它成为 困难 语言 - 从某种意义上说,学习该语言并不难,但很难全部使用它的功能正确,因为这需要扎实的架构和良好实践知识。

您可能会想像一种访问隐藏属性的方法,甚至可以使用 var_dump() + ob_ 函数之类的功能 - 但这只会说明使用某些不错的功能可能会有多么可怕。

以及如何处理

不要以这种方式使用Reflection。在构建架构时当然不要指望这一点。这不是它应该被使用的东西。如果你想从外部访问你的属性——那么——很好,将它们声明为public

只要正确使用东西。这是唯一的出路。如果你不知道什么是正确的用法 - 然后学习。这是我们一直在做的事情。每天。

【讨论】:

非常感谢您在这里解决了我的疑问,真是一个很好的例子。【参考方案2】:

publicprotectedprivate 令牌旨在为属性定义可见性,而不是以任何方式提供安全性。

可见性用于区分:

    您的公共界面, 暴露给类扩展的接口,或者, 内部状态。

反射主要是为了帮助提供诸如 AOP、DIC、代理等好东西;具体来说,它并不是黑客的工具。使用您的代码的人可以简单地阅读它以获得他们想要的东西,不,为了他们自己的“邪恶”目的而对其进行编辑。

【讨论】:

那么在主要用于安全目的的OOP概念中,有一个关于publicprivateprotected的误解。 @SudhanshuSaxena 我很想知道哪篇文章提到了这样的事情;他们显然在提倡错误的想法:) 此外,许多文档生成器提供了隐藏私有字段和方法的选项。这对于制作只有 public 方法字段和类的公共 API 文档很有用。 @janek2012 对,这也是可见性如何有用的一个例子:) 我还要补充一点,反射用于 DI 容器实现(用于分析类的构造函数),它不依赖于配置。

以上是关于可以通过反射类访问的公共,私有,受保护类有啥用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

受保护和私有有啥区别? [复制]

Java通过受保护的getter访问私有超类成员

抽象类中的抽象方法应该有啥访问修饰符?

“私有”和“受保护的内部”有啥区别?

在类的构造函数上使用受保护的访问修饰符

Objective-C - 私有与受保护与公共