PHP OOP:创建一个新类?
我有三张桌子:PHP OOP:创建一个新类?,php,oop,Php,Oop,我有三张桌子: users: id first_name last_name courses: id name student_courses: id student_id course_id paid 用户跟踪用户,课程跟踪课程,student_课程是显示学生注册了哪些课程的表格。我目前有一个“用户”类和一个“课程”类。我的问题是:我是否应该创建一个StudentCourses类来处理student_courses表的交互 ie:我需要创建一个函数,获取用户注册的所有课程,将它们标记为付
users:
id
first_name
last_name
courses:
id
name
student_courses:
id
student_id
course_id
paid
用户跟踪用户,课程跟踪课程,student_课程是显示学生注册了哪些课程的表格。我目前有一个“用户”类和一个“课程”类。我的问题是:我是否应该创建一个StudentCourses类来处理student_courses表的交互
ie:我需要创建一个函数,获取用户注册的所有课程,将它们标记为付费课程,等等
最好是:
$student = new User($userId);
$student->getCourses();
$student->markCourseAsPaid($courseId);
或
等等。我不会创建单独的类。我的方法是使用如下内容:
$student = new User($userId);
$course = new Course($courseId);
$student->markCourseAsPaid($course);
由于student\u courses
表只是一种关系,因此不应该有额外的类。一个额外的类意味着它是一个实体,它不是,它是一种关系
我的代码与您的不同,因为我首先获取适当的课程
实例,然后将该实例传递给用户。在我看来,只传递课程的ID是很奇怪的,因为用户
对象只接收一个数字作为参数,这根本没有意义。当然,我们可能不需要ID(主键),而是一个辅助键。然后这个方法就没有用了,因为它需要的是PK,而不是一些SK。因为我选择先获取Course
对象,所以我们没有这个问题,因为Course对象知道如何通过辅助键检索正确的课程
编辑:由于这是一种对象化的关系,因此使用额外的类可能有一定的意义。但我会用另一种方法:
$studentCourse = new StudentCourse($studentId, $courseId);
$studentCourse->markPaid();
由于student ID和course ID都构成了表的次键,因此它们都应该在构造函数中指定。在这种情况下,两者都可以工作
通常,您会在MVC(模型-视图-控制器)范例中将每个模型/表设置为一个类(即学生、课程、用户等)。然后在每个类中,您可能有一个变量来关联它们。我不认为需要StudentCourses类,即使表结构显示了一种关系,也不需要另一个类。第一个示例在我看来更面向对象。同样,你也可以这样做,但我自己总是选择更多面向对象的代码。如果你将来要扩展应用程序,我会为StudentCourse创建单独的类。现在,除了join attributes(paid)之外,它只有一个附加属性,但当您需要添加其他属性时,您仍将创建该类。我将为
课程学生创建第三个类,该类将依赖于数据库上的表和视图,原因如下:,关注点分离
您的视图用于所有选择和表的插入、更新和删除
您的视图将由两个表的所有相关字段组成(使用2internal join
)(学生和课程),这些字段基于course\u student
表中的关系
一行将如下所示:
student_id, student_first_name, student_last_name, courses_id, courses_name, is_paid
如果你想让所有学生都参加一门课程,你可以使用名为getStudentsByCourse(courseId)
的方法
如果您想获取特定学生的所有课程,可以使用名为getStudentCourses(studentId)
的方法
如果您需要为一门课程(或多门课程)注册一组学生,可以使用名为setStudentsCourses(studentId,courseId)
(其中两个参数都可以是整数或数组。如果您从对象的角度考虑学生课程
和课程
表,您会注意到学生课程
是一个非常有趣的表,因为它包含了学生的各个对象。它们是您想要的ent对象连接到。您现在在courses
中所拥有的只是,例如,它的名称和描述。因此,您的StudentCourse
实例可以简单地聚合它。您只需加载该实例一次,然后跨StudentCourse
实例共享它:
例如,您的markAsPaid
方法应该在上。换句话说,它应该在Course
上。但是,您可以在学生上添加payForCourse
,然后在相应的课程上调用markAsPaid
。您可能希望引入一个充当删除第2行,和$student->markCourseAsPaid($courseId);
是一个更好的选择…不需要为这个命令加载课程信息(包括数据库trip),除非新建课程($courseId);
使用延迟加载(实际上与不创建它相同)@Rudu是的,我正在做这个解释;)我确实希望ORM类足够聪明,在实际请求之前不会加载任何值。我想我明白你的意思。你如何建议学生注册以下课程:$student=新学生($studentId);$course=新课程($courseId);
student_id, student_first_name, student_last_name, courses_id, courses_name, is_paid