简体   繁体   English

PHP静态方法与非静态方法/标准函数

[英]PHP static methods vs non-static methods/standard functions

I am working on a web app and writing pure OOP based PHP for the first time. 我正在开发一个Web应用程序,并且是第一次编写基于纯OOP的PHP。 And I have a question about static method VS standard function: 我对静态方法VS标准功能有疑问:

Here is an example scenario: 这是一个示例方案:

class Session
{
    public function start_new_session()
    {
        session_start();
        //other code here like token generator
    }
}

VS VS

class Session
{
    static function start_new_session()
    {
        session_start();
        //other code here like token generator
    }
}

Questions 问题

  1. What is the difference in both? 两者有什么区别?
  2. Which is better for my case? 我的情况哪个更好?
  3. Any application? 有申请吗? (I mean, what are the best scenario to use static method and standard function) (我的意思是,使用静态方法和标准函数的最佳方案是什么)

My Research: 我的研究:

I spent some time to find the answer but don't found relevant answer however I found a lot of debate and useful material. 我花了一些时间找到答案,但是没有找到相关的答案,但是我发现了很多争论和有用的材料。 Believe me it is super hard to decide (Who is right/wrong?) for a beginner like me: 相信我,对于像我这样的初学者而言,很难(谁是对是错)做出决定:

  1. In this question Someone said, It's horrible idea to use cookies in static functions and someone's saying It's a great idea 在这个问题上,有人说: 在静态函数中使用cookie是一个可怕的主意 ,有人说这是一个好主意

  2. And in this question : Everyone is debating on performance and some experts are saying, the static functions execute faster and some saying; 在这个问题上 :每个人都在争论性能,有些专家说,静态函数执行得更快,有些说法; functions are faster. 功能更快。 And result also vary because of different versions of php. 由于不同版本的php,结果也有所不同。

Some useful stat: 一些有用的统计信息:

PHP 5.2 : static methods are ~10-15% faster. PHP 5.2 :静态方法的速度提高了约10-15%。

PHP 5.3 : non-static methods are ~15% faster PHP 5.3 :非静态方法快15%

PHP 5.4 : static methods are ~10-15% faster PHP 5.4 :静态方法快10-15%

PHP 5.5 : static methods are ~20% faster PHP 5.5 :静态方法快20%

To call a non-static method you need to instantiate the class (use the new keyword to create a new instance of the class). 要调用非静态方法,您需要实例化该类(使用new关键字创建该类的新实例)。

When calling a static method you don't have to "new it up" but it won't have direct access to any of the non-static properties or methods. 调用静态方法时,您不必“将其更新”,但是它无法直接访问任何非静态属性或方法。 There are dozens of use-cases / scenarios where you might want to use one over the other. 在许多用例/场景中,您可能想使用其中一个。

To be quite honest it has never even crossed my mind to think about performance of using one over the other. 老实说它甚至从来没有穿过我的脑海想到用一个比其他的性能 If it got to a point where it made that much of a noticeable difference (and all major steps had been taken to increase efficiency) then I would imagine that either the maintenance costs of such a big application would outweigh the need for the increased efficiency or the logic behind the app is fairly flawed to begin with. 如果达到某种程度的显着差异(并且已经采取了所有主要步骤来提高效率),那么我可以想象,无论是这么大的应用程序的维护成本,还是超过了提高效率的需求,还是首先,该应用程序背后的逻辑存在很多缺陷。


Examples for static and non-static 静态和非静态示例

If I was going to use a class for the example in your question then I would use the static version as nothing in the method is reliant on other properties of the class and you then don't have to instantiate it: 如果要在您的问题示例中使用一个类,那么我将使用静态版本,因为该方法中的任何内容都不依赖于该类的其他属性,因此您不必实例化它:

Session::start_new_session()

vs

$session = new Session();

$session->start_new_session();

