Audit required: Use of insecure `eval()` function foundPHP-A1000Syntax errorPHP-E1111Invalid use of `implements` keywordPHP-W1008Call with inconsistent number of parametersPHP-W1025Undefined function call detectedPHP-E1000Exception being raised is not from a valid exception classPHP-E1001Method is called but not definedPHP-E1002Invalid static method call detectedPHP-E1003Missing return statement in method/functionPHP-E1004Invalid use of class method overridingPHP-E1005Invalid typehint detected in arrow functionPHP-T1000Literal array with empty item(s)PHP-W1001Use of an empty `[]` to read from an arrayPHP-W1002Use of deprecated `(unset)` castPHP-W1003Bad class attribute(s)PHP-W1004Invalid usage of class constant fetch expressionPHP-W1006Duplicate declaration foundPHP-W1007Interface doesn't inherit from another interfacePHP-W1009Invalid use of `extends` keywordPHP-W1010Invalid use of `use`PHP-W1011Invalid property promotionPHP-W1013Invalid attribute classPHP-W1015Trait as attribute is not allowedPHP-W1016Function call parameters are inconsistentPHP-W1020`break` / `continue` used outside of a loopPHP-W1027Abstract method found outside of an abstract classPHP-W1030Undefined static properties must not be accessedPHP-W1034Undefined constants must not be usedPHP-W1038Detected use of `@` to suppress errorsPHP-W1078Attribute class cannot target class constantsPHP-W1005Access to an undefined static propertyPHP-E1007Audit required: Presence of debug function foundPHP-A1012Audit required: Use of an insecure cipherPHP-A1007Audit required: Include statements might be vulnerable to injection attacksPHP-A1001Audit required: SQL query might be vulnerable to injection attacksPHP-A1002Audit required: Sensitive cookie without `HttpOnly` attributePHP-A1003Audit required: Use of an insecure hashing functionPHP-A1004Audit required: Sensitive cookie without `secure` attributePHP-A1005Directory created with insecure permissionsPHP-A1006Manual generation of session ID detectedPHP-A1008Audit required: Function may be vulnerable to arbitrary commands executionPHP-A1009Audit required: Entity substitution can be vulnerable to XXE attacksPHP-A1010Found class constants inside a traitPHP-E1113`switch` statement contains multiple `default` casesPHP-E1114Invalid `options` array while creating a cookiePHP-E1116Abstract method has definitionPHP-E1118Use of compute intensive function in loop conditionPHP-P1000Use of duplicate type in Union types detectedPHP-T1005Use of nullable `mixed` is forbiddenPHP-T1006Nested function declaration is discouragedPHP-W1023Invalid typehint detected in functionPHP-W1029`echo` called with an invalid valuePHP-W1041Type casting is not validPHP-W1042`print` called with a value which isn't a `string`PHP-W1044Audit required: Insecure use of loggerPHP-A1011Class constants don't comply with PSR standardsPHP-C1000Invalid use of increment/decrement operatorsPHP-E1006Array contains duplicate keysPHP-W1000Undefined properties must not be accessedPHP-W1033`use` statement has no effectPHP-W1069Dead code found after `return`PHP-W1074Variable assigned to itselfPHP-W1077Parameter with a default value is not lastPHP-W1079Variable is used but not definedPHP-W1066Class method doesn't comply with PSR standardsPHP-C1001Invalid type used inside string literalPHP-W1043Use of deprecated `libxml_disable_entity_loader()`PHP-W1086Visibility should be explicitly declaredPHP-W1088Function comparison is always positivePHP-W1089Useless post increment/decrementPHP-W1090Missing native return type declaration for closure/anonymous functionPHP-T1003Unused private class property foundPHP-W1075Unused private class method foundPHP-W1076Invalid class instantiationPHP-W1012Invalid assignmentPHP-W1032`throw` expression used in PHP < 8.0PHP-W1017Invalid return typehint for functionPHP-T1002Unsafe usage of `new static()`PHP-W1014Invalid arrow functionPHP-W1018Invalid return typehint for closurePHP-T1001Abstract method defined in a non-abstract classPHP-E1115Unused variable in the closure `use`PHP-W1039Unused constructor parameterPHP-W1037Bad argument passed to `isset`PHP-W1040Typed property accessed before initializationPHP-E1008Class used with `instanceof` is not of valid typePHP-E1009`nullsafe` returned by referencePHP-W1019Invalid closure attributePHP-W1021Attribute class can not be used with functionPHP-W1022Attribute class can not be used with parameter/propertyPHP-W1024`nullsafe` expression returned by referencePHP-W1026Attribute class can not be used with methodPHP-W1031Attribute class can not be used with propertyPHP-W1035Useless `unset` callPHP-W1036Inaccessible propertyPHP-W1067Empty function/method foundPHP-W1080Empty block of code foundPHP-W1085Defining case-insensitive constants is deprecatedPHP-W1083Use of nested `switch` statements foundPHP-W1091`match` expression is returning `void`PHP-W1045Unknown magic method detectedPHP-W1081`final` keyword is redundantPHP-W1082Use of deprecated filter constantPHP-W1084`string` casting in concatenation is redundantPHP-W1087Missing class doc commentPHP-D1001Missing function/class method doc commentPHP-D1002Use of `FIXME`/`XXX`/`TODO` encounteredPHP-W1073Class property provided with an invalid typePHP-T1004Unresolvable use statementPHP-W1068`compact()` called with undefined variablesPHP-W1070Invalid regex pattern foundPHP-W1071Invalid symbol in group `use` statementPHP-W1072Consider using `func_num_args`PHP-P1001Function with cyclomatic complexity higher than threshold foundPHP-R1006
PHP logoPHP/
PHP-W1014

