有没有办法在调用构造函数之前设置属性?

2023-12-26

是的,我知道依赖项应该传递给构造函数。我不是在问编码风格或该做什么和不该做什么。

我的应用程序中的许多类都与数据库驱动程序类的实例相关联。为此,我使用 PHP 的后期静态绑定创建了一个抽象工厂类。该类的唯一成员是保存驱动程序引用的属性。它看起来像这样:

abstract class Factory {

    static private $__instances;
    static private $__default_driver;

    protected $_driver;

    static public function getInstance ( \Database\Driver $driver = null ) {
        if ( ! isset($driver) ) {
            if ( ! isset(self::$__default_driver) ) {
                require ( \Core\Options::$database_driver[ 'path' ] );
                self::$__default_driver = new \Core\Options::$database_driver[ 'class' ]( \Core\Options::$database_options );
            }
            $driver = self::$__default_driver;
        }

        $schema = $driver->getDatabase();
        $class  = get_called_class();

        if ( ! isset(self::$__instances[ $schema ][ $class ]) ) {
            self::$__instances[ $schema ][ $class ] = new $class( $driver );
            self::$__instances[ $schema ][ $class ]->_driver = $driver;
        }

        return self::$__instances[ $schema ][ $class ];
    }
}

正如您所看到的,当我创建派生类的实例时,我将驱动程序的实例传递给其构造函数。然后设置属性。如果可能的话,我想通过先设置属性然后调用构造函数来扭转这种情况。这样,派生类不需要实现构造函数,也不需要担心调用父方法(如果需要)。

我已经调查过ReflectionAPI 可以做到这一点,但我似乎找不到任何可行的方法。最多Dependency Injection我发现链接实际上使用了构造函数。这需要在 PHP 5.3 上运行。

对于那些坚持认为这是不可能的人来说,在 PHP 5.4 中可以轻松完成 http://www.php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php#108466 using ReflectionClass::newInstanceWithoutConstructor().


class Foo {
    public function __construct() {
        echo 'foo';
    }
}

$r = new ReflectionClass('Foo');
$o = $r->newInstanceWithoutConstructor();
$o->bar = 'baz';
$o->__construct();

从 PHP 5.4 开始,这是可能的。

但说实话:不。就是不行。不。实例化对象时,应始终调用对象的构造函数。不早(显然),也不晚。构造函数和对象其余部分的适当封装保证了对象始终处于一致的状态。一旦你开始使用它拆开ReflectionClass无法再对对象的状态做出任何保证,并且健全性和类型安全性也将被抛诸脑后。

因为你使用的是 5.3,所以你很幸运,那里没有办法做到这一点。如果你发现自己陷入了这样的困境,那么你就做错了。已经编写了非常复杂的程序,无需欺骗 PHP 的对象模型来延迟构造函数调用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法在调用构造函数之前设置属性? 的相关文章

