我对我正在创建的OOP PHP代码有几个疑问。它(到目前为止)用于检索在线存储的不同语言的标题和几个章节。但首先,我将展示代码,因为我的疑问涉及到这一点。这是我目前正在使用的类:
<?php
// Requires PHP 5.4+
class Subject
{
private $DB;
private $Language;
private $Keyword;
public function __construct($DB, $Keyword, $Language)
{
$this->DB=$DB;
$this->Keyword=$Keyword;
$this->Language=$Language;
}
private function query($query, $arg)
{
$STH = $this->DB->prepare($query);
$STH->execute(array_merge((array)$this->Keyword, (array)$arg));
return $STH->fetch()[$this->Language]; // PHP 5.4+
}
public function retrieveTitle ()
{
return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1");
}
public function retrieveChapter ($arg)
{
return $this->query("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1", $arg);
}
?>
然后我做类似的事情来显示页面:
if (isset($_GET['a']))
{
$Subject=new Subject($DB, $_GET['a'], $User->get('language'));
if ($Subject->retrieveTitle())
{
echo '<h1 id="Title">'.$Subject->retrieveTitle().'</h1>';
// Index
if ($Subject->retrieveTitle())
// ... code for the index
// Introduction
if ($Subject->retrieveChapter('Introduction'))
echo '<h2 id="Introduction">' . $_('Introduction') . '</h2>' . $Subject->retrieveChapter('Introduction');
// ... more non-relevant code.
}
}
else
// ... whatever
的第一个问题。我不确定这是否是处理这类数据的正确方法。我尝试分离方法并使它们尽可能小,同时也尝试不重复太多代码。这就是感觉正确的方式。但是我不明白为什么其他代码,类似于前一个,是不可取的。注意:这个类肯定有一些拼写错误,没有经过测试,这里只是为了说明区别,所以请不要使用它(至少不是字面上的):
<?php
// Requires PHP 5.4+
class Subject
{
public $Title;
public $Chapters = array ();
public function __construct($DB, $Keyword, $Language)
{
// Retrieve all
$STH = $DB->prepare("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1");
$STH->execute(array($Keyword));
$this->Title = $STH->fetch()[$Language]; // PHP 5.4+
// Retrieve chapters
$ToForeach = ('Introduction','History','1');
$STH = $DB->prepare("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1");
foreach ($ToForeach as $part)
{
$STH->execute(array($Keyword, $part));
$this->Chapters = $STH->fetch()[$Language];
}
}
}
?>
然后直接访问属性(或者甚至在中间构建一些get(),但是你明白了)。
那么,有什么区别吗?第一个方法与第二个方法编码类的优点和缺点是什么?在第一种情况下,内存使用应该稍微小一点,但我认为在这种情况下,与可读性相比,这不会是一个问题。
编辑:只是用一种别人能理解的方式来写这个问题,这让我从另一个角度来思考。第一种方法看起来也更容易测试。
第二个问题。如果我想做一个/一些方法来保存数据,我应该把它放在同一个类还是在不同的一个?因为如果我把它放在一个类中,它会把所有与主题相关的方法捆绑在一个非常独立的类中,如果我把它分开,我就会有更专门的类和独立的角色。
任何进一步的建议,特别是关于编码最佳实践[我可能没有遵循],也欢迎!
这不是一件容易的事。所以我只能关注其中的一小部分。为了不重复代码,我要说你给出的第一个例子有相当多的重复代码:
class Subject
{
/**
* @var ParametrizedQueryFetchQueryFactory
*/
private $queryFactory;
public function __construct($DB, $Keyword, $Language) {
$this->queryFactory = new ParametrizedQueryFetchQueryFactory($DB, $Language, [$Keyword]);
}
private function query($query, array $args = array()) {
return $this->queryFactory->query($query, $args);
}
public function retrieveTitle() {
return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY DATE DESC LIMIT 1");
}
public function retrieveChapter($part) {
return $this->query(
"SELECT * FROM chapters WHERE subject_keyword = ? AND TYPE = ? ORDER BY DATE DESC LIMIT 1",
[$part]
);
}
}
class ParametrizedQueryFetchQueryFactory
{
private $db, $returnIndex, $defaultArgs;
public function __construct($db, $returnIndex, array $defaultArgs = array()) {
$this->db = $db;
$this->returnIndex = $returnIndex;
$this->defaultArgs = $defaultArgs;
}
public function query($query, array $args = array()) {
$fetcher = new ParametrizedQueryFetch($this->db,$query, $this->returnIndex, $this->defaultArgs);
return $fetcher->execute($args);
}
}
class ParametrizedQueryFetch
{
private $db, $query, $returnIndex, $defaultArgs;
public function __construct($db, $query, $returnIndex, array $defaultArgs = array()) {
$this->db = $db;
$this->query = $query;
$this->returnIndex = $returnIndex;
$this->defaultArgs = $defaultArgs;
}
public function execute(array $args) {
$args = array_merge($this->defaultArgs, $args);
$stmt = $this->db->prepare($this->query);
$stmt->excute($args);
return $stmt->fetch()[$this->returnIndex];
}
}
顺便说一下,要使这个PHP 5.3兼容,您只需要更改这里的一行。