Unsafe usage of `new static()`PHP-W1014

Critical severityCritical
Bug Risk categoryBug Risk

This issue is raised for new static() calls that might break once the class is extended and the constructor is overridden with different type parameters.

Extending classes with calls to new static() is error-prone and will likely break your application. Restructure your code to prevent such usage.

Bad practice

class Controller
{
    public function __construct(string $name)
    {
    }

    public function getController()
    {
        return new static('Base');
    }
}

class UserController extends Controller
{
    // constructor method is overridden
    public function __construct(int $i)
    {
    }
}

// valid: will return an instance of "Controller" class
(new Controller('Base'))->getController();

// invalid: will return a Fatal Error: "Argument #1 ($i) must be of type int, string given"
(new UserController(1))->getController();

Make the class final

This is the easiest course of action - if the class does not need to be extended, but is open for inheritance anyway, (perhaps by accident) just make it final. At that point, you can also change new static() to just new self() without breaking functionality.

final class Controller
{
    public function __construct(string $name)
    {
    }

    public function getController()
    {
        return new static('Base');
    }
}

Make the constructor final

If you want the class open for extension, you can disallow overriding the constructor in child classes and make the code safe that way.

final class Controller
{
    final public function __construct(string $name)
    {
    }

    public function getController()
    {
        return new static('Base');
    }
}

Make the constructor abstract

Signatures of abstract constructors are enforced in child classes. The disadvantage of this approach is that the child class must define its own constructor, it cannot inherit the parent one.

class Controller
{
    abstract public function __construct(string $name);

    public function getController()
    {
        return new static('Base');
    }
}

Enforce constructor signature through an interface

Making the constructor abstract can also be achieved by an interface while keeping the implementation in the parent class. The child class doesn’t have to define its own constructor. It'll inherit the parent one, but PHP will enforce the constructor's signature if the child class defines one.

interface ControllerInterface
{
    public function __construct(string $name);
}

class Controller implements ControllerInterface
{
    public function __construct(string $name)
    {
    }

    public function getController()
    {
        return new static('Base');
    }
}

References