Returning NULL with return type declarations

Compizfox

I was refactoring a codebase for use with PHP7, particularly implementing scalar type hints and return type hints, when I encountered an problem.

I have a class with some properties, one of which an id. This id is not mandatory (you can construct an object without setting the id). When creating a new object of this class you don't set the id, and it gets an id as soon as it is inserted into the db (by a separate mapper class).

This mapper class needs to check if the object already exists in the db, and it does this by checking if the id is set:

if(empty($exampleObject->getId())) {
    // Insert object
} else {
    // Update object
}

I was applying return type hints to every function in my codebase, and the problem is that the function getId() can't return NULL if I enforce an int return type. It TypeErrors, even without having strict typing enabled:

Fatal error: Uncaught TypeError: Return value of ExampleClass::getId() must be of the type integer, null returned

I considered not setting a return type hint for this getter, but I then realised the problem is probably not the return type hinting, but the fact that I'm using mixed return types. I remember reading somewhere that using mixed return types is a bad thing, but I'm not sure how to tackle this without using mixed return types. I could:

  • Throw an exception in the getter, and design the check in the mapper class so that it catches that exception.
  • Catch the TypeError exception, and use that to indicate the id is not set.
  • Make the id property public, so I can call isset directly on that.
  • Add a different method hasId() return isset($this->id)

Frankly, don't really like any of these solutions, and I was wondering if there's a better option. What's the best practise for cases like this?

Also, shouldn't I only get a TypeError if I have strict typing enabled? I thought PHP7 defaulted to "weak type hints".

Andrea

PHP 7.1 added nullable types, where you put a question mark before the type name to mark the return type as accepting both that type and null:

public function getId(): ?int {
    /* … */
}

If you're still on PHP 7.0, I suggest omitting the type declaration and using a docblock.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Why is returning None when of return type option<T> not return the null pointer when T is not a reference

Conditional argument and return type declarations (aka type hinting)

Returning Null Value for Unknown Type

Rules for implicit int return type in ANSI C function declarations

Missing function's return type declaration - do declarations increate efficiency

Returning null in a function that should return an integer

ProfileBase Create method return returning null

Conditional return with Promises: throwing vs returning null

Implementing a "virtual" method returning *this (covariant return type)

Function not returning table despite it being the return type

returning int array when return type is int *

Return type for stored procedure returning ints

Type No return, in function returning non-void

return type for getter problem when returning enum

C++ Implicitly returning return type variable

Returning String array in a function with void return type

Return type of a function returning a lambda function

Returning null for generic type extension in c#

C# Generic Interface Type returning Null

Method return type with null in typescript

Return "null" on primitive return type function?

Typescript function return type null if parameter null

What is the type of an auto return type when returning *this in an anonymous class?

What is the type of an 'auto' return type when returning *this in an anonymous class?

App returning type optional -- needs to return type string

Type T = Type.GetType(TypeName); T is returning Null

Typescript duplicated type declarations

Is there a way to extend type declarations?

Do the following two declarations involving automatic return type work the same? If so, why?