PHP关键字Self、Static和parent的区别详解 |
简介在使用PHP代码时,您可能经常会遇到parent::、static::和self:: 。但是当你第一次作为一个开发人员开始的时候,有时候你会很困惑,不知道它们是做什么的,以及它们之间的区别 。 在我第一次作为开发人员开始工作后的很长一段时间里,我认为static::和self::是完全一样的 。 parent::是什么?假设我们有一个BaseTestCase类,它有一个setUp方法: class BaseTestCase { public function setUp(): void { echo 'Run base test case set up here...'; } } (new BaseTestCase())->setUp(); // Output is: "Run base test case set up here...'; 正如我们所看到的,当我们调用 setUp 方法时,它按预期运行并输出文本 。 现在,让我们假设我们想要创建一个新的 class FeatureTest extends BaseTestCase { // } (new FeatureTest())->setUp(); // Output is: "Run base test case set up here..."; 正如我们所看到的,我们没有在FeatureTest中定义setUp方法,所以在BaseTestCase中定义的方法将被运行 。 现在,假设我们想在运行FeatureTest中的setUp方法时运行一些额外的逻辑 。例如,如果这些类是作为PhpUnit测试的一部分使用的测试用例,那么我们可能需要在数据库中创建模型或设置测试值 。 一开始,你可能(错误地)认为你可以在你的FeatureTest方法中定义setUp方法,然后调用$this->setUp() 。老实说,当我第一次学习编程的时候,我总是陷入这个陷阱! 所以我们的代码可能看起来像这样: class FeatureTest extends BaseTestCase { public function setUp(): void { $this->setUp(); echo 'Run extra feature test set up here...'; } } (new FeatureTest())->setUp(); 但是,您会发现,如果我们运行这段代码,我们最终会陷入一个循环,导致您的应用程序崩溃 。这是因为我们递归地要求 Fatal error: Out of memory (allocated 31457280 bytes) (tried to allocate 262144 bytes) in /in/1MXtt on line 15 mmap() failed: [12] Cannot allocate memory mmap() failed: [12] Cannot allocate memory Process exited with code 255. 因此,我们需要告诉PHP在 class FeatureTest extends BaseTestCase { public function setUp(): void { parent::setUp(); echo 'Run extra feature test set up here...'; } } (new FeatureTest())->setUp(); // Output is: "Run base test case set up here... Run extra feature test set up here..."; 现在,正如你所看到的,当我们在FeatureTest类中运行setUp方法时,我们首先运行BaseTestCase中的代码,然后继续运行子类中定义的其余代码 。 值得注意的是,您并不总是需要将parent::调用放在方法的顶部 。实际上,您可以将其放置在方法中任何最适合代码目的的位置 。例如,如果你想先在FeatureTest类中运行你的代码,然后在BaseTestCase类中运行,你可以像这样将parent::setUp()调用移动到方法的底部: self::是什么?假设我们有一个 这两个类可能看起来像这样: class Model { public static string $connection = 'mysql'; public function makeConnection(): void { echo 'Making connection to: '.self::$connection; } } class User extends Model { public static string $connection = 'postgres'; } 现在让我们在两个类上运行 (new Model())->makeConnection(); // Output is: "Making connection to mysql" (new User())->makeConnection(); // Output is: "Making connection to mysql"; 正如我们所看到的,这两个调用都导致了Model类的connection属性被使用 。这是因为self使用了在方法所在的类上定义的属性 。在这两种情况下,makeConnection方法在Model类上是打开的,因为User类上不存在一个方法 。 为了进一步说明这一点,我们将向User类添加makeConnection方法,如下所示: class Model { public static string $connection = 'mysql'; public function makeConnection(): void { echo 'Making connection to: '.self::$connection; } } class User extends Model { public static string $connection = 'postgres'; public function makeConnection(): void { echo 'Making connection to: '.self::$connection; } } 现在,如果我们再次调用这两个方法,我们会得到以下输出: (new Model())->makeConnection(); // Output is: "Making connection to mysql" (new User())->makeConnection(); // Output is: "Making connection to postgres"; 正如您所看到的,对 static::是什么?现在我们已经知道了 为了更好地理解它的作用,让我们更新上面的代码示例,使用 class Model { public static $connection = 'mysql'; public function makeConnection() { echo 'Making connection to: '.static::$connection; } } class User extends Model { public static $connection = 'postgres'; } 如果我们在两个类上运行 (new Model())->makeConnection(); // Output is: "Making connection to mysql" (new User())->makeConnection(); // Output is: "Making connection to postgres"; 正如我们所看到的,这个输出与我们之前使用
因此,在我们的示例中,使用了 然而,值得注意的是,如果 什么时候使用self::或 static::?现在我们对 这一切都取决于您正在编写的代码的用例 。 一般来说,我通常会使用 例如,假设我想写一个类,我完全打算由子类继承(例如上面示例中的 这意味着我可以有信心,如果我重写任何静态方法或字段,我的子类将使用我的重写 。我无法告诉你有多少次我在代码中遇到了bug,当我在父类中使用 另一方面,一些开发人员可能会争辩说,你应该坚持使用 这意味着如果你遵循这个原则,你就不需要使用 一般来说,最好在编写代码时根据具体情况决定应该使用 以上就是PHP关键字Self、Static和parent的区别详解的详细内容,更多关于PHP关键字Self、Static和parent的资料请关注其它相关文章! |