Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Selectivley根据对方法的外部或内部调用公开函数_Php_Oop_Inheritance_Yii_Encapsulation - Fatal编程技术网

Php Selectivley根据对方法的外部或内部调用公开函数

Php Selectivley根据对方法的外部或内部调用公开函数,php,oop,inheritance,yii,encapsulation,Php,Oop,Inheritance,Yii,Encapsulation,这个问题与我试图实现的目标非常相似,但正如我在几乎每个问题的答案中所指出的,这是一个糟糕的设计 以下是我试图实现的目标: 跟踪在低活动配置表上执行的所有操作,以便将更改传播到生产和QA数据库。(配置表=配置存储在表中。) 以下是我问题的概要: Yii中的所有模型都是从CActiveRecord类扩展而来的,该类提供了一些方法来操作模型实例 让我们将其分为两类: 非原语-触发onBeforeDelete、onAfterFind、onAfterSave等事件(例如:) 原语——直接创建和执行命令而

这个问题与我试图实现的目标非常相似,但正如我在几乎每个问题的答案中所指出的,这是一个糟糕的设计

以下是我试图实现的目标:
跟踪在低活动配置表上执行的所有操作,以便将更改传播到生产和QA数据库。(配置表=配置存储在表中。)

以下是我问题的概要:
Yii中的所有模型都是从CActiveRecord类扩展而来的,该类提供了一些方法来操作模型实例

让我们将其分为两类:

  • 非原语-触发onBeforeDelete、onAfterFind、onAfterSave等事件(例如:)
  • 原语——直接创建和执行命令而不触发事件——即充当查询生成器。(例:)
  • 现在,这些原语也是公共成员,因此可以由用户自行决定从类外调用——它们将修改表而不触发任何事件

    以下是我提出的解决方案:

  • 为所有开发人员制定只使用非原语方法的准则
  • 将CActiveRecord封装在我自己的模型类中,并仅公开非原语
  • 案例1将更容易实现,但更容易出错,因为有时一些开发人员可能会忘记限制而使用原始方法

    案例2将要求我编写大量代码/方法,公开我希望使用的方法。此外,如果Yii CActiveRecord和我的ActiveRecord类没有相同的接口,这可能会导致混淆


    我认为,更好的解决方案是允许在内部使用原语,同时限制外部调用,即使用私有/公共访问说明符。(这已经与我在案例2中提供的原因相矛盾,但这是我能想到的唯一解决方案。)由于我不能在不封装的情况下使用私有/公共说明符,并且我不能封装,所以我想在方法中区分函数是外部调用还是内部调用debug_backtrace是一个可行的解决方案,但我在这里是为了一个更优雅、不太老套的解决方案,或者一个明确的声明,这是不可能做到的。

    首先,你应该后退一步,想想为什么行为会有如此大的差异。调用非基元的方法应在模型实例上调用:

    $ar = new Something();
    $ar->update(...);
    
    虽然您调用primitive的方法应该在模型本身上调用:

    Something::model()->updateByPk(...);
    
    显然,在第二种情况下提出事件是没有意义的,因为

  • 您根本不应该直接使用
    ::model()
    ,并且
  • 根据方法的不同,该操作可能会影响PHP中没有相应模型实例的多个记录
  • 因此,寻求解决方案应首先回答以下两个问题:

  • 在一个完美的世界中,当调用模型上的任何方法时,会如何通知您?(显然,要使调用有意义,该方法必须是原始的)
  • 在一个完美的世界中,如果一个操作影响了未知数量的记录(在PHP中),您将如何得到通知

  • 虽然这个问题可能很有趣,但它更适合@hek2mgl,在你提到之前,我不是programmers.stackexchange.com的成员,谢谢你,我会调查一下。是的,我想你会得到更好的答案。另外,我会在问题中添加一些解释代码。我无法正确突出显示代码,因此我通过github链接引用代码,我对CActiveRecord类的扩展与这个问题无关,因此我没有发布它。如果我能给出一个一般性的建议:
    为所有开发人员只使用非原始方法制定指导原则。
    这不起作用,因为开发人员不会这样做。尤其是在最后期限到来的时候。(这是我的经验)你也会一次又一次地提醒他们关于指导方针的事情。(对这两个网站来说都很烦人)我会搜索一个自动解决方案我理解你所说的“你不应该直接使用
    ::model()
    ”是什么意思,但我需要一个方法来实现这一点。此外,在数据库层上使用触发器是实现这一点的理想场所——如果找不到解决方案,我会退回到这个问题上——我想从这个问题中得到的是,确保在Yii中没有可能实现这一点。@AdeelHasanAkbari:你不能以任何理智的方式强制执行这一点。你不应该触摸静态模型,所以不要触摸。当你真正想写新的Foo()的时候,你就不能打字并写出
    Foo::model()
    。此外,我还发布了一些你需要回答的反问题。如果你甚至不能回答“你希望它如何工作”,那么显然它永远不会起作用。因为你也是一名编程老师,我将把这当作一个练习,尽我最大的能力回答你的问题,如果我犹豫不决,我希望你能耐心地对待我。1.在编程方面,我会在封装后使用magic方法
    \uu call()
    ,了解在模型上调用了哪些方法。2.我可以分析由操作-查询解析器生成的查询,或者采用更简单、更可靠的方法,使用触发器跟踪更改。@AdeelHasanAkbari:我不是说如何实现它们,我是说您希望如何公开它们?换句话说,假设这个特性存在,并且神奇地按照您想要的方式工作。使用它的代码会是什么样子?我现在明白了。。。这充其量也会很尴尬。一段根据您与之交互的方式进行变形/调整的代码可能会有些混乱。谢谢你让我思考!我