我正在尝试从我的页面生成时间(最多0.9秒!)中减少十分之一秒的宝贵时间!我想知道是否有更有效的方法来加载以下(示例)数据。
想象一下,你有一个描述用户的类,以及一个描述用户写的帖子的类。
要列出特定用户撰写的每篇帖子的各种属性,您可以使用以下代码:
$user = new User( $user_id );
$post_array = $user->get_posts();
User类内部将是以下代码:
function get_posts()
{
$posts_array = array();
$result = mysql_query( "SELECT id FROM posts WHERE author = '" . $this->id . "'" );
while ( $row = mysql_fetch_array( $result ) )
{
$posts_array[] = new Post( $row['id'] );
}
}
我不喜欢这样一个事实:我必须两次点击数据库,一次获取帖子ID,每次我实例化Post类时都会这样。我是否已将自己编入角落?有没有更有效的方法呢?
使用SELECT * FROM posts...
将所有帖子的数据传递给实例化的Post对象然后使用$posts_array[] = new Post( $row );
会不会是不好的做法?
答案 0 :(得分:1)
我没有看到一次执行大查询(即SELECT *
)然后将其传递给post对象,可能是通过特殊方法或静态构造函数(例如Post::createPostFromData()
)。事实上,我认为这被称为Dependency Injection,强烈建议使用它,因为设计模式会发生。
DRY
除非我完全弄错,DRY
原则专门指代代码,即没有几段代码执行相同的操作,或者字面上是相同的代码行,其中0或更小变化,如果你这样做,将它们分解为函数/方法/你有什么。原因很多,但主要集中在维护和调试上 - 如果有任何需要改变,那么使用DRY
只需更改一次。
在这种情况下,没有理由重复代码甚至查询,因为您只是使用预先构建的数据填充对象。但是,如果您想添加允许您按ID获取帖子然后填充对象的代码,那么通过编写代码来填充对象两次就可以完全违反DRY,即使数据来自多个来源也是如此
在这种情况下,我会主张使用纯静态构造函数,以便您可以完全控制实例化的条件,例如:
class Post {
// object properties
protected $post_id;
public $post_name;
// ...
protected function __construct($post_id, $post_data = null) {
if (is_null($post_data)) {
// create $post_data object by fetching $post_id
}
// code to populate the object
}
public static function fromData($data) {
if (!is_array($data)) {
return false;
}
return new self(null, $data);
}
public static function fromId($post_id) {
if (!ctype_digit((string)$post_id)) {
return false;
}
return new self($post_id);
}
}
答案 1 :(得分:1)
欢迎来到不太精彩的对象关系映射世界!
就“OO设计纯度”而言,您现在的工作方式具有直接实施的优势,并可根据需要按需加载来自数据库的相关数据块。 MySQL查询需要时间,但通过网络传输大型结果集也是如此。注意过早优化并了解可以实施的其他策略,以减少可能更有效且更容易实现的页面加载时间。您确定应用程序的这一方面对加载时间有重大影响吗?即使它是,你有没有看过PHP字节码缓存或MySQL查询缓存?
答案 2 :(得分:0)
每次要获取Post时,为什么不使用PostSet使用单个查询返回Posts,而不是运行查询?你可以使它变得懒惰,以便它只在你开始从它获取帖子时运行查询。为方便起见,请查看Zend Framework,特别是Zend_Db和Zend_Db_Table。您不必使用整个框架 - 只需要您需要的类。
答案 3 :(得分:0)
使用INNER JOIN查询怎么样?
$result = mysql_query("SELECT user_table.id, post_table.id, post_table.user_id FROM user_table INNER JOIN post_table ON post_table.user_id = user_table.id WHERE user_table.name = '".$user_name);
**注意:我没有测试过它的“WHERE”部分,但我之前使用过JOIN。这更像是一种理论,而不是一种答案。
用户选择可以建立在您希望的任何列上。
INNER JOIN示例: - http://www.w3schools.com/sql/sql_join_inner.asp