随机推荐

  • 如何将当前行的值除以下一行的值?

    在 Spark Sql 1 6 版本中 使用DataFrames 有没有一种方法可以计算特定列的每一行当前行与下一行相除的分数 例如 如果我有一个只有一列的表 如下所示 Age 100 50 20 4 我想要以下输出 Franction 2
  • 如何显示下一张/上一张卡片的RecyclerView的一部分

    实现此功能的最佳策略是什么 我有一个带有卡片的水平 RecyclerView 每张卡片都会填满整个屏幕 但我希望它显示下一张卡片和上一张卡片 如果它有多个项目 的一部分 我知道我可以通过设置我的卡来实现这一点android layout w
  • 从java中的String中删除除少数特定标签之外的Html标签

    我的输入是纯文本字符串 要求是删除除少数特定标签之外的所有 html 标签 例如 p li u u li li 如果这些特定标签具有类似属性class or id 我想删除这些属性 几个例子 a href Link a gt Link li
  • Hadoop 2.2.0 与 Mahout 0.8 兼容吗?

    我的 hadoop 集群版本 2 2 0 与 mahout 0 8 一起运行 它兼容吗 因为每当我运行这个命令时 bin mahout recommenditembased input mydata dat usersFile user d
  • Google 云端硬盘帮助需要访问自己的云端硬盘帐户

    我想在网页上访问我自己的谷歌驱动器 但允许任何人上传文件并限制下载访问或仅向用户显示有限的文件以供下载 Drive API 假设我将访问其他用户的凭据 但我想要的恰恰相反 任何人都可以查看我的文件 限制查看内容 但可以自由上传 我googl
  • 为什么不能修改 Mongoose 查询返回的数据(例如:findById)

    当我尝试更改 Mongoose 查询返回的数据的任何部分时 它没有任何效果 昨天我花了大约两个小时试图解决这个问题 有各种各样的问题 clone s 使用临时存储变量等等 最后 就在我以为自己要疯了的时候 我找到了解决办法 所以我想将来有人
  • GWT:如何从 RootPanel 获取对按钮的引用?

    我正在使用 GWT 2 4 在我的 onModuleLoad 方法中 给定一个字符串 id 如何从 RootPanel 对象获取对页面上现有按钮的引用 我正在尝试这个 public void onModuleLoad final Butto
  • 存储一个正整数需要多少位?

    存储一个正整数 例如数十亿 需要多少位 您是否必须使用 log2 N 才能找到答案 由于我多次看到错误报告的答案 我想我会发布正确的答案 表示正整数 n 所需的位数为 bits floor log2 n 1 其中 log2 表示以 2 为底
  • Fabric JS:鼠标按下时复制/粘贴对象

    我正在尝试创建一个块游戏 您可以从菜单中选择形状并将它们放置在画布上 有一个形状菜单 您可以将形状拖到画布上 我希望它在将克隆拖到画布上时将主要形状保留在菜单中 这可能吗 我创建了一个 jsfiddle 来提供帮助 JSFIDDLE htt
  • gfortran 不适用于 Mac OS X 10.9

    我将 Mac 更新到 OS X 10 9 GM 然后发现 gfortran 不起作用 构建任何程序时 它都会显示 ld library not found for lcrt1 10 5 o collect2 ld return 1 有谁知道
  • ReactJS - 即使从选择下拉列表中选择相同的选项也会触发事件

    当从 ReactJS 的下拉列表中选择一个选项时 如何触发事件 目前我正在使用onChange但即使再次选择相同的选项 我也需要触发一个事件 当前代码
  • java.net.ConnectException

    我看过一些关于这个主题的帖子 但我仍然不知道出了什么问题 以下是代码 import java sql public class SQL public static void main String args Connection conn
  • 从IP地址获取位置[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话
  • AttributeError:“float”对象没有属性“split”

    我正在调用这条线 lang modifiers keyw strip for keyw in row language modifiers split if not isinstance row language modifiers flo
  • android.view.Surface - OutOfResourcesException

    我有这个奇怪的错误 但没有找到任何可能的解决方案 在使用我的应用程序后 问题总是随机出现 该应用程序几乎可以在所有设备上完美运行 仍然存在此问题的设备之一正在运行 CM 7 1 0 我知道很多 CM7 用户都在抱怨类似的问题 不幸的是 我有
  • 如何有条件地在 JSP 页面中显示一个 div 的内容而不是另一个 div 的内容?

    我对JSP开发很陌生 我有以下疑问 如果进入 JSP 页面我有 2div像这样 div p SUCCESS p div div p FAILURE p div 我必须根据 a 的值仅显示这些 div 之一status变量放入Http会话只能
  • 比较文件内字母顺序的最佳方法?

    我有一个文件 其中有很多字母序列 其中一些序列可能是相同的 所以我想对它们进行全部比较 我正在做这样的事情 但这并不完全是我想要的 for line in fl line line split for elem in line if gt
  • Go HTTP 服务器性能问题

    我正在编写一个事件收集器http 服务器 该服务器将承受重负载 因此 在 http 处理程序中 我只是反序列化事件 然后在 goroutine 中的 http 请求 响应周期之外运行实际处理 由此 我发现如果我以每秒 400 个请求的速度访
  • Json反序列化,创建重复对象

    展示问题的模型比首先尝试解释它更容易 internal class Program private static void Main string args Class1 class1 new Class1 Name Scott Class
  • 有没有办法在调用构造函数之前设置属性?

    是的 我知道依赖项应该传递给构造函数 我不是在问编码风格或该做什么和不该做什么 我的应用程序中的许多类都与数据库驱动程序类的实例相关联 为此 我使用 PHP 的后期静态绑定创建了一个抽象工厂类 该类的唯一成员是保存驱动程序引用的属性 它看起