我可以将代码包含在 PHP 类中吗?

2022-08-30 09:32:18

我想做一个PHP类,比如Myclass.php。现在,在该类中,我只想定义类本身和一些实例变量。但所有方法都必须来自Myclass_methods.php文件。我可以将该文件包含在类正文中吗?

我有充分的理由想要将其分开。简而言之,我将有一个后端,我可以在其中更改类的业务逻辑,而所有其他内容必须保持不变。系统为我维护所有ORM和其他东西。

但是,如果这是一个坏主意,那么在编辑业务逻辑后重新生成整个类文件可能会更好(因此,在这种情况下,用户定义的方法)。

性能问题:如果在一个请求期间,Myclass.php只包含一次,实际上Myclass_methods.php也应该只包含一次。可能是错的。专家?


答案 1

不。不能在类正文中包含文件。
在定义类的文件中,只能包含方法主体中或类主体外部的文件

从你的描述中,我带你想要这个:

<?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()
    }
}

通过将 Meowing TypeHint 添加到 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应该能够做任意的喵喵声,那么使用策略模式。

有关 PHP 中的更多设计模式,请查看以下资源:


答案 2

创建具有相关基本功能的核心类,然后使用所需的方法扩展它可能不是一个想法 - 这似乎是一种更合乎逻辑的方法。


推荐