PHP 从子类工厂方法调用超类工厂方法

发布于 12-22 08:59 字数 965 浏览 6 评论 0原文

我正在编写一个带有子类的 php 应用程序,因为我想要有多种方法来创建对象,所以我正在执行不同的工厂方法而不是多个构造函数。

我有一个带有工厂方法的 User

User::from_id
User::from_netid

我有几个 User 的子类。我之前调用的是父超级构造函数,但是当我切换到工厂方法时,构造函数不存在。

我有 Student,它是 User 的子类。为了让它工作,我必须将 User::from_id 中的几乎所有超类工厂代码复制到 load_by_id,因为在这种情况下实例已经存在:

// In Student.php - Student extends User
public static function from_id_and_course($id, $course){
    $instance = new self();
    $instance->load_by_id($id);
    $instance->course = $course;
    ...
}

我想要以子类调用超类工厂方法为起点,然后继续添加其他字段。像这样的东西......

$instance = User::from_id($id);

或者

$instance = Student::from_id($id);

但在这些情况下它给了我一个 User 对象,而我需要一个 Student 对象。我实现此目的的唯一方法是执行 $instance = new self()

如何从子类调用超类工厂方法作为起点来创建新的子类工厂方法?

I am writing a php app with subclasses and since I want to have multiple ways to create an object I am doing different factory methods instead of multiple constructors.

I have a User with factory methods

User::from_id
User::from_netid

I have several subclasses of User. I was previously calling the parent superconstructor, but when I switched to the factory method that constructor didn't exist.

I have Student, a subclass of User. To get it to work, I had to duplicate almost all of my superclass factory code in User::from_id to load_by_id, since in this situation the instance already existed:

// In Student.php - Student extends User
public static function from_id_and_course($id, $course){
    $instance = new self();
    $instance->load_by_id($id);
    $instance->course = $course;
    ...
}

I want to call the superclass factory method from the subclass as a starting point, and then continue to add the other fields. Something like this...

$instance = User::from_id($id);

or

$instance = Student::from_id($id);

but in these cases it gives me a User object, and I need a Student object. The only way I could accomplish this is by doing $instance = new self().

How can I call the superclass factory method from the subclass as a starting point to create a new subclass factory method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梅窗月明清似水2024-12-29 08:59:54

您的问题是这样的:

$instance = new self();

self 指的是定义该方法的类,而不是调用者:

  • 当调用 Student::from_id() 时,如果它不存在,它会回退到 User::from_id()
  • User::from_id() 中,self 指的是 User,而不是 Student

您必须使用 late-static 绑定

$instance = new static();

但是,就像我一直做的那样,我强烈建议不要这么做。使用对象作用域比使用静态作用域更好。扩展、伪造或模拟以及顺便测试也更容易。

没有什么问题:

$user = new User;
$user->from_id($id);

$student = new Student;
$student->from_id($id);

……实际上更好。

Your problem is this:

$instance = new self();

self refers to the class where the method is defined, not the caller:

  • When Student::from_id() is called, if it doesn't exist, it falls back to User::from_id().
  • In User::from_id(), self refers to User, not Student.

You'd have to use late-static bindings:

$instance = new static();

However, like I always do, I'd highly recommend against it. You're better off using the object scope than the static scope. It's easier to extend, to fake or mock and incidentally, to test.

There's nothing wrong with:

$user = new User;
$user->from_id($id);

$student = new Student;
$student->from_id($id);

...it's actually better.

拥抱影子2024-12-29 08:59:54

如果您使用 PHP 5.3 或更高版本,则可以使用 后期静态绑定

class User
{
  public static function from_id($id)
  {
    // factory
    $object = new static();

    // setup

    // return
    return $object;
  }
}

class Student extends User { }

$student = Student::from_id($id); // $student should be of class Student

注意 - 您最好为模拟/测试/健全性设置整个工厂类......

If you're using PHP 5.3 or higher, you could use the Late Static Bindings that are now available:

class User
{
  public static function from_id($id)
  {
    // factory
    $object = new static();

    // setup

    // return
    return $object;
  }
}

class Student extends User { }

$student = Student::from_id($id); // $student should be of class Student

Note - you're probably better off setting up a whole factory class for mocking/testing/sanity...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文