有没有一种方法可以强制PHP在编译时检查构造函数调用?

3

我的大部分最近的经验都是在Java方面,我很惊讶以下PHP代码并没有抛出编译时错误:

<?php
class Test { }
$a = new Test('foo', true, false, 18320);

有没有办法强制使这个成为语法或编译时错误?

3个回答

4

PHP是一种松散类型的动态语言,它允许您在函数或构造函数调用中传递任何集合和任何数量的参数,除非它们的定义中的类型提示没有被传递的参数满足;例如,以下代码就无法正常运行:

class Test {
    public function __construct(array $a, $b, $c, $d) {}
}

// Catchable fatal error: Argument 1 passed to Test::__construct()
// must be an array, string given
$a = new Test('foo', true, false, 18320);

但即使如此,这也不会导致语法错误,而是在运行时发生致命错误。

最接近的方法是在函数或方法体内在运行时强制执行检查。


谢谢!让我困惑的是我没有定义构造函数,所以我希望看到一个“未定义方法的调用”。但是我忘记了默认构造函数。 - Adam Monsen
1
@Adam Monsen:噢,这里又有一个难题:在PHP中没有默认构造函数!如果实例化一个没有任何构造函数的类,那么唯一发生的事情就是内存分配。没有构造函数被调用!更多信息请参见此处:https://dev59.com/I2445IYBdhLWcg3w4-Fe#4650617 - BoltClock
@Adam Monsen:但由于PHP中的对象几乎与JavaScript一样具有动态性和可扩展性,因此您很少会遇到问题。您唯一可能遇到困难的情况就是在那个问题描述的情况下。我只是觉得这个好奇点值得一提 :) - BoltClock
哎呀!没有默认构造函数。我猜编程语言的作者希望即使没有构造函数也可以使用“new”,而松散类型与其他函数/方法有相似的行为。 - Adam Monsen
我想这就是为什么你甚至可以在使用new时省略括号,所以你可以得到类似$a = new Test;的东西。 - BoltClock

1

从记忆中来看,我认为即使在运行时也不会引发警告。相反,提供的参数过少会引发错误,谢天谢地!

然而,有一种方法可以引发错误:编写一个检查参数计数的构造函数。您可以使用func_num_args()func_get_args()来实现这一点。如果您需要多次使用它,可以将其放在父类中并进行扩展,尽管当然这将排除您可能需要的任何其他继承层次结构。

编辑:一个随机的灵感让我搜索“php lint”。猜猜我找到了什么?虽然没有尝试过 :)


1

正如BoltClock所说,你不能...

但是如果你真的想在运行时检查这个,你可以显式地声明一个默认构造函数,不带任何参数,并使用func_num_args来检查有效传递的参数数量,如果适用则引发异常。

class Test
{
    public function __construct()
    {
        if( func_num_args() > 0 )
        {
            /* Error management */
        }
    }
}

+1,因为这很类似于我的帖子,而且你几乎要达到10k了 :) - halfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接