草庐IT

php - 旧式和新式 PHP 构造函数之间的区别

coder 2024-01-03 原文

谁能告诉我“旧式”对象构造函数与“新式”构造函数有何不同?我正在学习 PHP OOP,我想知道我什么时候阅读旧语法与新语法,并更好地了解 OOP 在 PHP 中随时间发生的变化。

新风格

class aObject
{
    public $name;

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

最佳答案

“旧”构造函数语法指的是 PHP4。 PHP4 的最后一个版本是 2008 年,PHP5 的第一个版本是 2004 年。这是一个旧式类和新式类的例子。

旧的 (PHP4)

<?php

class MyOldClass
{
    var $foo;

    function MyOldClass($foo)
    {
        $this->foo = $foo;
    }

    function notAConstructor()
    {
        /* ... */
    }
}

新(PHP5+)

<?php

class MyNewClass
{
    var $foo;

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

    public function notAConstructor()
    {
        /* ... */
    }
}

您会在这里注意到一些事情。最重要的变化是命名构造函数的规范方式已从 ClassName() 更改为 __construct()。这为所有类构造函数提供了相同的、可预测的名称——这是必要的便利。假设您有一个名为 ParentClass 的类,它有 20 个 child ,每个 child 都有自己的构造函数。如果您想从每个子类调用父构造函数,您可以调用 ParentClass::ParentClass()。如果您想更改 ParentClass 的名称,则必须更改所有 20 个构造函数调用。但是,使用新方法,您只需调用 parent::__construct(),这将始终有效,即使父类的名称发生变化也是如此。

与此更改相关,PHP5 还引入了类析构函数 (__destruct()),当对象被销毁时调用(与构造函数相反)。

另一个关键变化是 PHP5 引入了 method and property visibility它允许对类的方法和属性进行某种“访问控制”。只有标记为 public 的方法和属性才能从类或其子类之外的上下文中访问。以下是这方面的示例:

<?php

class StackOverflow
{
    /* This can be accessed from anywhere.
     *
     * You can access it from outside the class:
     *     $so = new StackOverflow();
     *     $so->publicProperty = 10;
     *     echo $so->publicProperty;
     * 
     * Or from inside the class:
     *     $this->publicProperty = 5;
     *     echo $this->publicProperty;
     */
    public $publicProperty = 1;

    /* This can be accessed only from methods inside this class.
     *
     *     $this->privateProperty = 5;
     *     echo $this->privateProperty;
     * 
     * You cannot access it from outside the class, as above.
     * Private properties cannot be accessed from child classes,
     * either.
     */
    private $privateProperty = 2;

    /* This can be accessed only from methods inside this class,
     * OR a child-class.
     *
     *     $this->protectedProperty = 5;
     *     echo $this->protectedProperty;
     * 
     * You cannot access it from outside the class, as with public.
     * You can, however, access it from a child class. 
     */
    protected $protectedProperty = 3;
}

现在,方法的工作方式完全相同。您可以将类中的函数(方法)标记为 publicprivateprotected。在 PHP4 中,所有类成员都是隐式的 public。类似地,构造函数 (__construct()) 也可以是publicprivateprotected!

如果一个类不包含public构造函数,它不能被类外的代码实例化(或者,它的子类,对于protected)。那么你将如何使用这样的类呢?嗯,static methods ,当然:

<?php

class ClassWithPrivateConstructor
{
    private $foo;

    private function __construct($foo)
    {
        $this->foo = $foo;
    }

    public static function fromBar($bar)
    {
        $foo = do_something_to($bar);

        return new self($foo);
    }
}

要从其他地方实例化此类,您需要调用:

$obj = ClassWithPrivateConstructor::fromBar($bar);

当您需要在调用构造函数之前预处理输入,或者当您需要多个采用不同参数的构造函数时,这会很有用。

这个方法名,__construct(),以及其他以__开头的方法名,比如__get()__set (), __call(), __isset(), __unset(), __toString()等称为 magic methods .

PHP5带来了很多dramatic changes , 但主要是为了保持与 PHP4 代码的兼容性,因此仍然允许使用旧式构造函数。

PHP7 现已于今年发布,构造函数语法没有任何变化。 PHP7 中与 class 相关的唯一重大变化是允许使用匿名类(参见 here)。

从 PHP7 开始,旧式构造函数 are officially deprecated (引发 E_DEPRECATED 错误),并将在 PHP8 中完全删除。

关于php - 旧式和新式 PHP 构造函数之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34565713/

有关php - 旧式和新式 PHP 构造函数之间的区别的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  4. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  7. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  8. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  9. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