Also, static properties on a class will remember state that would have otherwise been lost if you were to use a non-static property and instantiation: 同样,类的静态属性将记住状态,否则,如果您使用非静态属性和实例化,该状态将丢失:

class Session
{
    protected static $sessionStarted = false;

    static function start_new_session()
    {
        if (!static::$sessionStarted) {
            session_start();
            static::$sessionStarted = true;
        }
    }
}

Then even if you did: 然后,即使您这样做:

$session = new Session();

$hasStated = $session::sessionStarted;

$hasStarted would still be true . $hasStarted仍然是true

You could even do something like: 您甚至可以执行以下操作:

class Session
{
    protected static $sessionStarted = false;

    public function __construct()
    {
        $this->startIfNotStarted();
    }

    function startIfNotStarted()
    {
        if (!static::$sessionStarted) {

            session_start();

            static::$sessionStarted = true;
        }
    }
}

This way you don't need to worry about starting the session yourself as it will be started when you instantiate the class and it will only happen once. 这样,您无需担心自己启动会话,因为它将在实例化类时启动,并且只发生一次。

This approach wouldn't be suitable if you had something like a Person class though as the data would be different each time and you wouldn't want to use the same data in difference instantiations. 如果您有类似Person类的内容,那么这种方法将不合适,因为每次数据都不同,并且您不想在差异实例化中使用相同的数据。

class Person
{
    protected $firstname;

    protected $lastname;

    public function __construct($firstname, $lastname)
    {
        $this->firstname = $firstname;
        $this->lastname = $lastname;
    }

    public function getFullname()
    {
        return "{$this->firstname} {$this->lastname}";
    }
}

// //

$person1 = new Person('John', 'Smith');
$person2 = new Person('Jane', 'Foster');

$person1->fullname(); // John Smith
$person2->fullname(); // Jane Foster

If you were to use static methods / properties for this class then you could only ever have one person 如果您要为此类使用静态方法/属性,则只能有一个人

class Person
{
    protected static $firstname;

    protected static $lastname;

    static function setName($firstname, $lastname)
    {
        static::$firstname = $firstname;
        static::$lastname = $lastname;
    }

    static function getFullname()
    {
        return static::$firstname . ' ' . static::$lastname;
    }
}

// //

Person::setName('John', 'Smith');
Person::setName('Jane', 'Foster');

Person::getFullname(); //Jane Foster

The debates 辩论

You are probably going to see a lot of debates over which is better and what the best practices are when it comes to PHP (not just about static and not-static methods). 在使用PHP时,您可能会看到很多争论,那就是哪种更好,什么是最佳实践(不仅仅涉及静态和非静态方法)。

I wouldn't get bogged down with it though! 我不会陷入困境! If you find that one side makes more sense to you (and whatever you building at the time) then go with that one. 如果您发现一侧对您(以及您当时建造的任何建筑物)更有意义,则选择另一侧。 Standards and opinions change all the time in this community and half of the stuff that was a problem 5 years ago (or even less) will actually be non-issues today. 在这个社区中,标准和观点一直在变化,而5年前(甚至更少)是一个问题的东西实际上今天已经不再存在。

Take the Laravel framework as an example -- one of the (many) debates is that Facades are bad because they're static and make use of magic methods which is hard to test and debug. Laravel框架为例-(许多)辩论之一是Facades不好,因为它们是静态的,并且使用难以测试和调试的魔术方法。 Facades are actually very easy to test and with the use of stack trace error reporting it isn't hard to debug at all. 外墙实际上非常易于测试,并且通过使用堆栈跟踪错误报告,一点也不难调试。

That being said, if you find the majority of people are saying the same thing and there isn't really a debate for the other side, there is probably a reason eg don't use mysql_ functions or don't run queries inside a loops. 话虽这么说,如果您发现大多数人都在说同样的话,而对于另一侧并没有真正的争论,则可能是有一个原因,例如,不使用mysql_函数或不在循环内运行查询。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM