PHP关键字Self、Static和parent的区别详解
在使用PHP代码时您可能经常会遇到parent::、static::和self::。但是当你第一次作为一个开发人员开始的时候有时候你会很困惑不知道它们是做什么的以及它们之间的区别。在我第一次作为开发人员开始工作后的很长一段时间里我认为static::和self::是完全一样的。parent::是什么假设我们有一个BaseTestCase类它有一个setUp方法1234567891011classBaseTestCase{publicfunctionsetUp(): void{echoRun base test case set up here...;}}(newBaseTestCase())-setUp();// Output is: Run base test case set up here...;正如我们所看到的当我们调用 setUp 方法时它按预期运行并输出文本。现在让我们假设我们想要创建一个新的FeatureTest类来继承BaseTestCase类。如果我们想运行FeatureTest类的setUp方法我们可以这样做12345678classFeatureTestextendsBaseTestCase{//}(newFeatureTest())-setUp();// Output is: Run base test case set up here...;正如我们所看到的我们没有在FeatureTest中定义setUp方法所以在BaseTestCase中定义的方法将被运行。现在假设我们想在运行FeatureTest中的setUp方法时运行一些额外的逻辑。例如如果这些类是作为PhpUnit测试的一部分使用的测试用例那么我们可能需要在数据库中创建模型或设置测试值。一开始你可能错误地认为你可以在你的FeatureTest方法中定义setUp方法然后调用$this-setUp()。老实说当我第一次学习编程的时候我总是陷入这个陷阱所以我们的代码可能看起来像这样1234567891011classFeatureTestextendsBaseTestCase{publicfunctionsetUp(): void{$this-setUp();echoRun extra feature test set up here...;}}(newFeatureTest())-setUp();但是您会发现如果我们运行这段代码我们最终会陷入一个循环导致您的应用程序崩溃。这是因为我们递归地要求setUp一遍又一遍地调用它自己。你可能会得到类似这样的输出1234Fatal error: Out of memory (allocated 31457280 bytes) (tried to allocate 262144 bytes) in /in/1MXtt on line 15mmap() failed: [12] Cannot allocate memorymmap() failed: [12] Cannot allocate memoryProcess exited with code 255.因此我们需要告诉PHP在BaseTestCase中使用setUp方法而不是使用$this-setUp()。为了做到这一点我们可以像这样用parent::setUp()替换$this-setUp()12345678910111213classFeatureTestextendsBaseTestCase{publicfunctionsetUp(): void{parent::setUp();echoRun extra feature test set up here...;}}(newFeatureTest())-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::是什么假设我们有一个Model类它有一个静态的connection属性和一个makeConnection方法。我们还可以想象我们有一个User类它继承了Model类并覆盖了connection属性。这两个类可能看起来像这样1234567891011121314classModel{publicstaticstring$connectionmysql;publicfunctionmakeConnection(): void{echoMaking connection to: .self::$connection;}}classUserextendsModel{publicstaticstring$connectionpostgres;}现在让我们在两个类上运行makeConnection方法看看我们会得到什么输出1234567(newModel())-makeConnection();// Output is: Making connection to mysql(newUser())-makeConnection();// Output is: Making connection to mysql;正如我们所看到的这两个调用都导致了Model类的connection属性被使用。这是因为self使用了在方法所在的类上定义的属性。在这两种情况下makeConnection方法在Model类上是打开的因为User类上不存在一个方法。为了进一步说明这一点我们将向User类添加makeConnection方法如下所示12345678910111213141516171819classModel{publicstaticstring$connectionmysql;publicfunctionmakeConnection(): void{echoMaking connection to: .self::$connection;}}classUserextendsModel{publicstaticstring$connectionpostgres;publicfunctionmakeConnection(): void{echoMaking connection to: .self::$connection;}}现在如果我们再次调用这两个方法我们会得到以下输出1234567(newModel())-makeConnection();// Output is: Making connection to mysql(newUser())-makeConnection();// Output is: Making connection to postgres;正如您所看到的对makeConnection的调用现在将使用User类上的connection字段因为这是该方法存在的地方。static::是什么现在我们已经知道了self::的作用让我们来看看static::。为了更好地理解它的作用让我们更新上面的代码示例使用static::而不是self::如下所示1234567891011121314classModel{publicstatic$connectionmysql;publicfunctionmakeConnection(){echoMaking connection to: .static::$connection;}}classUserextendsModel{publicstatic$connectionpostgres;}如果我们在两个类上运行makeConnection方法我们会得到以下输出1234567(newModel())-makeConnection();// Output is: Making connection to mysql(newUser())-makeConnection();// Output is: Making connection to postgres;正如我们所看到的这个输出与我们之前使用self::$connection时不同。对User类上的makeConnection方法的调用使用了User类上的connection属性而不是Model类该方法实际所属的类。这是由于PHP中一个名为“后期静态绑定”的特性。根据PHP文档这个特性被命名为“后期静态绑定”从内部的角度考虑。“后期绑定”来自这样一个事实即static将不会使用定义方法的类来解析而是使用运行时信息来计算。它也被称为“静态绑定”因为它可以用于但不限于静态方法调用。因此在我们的示例中使用了User类上的connection属性因为我们在同一个类上调用了makeConnection方法。然而值得注意的是如果connection属性在User类上不存在它将回退到使用Model类上的属性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2484894.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!