【问题标题】:How to allow Object creation of a class on only particular classes in PHP?如何允许仅在 PHP 中的特定类上创建类的对象?
【发布时间】:2016-03-31 06:10:30
【问题描述】:

在 PHP 中,假设有四个类 A、B、C 和 D。它们都不继承另一个。它们都是独立的类。现在,我只希望 B 和 C 能够创建 A 类的对象。D 不应该能够创建 A 类的对象。

这可以在 PHP 中完成吗?如果是,如何?我尝试刷新我的面向对象概念,但似乎无法在 PHP 中找到合适的答案。

不胜感激。

【问题讨论】:

  • 投反对票的人,请告诉我为什么?
  • 我认为函数debug_backtrace()会在这里帮助你
  • @ChetanAmeta Ok Lemmi 看看。谢谢
  • 见我回答中的例子
  • 也许你能解释一下你为什么要这样做?这可能会提供更好的建议来解决您的实际问题。

标签: php algorithm class oop design-patterns


【解决方案1】:

PHP 没有为这种限制提供任何明确的方法。

虽然这个问题对我来说听起来很奇怪(为什么要这样做?)我可以在这里想象两种可能的方法,都有严重的缺点:

  1. 您可以尝试限制对类定义的访问: 在能够实例化某个类的对象之前,必须知道类定义。为此使用了两种策略:

    a) 在需要时加载类定义的显式包含语句。这显然可以通过基础系统来阻止。要么通过暴力拒绝权限,所以如果你处理文件权限,尽管这会导致运行时错误。或者通过替换实际文件,例如通过使用根据需要更改的级联符号链接。

    b) 一些自动加载机制。这种情况显然允许实现一个额外的过滤步骤,该步骤可能会加载一些虚假的类定义,或者在应该拒绝访问目标类的情况下简单地抛出错误。

  2. 您可以主动阻止对象创建。同样有两种变体:

    a) 在类构造函数中抛出异常。很不礼貌的事情……

    b) 遵循工厂模式并将类构造函数声明为非公开的,并且仅提供静态生成器方法作为实例化类对象的唯一方法。这更加透明,方法可以引发异常或拒绝返回预期结果。

为此,您显然需要一些信息来决定是否应批准请求。应该可以评估执行堆栈以检测从哪个代码段触发了对象创建。对该信息的词汇分析或与某些目录的比较可以构成决策的基础。

但正如开头所说:所有方法都有缺点。这听起来更像是对可能性的错误使用......虽然......可能性有待探索,对吧? ;-)

【讨论】:

  • 感谢您的解释。我将讨论你提到的第二点。而且由于我在这个领域没有你那么有经验,所以你的第一点就超出了我的想象。为了便于理解,您能否提供任何我可以阅读的链接?
  • 您能否更详细地说明您在第一点中不了解的具体内容是什么?
  • 你说“在能够实例化某个类的对象之前,必须知道类定义”是什么意思?
  • 好吧,在你真正包含那个类的实现之前,试试$obj = new MyClass; 之类的东西。显然行不通。这就是我所说的“必须知道”的意思。
【解决方案2】:

我认为这里的功能 debug_backtrace 会帮助你。看看下面的例子。

class A
{
    public function __construct()
    {
        echo debug_backtrace()[1]['class'];
    }
}

class B
{
    public function createObj()
    {
        $obj = new A();
    }
}

class C
{
    public function createObj()
    {
        $obj = new A();
    }
}

class D
{
    public function createObj()
    {
        $obj = new A();
    }
}

$o = new B();
$o->createObj(); //echo B

$o = new C();
$o->createObj(); //echo C

$o = new D();
$o->createObj(); //echo D

A 类的__construct 中,您可以根据您的要求设置条件。

但是恕我直言,继承和抽象是该任务的更好选择。

【讨论】:

  • 这看起来像是 gnna 工作,并且是@arkascha 在他的回答中在#2 中指出的。我会试试看,然后回来。
猜你喜欢
  • 2013-11-29
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 2017-04-02
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
相关资源
最近更新 更多