PHP 命名空间覆盖 Use 语句

标签 php inheritance model-view-controller namespaces

谁能告诉我是否可以覆盖 use 语句?

我的示例是 MVC 设置,其中的核心代码能够使用扩展核心版本的自定义版本覆盖每个 Controller /模型。

我面临的问题是我的核心 Controller 有一个 use 语句告诉它使用核心模型,所以如果我扩展模型,我不知道如何告诉它使用自定义模型而不是核心模型

我显然可以更新核心 Controller 使用语句以指向自定义版本,但核心代码是共享的,因此使用此核心核心的其他站点上可能不存在自定义版本

Use 语句显然是文件级别的,所以我猜这是不可能的,但我希望有一些我不知道的东西或者可能有解决方法

示例

核心 Controller

namespace Core;

use Core\Model\Example as ExampleModel;

class ExampleController {

    public function output() {
        $model = new ExampleModel;
        $model->test();
    }

}

核心模型

namespace Core;

class ExampleModel() {

    public function test() {
        echo 'This is the core test';
    }

}

自定义 Controller

namespace Custom;

use Custom\Controller\Example as Base,
    Custom\Model\Example as ExampleModel;

class ExampleController extends Base {

    //Inherits the output() method

}

自定义模型

namespace Custom;

use Core\Model\Example as Base;

class ExampleModel extends Base {

    public function test() {
        echo 'This is the custom test';
    }

}

因此,在这个示例中,我是否可以创建一个自定义 Controller 的实例,它使用自定义模型来输出“这是自定义测试”,而无需修改核心代码?

希望我的问题有意义

谢谢

最佳答案

我不太确定我理解你的问题,但答案应该是不言而喻的:如果你的自定义模型从核心模型扩展,你可以简单地从该自定义类扩展另一个类
如果您正在编写代码,这取决于核心类的子类是否存在,那么该子类将成为您项目的重要组成部分。如果您无法更改核心本身,请将该类添加为依赖项。就这么简单。

添加第二层继承不必让您担心,这样做是很常见的。像这样的事情是完全可以预测的,而且可靠:

namespace Core;
class Model
{
    public function coreTest()
    {
        return 'from the core';
    }
}
namespace Custom;
use Core\Model;
class CustomModel extends Model
{
    public function customTest()
    {
        return 'from the custom model';
    }
}
//finally
namespace Project;
use Custom\CustomModel;
class ProjectModel extends CustomModel
{
    public function test()
    {
        return array(
            $this->coreTest(),
            $this->customTest(),
            'From the project'
        );
    }
}
$test = new ProjectModel();
echo implode(PHP_EOL, $test->test());

但是,如果您希望给定的类从另一个类扩展,则根据该类是否存在,您需要条件导入
简单的 use 语句在编译时进行评估,因此您无法使用 if 检查来在扩展的类之间进行切换。

然而,有一个棘手的解决方法,但我不会依赖它。检查给定的类是否存在(不自动加载),并为存在的类设置别名。

if (!class_exists('\\Custom\\Model', false))
    class_alias('\\Core\\Model', 'Base');
else
    class_alias('\\Custom\\Model', 'Base');
class CustomModel extends Base
{}

但说实话:不要走这条路。当然,您的代码可以工作,但是如果您随后依赖于自定义类中定义的可用方法,但缺少该类,那么您的代码将失败......可怕的。

有关条件导入的详细信息:

Why use class alisases?

关于PHP 命名空间覆盖 Use 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24630152/

相关文章:

php - 带php的Haversine公式

java - 来自父类(super class)和子类的继承 getter

javascript - Backbone.js:结合多个模型的复杂 View

javascript - MVC 模式中 Ajax 中 GET/POST/PUT/DELETE 之间的区别

javascript - 具有 javascript 背景的 angularJS 思考

php - 在 PHP 和 MySQL 中处理时区?

php - php如何获取所有更新日期小于30天的记录

php - 如何从脚本发送订单确认电子邮件

java - Java中父类(super class)引用无法调用子类方法

c++ - 不同类中的枚举不兼容?