PHP Call Superclass Factory Method from Subclass Factory Method

让人想犯罪 __ 提交于 2021-01-28 14:22:46

问题


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?


回答1:


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.




回答2:


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...



来源:https://stackoverflow.com/questions/8583989/php-call-superclass-factory-method-from-subclass-factory-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!