Skip to main content
Code Review

Return to Revisions

2 of 5
added 2349 characters in body

OOP, real-world User + related data class design

This is an OOP question and probably answerable even if you don’t have PHP knowledge. (A side note – we are learning PHP OOP and decided to create a github to hopefully help others learn this and other best practices a bit easier, https://github.com/nizamani/PHPBestPractices1-OOP if you are interested. PRs, issues etc are very welcome)

Overview

A simple app with 3 database tables, one a basic users table, the other two containing information about the users' favorite food and favorite restaurant.

Goal/Output

Our current goal (exact question will be listed below) is to create two pages:

Page 1 output:

"Welcome to the app, Jenn"

<?php
namespace PHPBestPractices1OOP\Controller;
use PHPBestPractices1OOP\Request\Request;
use PHPBestPractices1OOP\Response\Response;
use PHPBestPractices1OOP\Domain\User\UserFactory;
class GreetSingleUserPage
{
 /**
 * @var Response
 */
 private $response;
 /**
 * @var Request
 */
 private $request;
 /**
 * @var UserFactory
 */
 private $userFactory;
 /**
 * GreetSingleUserPage constructor.
 * @param Request $request
 * @param Response $response
 * @param UserFactory $userFactory
 */
 public function __construct(
 Request $request,
 Response $response,
 UserFactory $userFactory
 ) {
 $this->response = $response;
 $this->request = $request;
 $this->userFactory = $userFactory;
 }
 public function __invoke()
 {
 // create user object
 $userObject = $this->userFactory->createUser(2);
 // this will display greeting message to the user
 $this->response->setView("greetSingleUser/index.php");
 $this->response->setVars(
 array(
 "name" => $userObject->getName()
 )
 );
 return $this->response;
 }
}

Page 2 output:

"My name is Jenn, age is 28, favorite restaurant is KFC and favorite food is Fried Chicken"

<?php
namespace PHPBestPractices1OOP\Controller;
use PHPBestPractices1OOP\Request\Request;
use PHPBestPractices1OOP\Response\Response;
use PHPBestPractices1OOP\Domain\User\UserFactory;
class DisplayUserInformationPage
{
 /**
 * @var Response
 */
 private $response;
 /**
 * @var Request
 */
 private $request;
 /**
 * @var UserFactory
 */
 private $userFactory;
 /**
 * DisplayUserInformationPage constructor.
 * @param Request $request
 * @param Response $response
 * @param UserFactory $userFactory
 */
 public function __construct(
 Request $request,
 Response $response,
 UserFactory $userFactory
 ) {
 $this->response = $response;
 $this->request = $request;
 $this->userFactory = $userFactory;
 }
 public function __invoke()
 {
 // create user object
 $userObject = $this->userFactory->createUser(2);
 // this will display the user's information
 $this->response->setView("displayUserInformation/index.php");
 $this->response->setVars(
 array(
 "name" => $userObject->getName(),
 "age" => $userObject->getAge(),
 "restaurant" => $userObject->getFavoriteRestaurantName(),
 "food" => $userObject->getFavoriteFoodName()
 )
 );
 return $this->response;
 }
}

Database

In practice these are sql databases, note though if you happen to look at our github we've "faked" this db using php arrays to make the project easier to run and try out

users
id name age favoriteRestaurantId favoriteFoodId
1 Mike 30 1 1
2 Jenn 28 3 3
restaurants
id name averagePrice style
1 McDonalds 1 American
2 Taco Bell 1 Mexican
3 KFC 2 American
foods
id name caloriesPerOunce
1 French Fries 100
2 Hamburger 135
3 Fried Chicken 97

(https://github.com/nizamani/PHPBestPractices1-OOP/blob/master/src/fakedatabase/db.php)

Our Current User class (we also have Restaurant and Food classes)

<?php
namespace PHPBestPractices1OOP\Domain\User;
use PHPBestPractices1OOP\Domain\Food\Food;
use PHPBestPractices1OOP\Domain\Restaurant\Restaurant;
class User
{
 // region vars
 /**
 * @var int
 */
 private $userId;
 /**
 * @var string
 */
 private $name;
 /**
 * @var int
 */
 private $age;
 /**
 * @var Restaurant
 */
 private $favoriteRestaurant;
 /**
 * @var Food
 */
 private $favoriteFood;
 // endregion
 // region set
 /**
 * @param $userId
 */
 public function setId($userId)
 {
 $this->userId = $userId;
 }
 /**
 * @param string $name
 */
 public function setName($name)
 {
 $this->name = $name;
 }
 /**
 * @param int $age
 */
 public function setAge($age)
 {
 $this->age = $age;
 }
 /**
 * @param $favoriteRestaurant
 */
 public function setFavoriteRestaurant(Restaurant $favoriteRestaurant)
 {
 $this->favoriteRestaurant = $favoriteRestaurant;
 }
 /**
 * @param $favoriteFood
 */
 public function setFavoriteFood(Food $favoriteFood)
 {
 $this->favoriteFood = $favoriteFood;
 }
 // endregion
 // region get
 public function getId()
 {
 return $this->userId;
 }
 /**
 * @return string
 */
 public function getName()
 {
 return $this->name;
 }
 /**
 * @return int
 */
 public function getAge()
 {
 return $this->age;
 }
 /**
 * @return Restaurant
 */
 public function getFavoriteRestaurant()
 {
 return $this->favoriteRestaurant;
 }
 /**
 * @return string
 */
 public function getFavoriteRestaurantName()
 {
 return $this->favoriteRestaurant->getName();
 }
 /**
 * @return string
 */
 public function getFavoriteFoodName()
 {
 return $this->favoriteFood->getName();
 }
 /**
 * @return Food
 */
 public function getFavoriteFood()
 {
 return $this->favoriteFood;
 }
 // endregion
}

(https://github.com/nizamani/PHPBestPractices1-OOP/blob/master/src/classes/Domain/User/User.php)

Our Question

Our current user class works fine, but is slower than it could be for Page 1. Page 1 only requires the user's name, Jenn, which is data in the users table. Yet we still have to get data from the restuarants and foods tables in order to create our user object.

We imagine that in the future half of our app's pages only need info from the users table, while the other half of our app's pages need info from all 3 tables. Since we want our app to be fast and responsive, would it be a good idea to have our user class only include things from the users table, and then maybe create another class userDetail which includes the Food and Restaurant objects? On pages that we only need to display basic user table info, we use our user class, and on pages where we need to display info about their favorite food and restaurant we use userDetail class? Or is there some other, better way to do this?

Thanks for taking a look, we appreciate it.

lang-php

AltStyle によって変換されたページ (->オリジナル) /