我想创建一个PHP类,可以说Myclass.php。现在在该类中,我只想定义类本身和一些实例变量。但是所有方法都必须来自Myclass_methods.php文件。我可以只将该文件包含到班级正文中吗?
我有充分的理由为什么要分开这个。简而言之,我将拥有一个后端,在其中可以更改类的业务逻辑,而所有其他内容必须保持不变。系统为我维护所有ORM和其他内容。
但是,如果这不是一个好主意,则最好在编辑业务逻辑之后重新生成整个类文件(因此,在这种情况下为用户定义的方法)。
性能问题:如果在一个请求中仅包含一次Myclass.php,则实际上也应仅包含一次Myclass_methods.php。可能是错误的。专家?
不可以。您不能在类主体中包含文件。 在定义类的文件中,您只能在 方法主体中 或 类主体外部 包括文件。
根据您的描述,我认为您需要这样做:
<?php // MyClass.php class MyClass { protected $_prop; include 'myclass-methods.php'; } <?php // myclass-methods.php public function myMethod() { $this->$_prop = 1; }
运行此代码将导致
Parse error: syntax error, unexpected T_INCLUDE, expecting T_FUNCTION
这是可能的
<?php // MyClass.php class MyClass { protected $_prop; public function __construct() // or any other method { include 'some-functions.php'; foo($b); // echoes 'a'; } } <?php // some-functions.php $b = 'a'; function foo($str) { echo $str; }
这样,会将包含文件的内容导入方法范围,而不是类范围。您可以在包含文件中包括函数和变量,但不能包括方法。您 也可以但不应该 将整个脚本放入其中并更改方法的作用,例如
<?php // MyClass.php // ... public function __construct($someCondition) { // No No Code here include ($someCondition === 'whatever') ? 'whatever.php' : 'default.php'; } // ... <?php // whatever.php echo 'whatever'; <?php // default.php echo 'foo';
但是,用这种方式修补类以表现出不同的行为并不是您在OOP中应该做的。这完全是错误的,应该使您的眼睛流血。
由于要动态更改行为,因此扩展类也不是一个好选择(请参见下面的原因)。您真正想要做的是编写一个接口,并使您的类使用实现此接口的对象,从而确保可以使用适当的方法。这称为策略模式,其工作方式如下:
<?php // Meowing.php interface Meowing { public function meow(); }
现在,您获得了所有喵喵行为都必须遵守的合同,即拥有喵喵方法。接下来定义喵叫行为:
<?php // RegularMeow.php class RegularMeow implements Meowing { public function meow() { return 'meow'; } }
现在使用它,使用:
<?php // Cat.php class Cat { protected $_meowing; public function setMeowing(Meowing $meowing) { $this->_meowing = $meowing; } public function meow() { $this->_meowing->meow() } }
通过将MeowingTypeHint添加到setMeowing,可以确保所传递的参数实现了Meowing接口。让我们定义另一个喵叫行为:
<?php // LolkatMeow.php class LolkatMeow implements Meowing { public function meow() { return 'lolz xD'; } }
现在,您可以轻松地交换如下行为:
<?php require_once 'Meowing.php'; require_once 'RegularMeow.php'; require_once 'LolkatMeow.php'; require_once 'Cat.php'; $cat = new Cat; $cat->setMeowing(new RegularMeow); echo $cat->meow; // outputs 'meow'; // now to change the behavior $cat->setMeowing(new LolkatMeow); echo $cat->meow; // outputs 'lolz xD';
通过定义抽象的BaseCat和meow方法,然后从中派生具体的RegularCat和Lolkat类,您也可以通过继承解决上述问题,但是您必须考虑要实现的目标。如果您的猫永远不会改变它们的喵叫方式,请继续使用继承,但是如果您的RegularCat和Lolkat应该能够发出任意叫声,请使用“策略”模式。