PHP 静态函数与实例函数,基础知识
我正在尝试了解何时应使用静态函数,并且很难找到我的问题的答案。我正在创建一个类User
,它与一个类Group
相关。如果我有一个用户 ID 并且我想从中获取一个用户对象,那么最好是像
$existingUser = User::get($userId);
这样定义类
class User()
{
public static function get($id){
$user = new User();
return $user->findById($id);
}
public function findById($id) {
//find and populate user object
}
}
或
$existingUser=new User();
$existingUser->findById($userId);
这样定义类,
class User()
{
public function findById($id) {
//find and populate user object
}
}
如果我要编写一个返回的函数呢?基于用户 ID 的 Group 对象数组?
class User()
{
//stuff
$groupArray = Group::getAllByUserId($this->getId())
//stuff
}
或
class User()
{
//stuff
$group = new Group();
$groupArray = $group->findAllByUserId($this->getId());
//stuff
}
第二种方法创建一个从未使用过的空组对象。有关系吗? 我是否误解了静态的概念?我知道它对于不必实例化一个类很有用,所以如果该函数无论如何都实例化一个类,那么这是否违背了目的?如果是这样,什么时候使用静态函数的例子是什么?
在这个过于简化的例子中我还应该考虑什么?
I'm trying to learn when static functions should be used, and have had a difficult time finding an answer my questions. I am creating a class User
, which is related to a class Group
. If I have a user id and I want to get a user object from that, is it better to do something like
$existingUser = User::get($userId);
where the class is defined like this
class User()
{
public static function get($id){
$user = new User();
return $user->findById($id);
}
public function findById($id) {
//find and populate user object
}
}
or
$existingUser=new User();
$existingUser->findById($userId);
where the class is defined like this
class User()
{
public function findById($id) {
//find and populate user object
}
}
What about if I were to write a function which returns an array of Group objects based on a user id?
class User()
{
//stuff
$groupArray = Group::getAllByUserId($this->getId())
//stuff
}
or
class User()
{
//stuff
$group = new Group();
$groupArray = $group->findAllByUserId($this->getId());
//stuff
}
The second method creates an empty group object which is never used. Does it matter?
Am I misunderstanding the concept of static? I know it is useful for not having to instantiate a class, so if the function instantiates one anyway, does that kind of defeat the purpose? If so, what would be an example of when a static function would be used?
Anything else I should be considering in this over simplified example?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在上面显示的情况下,您不需要静态函数。
静态函数实际上只是具有名称空间的全局函数。
当需要控制应用程序的全局状态,或者函数的多个副本导致结果不一致时,请使用它们。
回调有时需要是静态的,特别是当它们作为字符串传递时。
You don't need a static function int he case you show above.
Static functions are really just global functions with a namespace.
Use them when the global state of the application needs to be controlled, or if multiple copies of the function lead to inonsistant results.
Callbacks sometimes need to be static, especially if they are passed as a string.
我发现一个好的经验法则是思考“如果我没有[类名],我是否期望能够调用[方法名]?”
如果我没有用户,我是否期望能够调用 findByID?
可能不会。这是我遇到的例外之一; “加载”或“保存”方法有时是静态的。
何时使用非静态方法的一个完美示例是数据库类(其中的大多数方法) - 在尝试对其运行查询之前,您应该始终拥有一个数据库对象。
何时使用静态方法的一个例子是“帮助器”类,本质上是方便函数的集合。假设您有一些方法可以帮助您输出 HTML,您可能有
HTML::image()
、HTML::url()
和HTML::script( )
。在这些上,您不需要 HTML 对象来创建图像、URL 等。至于停止创建对象的多个副本(使用静态方法的一个参数),您应该使用单例模式(Google 一下)来确保对象只存在一个副本。
I find a good rule of thumb is thinking "If I don't have a [class-name], would I expect to be able to call [method-name]?"
If I don't have a user, would I expect to be able to call findByID?
Probably not. This is one of the exceptions I come across; a "load" or a "save" method sometimes makes sense to be static.
A perfect example of when to use non-static methods is (most methods in) a Database class - you should always have a database object before you try to run a query on it.
An example of when to use a static method would be a "helper" class, essentially a collection of handy functions. Say you have some methods that help you output HTML, you might have
HTML::image()
,HTML::url()
andHTML::script()
. On these, you shouldn't need a HTML object to create an image, URL, and so on.As for stopping multiple copies of objects being created (one argument for using static methods), you should use a Singleton pattern instead (Google it) to ensure only one copy of the object ever exists.
您可能应该在 Active Record 与数据映射器上查看这个问题:
https://stackoverflow.com/ questions/2169832/data-mapper-vs-active-record
这个问题的一个要点是,在大多数情况下,类上用于加载/保存的静态方法实际上并不是该类的核心功能。此外,在大多数情况下,存储和加载是一种与类对象分开的抽象概念。
“用户”是数据存储和检索对象吗?在大多数情况下,不,它是您系统中代表的具有各种属性和功能的人。当您开始将该对象的持久性绑定到对象中时,您就破坏了封装并使代码更难维护。如果下周您想要从内存缓存中加载用户怎么办?这与用户是否可以拥有某些属性或功能几乎无关。
You should probably check out this question on Active Record vs data mapper:
https://stackoverflow.com/questions/2169832/data-mapper-vs-active-record
One take from this question is that static methods on the class for loading/saving aren't really the core functionality of the class in most cases. Further, storing and loading is a kind of abstract concept that is separate from your class objects in most cases.
Isa "user" a data storage and retrieval object? In most cases, no, it is a person represented in your system that has various properties and functions. When you start tying the persistence of that object into the object, you break encapsulation and make it harder to maintain the code. What if next week you want to load your users out of memcache? It's hardly relevant to if a user can have some property or functionality.