The other day, while developing my PHP project and implementing the User
class, i started to wonder how this class should interact with the MySQL database the project is using.
前几天,在开发我的PHP项目和实现User类的同时,我开始思考这个类如何与项目使用的MySQL数据库交互。
Let me start with an example: let's say I have a getName()
method, inside the User
class, that returns the user's real name. What's the more fitting way to implement that method?
让我从一个例子开始:假设我在User类中有一个getName()方法,它返回用户的真实姓名。实现这种方法的更合适的方法是什么?
I came up with 2 solutions:
我想出了两个解决方案:
-
I put the DB query inside the
getName()
and only get what I need like this:我将DB查询放入getName()中,只得到我需要的东西:
public function getName() { // MySQL query code here }
-
I create a
load()
method inside theUser
class that load all the user data inside the class structure and then thegetName()
is something like this:我在User类中创建了load()方法,它在类结构中加载所有用户数据,然后getName()是这样的:
private $name; // Load all user data inside the class' structure public function load() { $this->name = // MySQL query here } public function getName() { return $this->name; }
I thought, not sure if mistakenly or not, that the first way is more efficient because i only get the data I need, while the second way is more OOP but less efficient.
我认为,不确定是否错误,第一种方法更有效,因为我只得到我需要的数据,而第二种方法是更多的OOP,但效率较低。
So, here's the question: what is the better way? Why? Are there better ways?
所以,问题是:什么是更好的方法?为什么?有更好的方法吗?
3 个解决方案
#1
1
Either way, consider storing/caching the results of that so you do not make a query every time you use getName on that object. Also, consider not wrrying about all that by using a ORM/DBAL Solution like propel or doctrine.
无论哪种方式,都可以考虑存储/缓存结果,所以每次在该对象上使用getName时,都不会生成查询。另外,考虑使用像推进或教义这样的ORM/DBAL解决方案来解决所有问题。
Also check out Lazy Loading and the Active Record Pattern
还可以检查延迟加载和活动记录模式。
#2
1
Run your query just in time and only run it once (unless you know the value might change), try something like the following:
及时运行您的查询,并且只运行一次(除非您知道值可能会发生变化),尝试如下操作:
class User {
protected $data;
function getName()
{
if (!isset($data['name'])) {
// if you can load more than just $this->data['name'] in one query
// you probably should.
$this->data['name'] = // query here
}
return $this->data['name'];
}
}
#3
0
Aside from the question being kinda broad (as there are countless patterns), the second way you mentioned is better IMO, and to add to it I would also suggest supplying ID as a parameter which you could then use to build a single query to fetch the user by ID and then manually assign all properties (from the fetched row).
除了有点宽泛的问题(如有无数的模式),你提到的第二种方式是更好的国际海事组织,并添加我也建议提供ID作为参数,你可以用来建立一个查询来获取用户的ID,然后手动分配所有属性(从所获取的行)。
#1
1
Either way, consider storing/caching the results of that so you do not make a query every time you use getName on that object. Also, consider not wrrying about all that by using a ORM/DBAL Solution like propel or doctrine.
无论哪种方式,都可以考虑存储/缓存结果,所以每次在该对象上使用getName时,都不会生成查询。另外,考虑使用像推进或教义这样的ORM/DBAL解决方案来解决所有问题。
Also check out Lazy Loading and the Active Record Pattern
还可以检查延迟加载和活动记录模式。
#2
1
Run your query just in time and only run it once (unless you know the value might change), try something like the following:
及时运行您的查询,并且只运行一次(除非您知道值可能会发生变化),尝试如下操作:
class User {
protected $data;
function getName()
{
if (!isset($data['name'])) {
// if you can load more than just $this->data['name'] in one query
// you probably should.
$this->data['name'] = // query here
}
return $this->data['name'];
}
}
#3
0
Aside from the question being kinda broad (as there are countless patterns), the second way you mentioned is better IMO, and to add to it I would also suggest supplying ID as a parameter which you could then use to build a single query to fetch the user by ID and then manually assign all properties (from the fetched row).
除了有点宽泛的问题(如有无数的模式),你提到的第二种方式是更好的国际海事组织,并添加我也建议提供ID作为参数,你可以用来建立一个查询来获取用户的ID,然后手动分配所有属性(从所获取的行)。