我编写PHP代码已经有一段时间了,但最近才表示要掌握OOP方法,我正在努力找出应用程序中某些东西的归属。
我已经编写了下面的代码,它是一个数据映射器,用于处理团队在应用程序中与数据库之间的信息,但我对应该在哪里/如何应用我的业务逻辑/规则感到困惑。
例如,如果调用了teamMapper类中的delete方法,那么只有在该团队没有参与任何匹配的情况下,它才应该继续运行SQL从数据库中删除该团队。在不违反任何OOP规则或使类难以进行单元测试的情况下,我该如何做到这一点?
我已经在谷歌上搜索了很多次,但到目前为止都无济于事,我看到的所有数据映射器都只有delete命令的SQL语句,并且没有关于是否真的可以执行该操作的逻辑。
我想我可以通过构造函数方法将MatchesMapper的实例注入到我的TeamMapper类中,然后继续运行像$this->MatchesMapper->hasMatches($team_id)这样的命令,或者在一个单独的类中有一个静态方法来做同样的事情,但正确的方法是什么?
如有任何帮助,我们将不胜感激,谢谢。
interface TeamMapperInterface
{
public function findById($id);
public function insert(TeamInterface $team);
public function update(TeamInterface $team);
public function delete($id);
public function isTeamByName($name);
}
class TeamMapper implements TeamMapperInterface {
private $db;
public function __construct($db)
{
// Assign the database connection to a variable which can be used throughout the class
$this->db = $db;
}
/**
* Find By Id
*
* This function retrieves a team's information from the database and returns it as an object of "team".
*
* @param $id
* @return null|Team
*/
public function findById($id)
{
// Prepare an SQL statement for attempting to retrieve the team's information from the database
$sql = 'SELECT `id`, `name`, `country`, `league`, `active` FROM `#` WHERE `id` = ? LIMIT 1';
// Execute the SQL statement
$query = $this->db->query($sql, array($id));
// Check to see whether the database query returned a record or not
if(is_object($query) === false || $query->num_rows() == 0)
{
// Return null as either the database query failed or no record could be found for the given id
return null;
}
// If a team was found then attempt to load it into an a new instance of the team class
return $this->loadTeam($query->row_array());
}
/**
* Insert
*
* This function takes a team interface object and inserts it into the database.
*
* @param TeamInterface $team
* @return mixed
* @throws Exception
*/
public function insert(TeamInterface $team)
{
// Verify that all of the variables in the object passed to this function have been set before attempting to insert the data into the database
if(is_null($team->getName()) || is_null($team->getCountry()) || is_null($team->getLeague()) || is_null($team->getActive()))
{
// Throw an exception because a certain event happened
throw new Exception('The team''s information is incomplete and therefore cannot be added to the database.');
}
// Check to see if there is already a team in the database with the given name
if($this->isTeamByName($team->getName()))
{
// Throw an exception because a certain event happened
throw new Exception('The team name specified already exists in the database.');
}
// Prepare an SQL statement for inserting the team's information into the database
$sql = 'INSERT INTO `#` (`id`, `name`, `country`, `league`, `active`) VALUES (?,?,?,?,?)';
// Execute the SQL statement and then return whether it was successful or not
return $this->db->query($sql, array('', $team->getName(), $team->getCountry(), $team->getLeague(), $team->getActive()));
}
/**
* Update
*
* This function takes a team interface object and uses it to update the relevant information on the database.
*
* @param TeamInterface $team
* @return mixed
* @throws Exception
*/
public function update(TeamInterface $team)
{
// Todo!
}
/**
* Delete
*
* This function delete's a team from the database using the id specified.
*
* @param $id
* @return mixed
* @throws Exception
*/
public function delete($id)
{
// Determine if the variable passed to this function was an instance of team interface instead of the expected integer for the id
if($id instanceof TeamInterface)
{
$id = $id->getId();
}
// The team can only be deleted if it doesn't have any matches assigned to it
if(MatchesMapper::numMatchesByTeam($id) > 0)
{
// Throw an exception because a certain event happened
throw new Exception('The team can only be deleted when it doesn''t have any matches assigned to it.');
}
// Prepare an SQL statement for deleting the team's information from the database
$sql = 'DELETE FROM `#` WHERE `id` = ?';
// Execute the SQL statement and then return whether it was successful or not
return $this->db->query($sql, array($id));
}
/**
* Is Team By Name
*
* This function queries the database to determine whether a team exists for a given name
*
* @param $name
* @return bool
*/
public function isTeamByName($name)
{
// Prepare an SQL statement for checking whether a team already exists in the database
$sql = 'SELECT `id` FROM `#` WHERE `name` = ? LIMIT 1';
// Execute the SQL statement
$query = $this->db->query($sql, array($name));
// Return the relevant result depending on whether a team was found or not
return ($query->num_rows() == 1) ? true : false;
}
/**
* Load Team
*
* This function takes an array containing some information about a given team and returns it as an object of "team"
*
* @param array $row
* @return Team
*/
private function loadTeam(array $row)
{
// Create a new object to hold the information for the team
$team = new Team($row['name'], $row['country'], $row['league'], $row['active']);
// Set the team's id as this can't be done through the constructor method of the team class
$team->setId($row['id']);
// Return the new team object
return $team;
}
}
如果存在依赖记录,可以使用InnoDB外键约束来停止删除。特别是限制。
请参阅:http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html