Question

My current way:

class A {
    public function function_b($myint) {
        if (!is_numeric($myint)) return false;

        // code ...
    }
}

I would like to abandon the function is_numeric() like this:

public function function_b(Integer $myint) {
    // code ...
}

It works with arrays like this:

public function function_c(Array $arr) {
    // only executes following code if $arr is an array / instance of Array!
}

Note: the function has to return false if the value isn't a number (int)! I don't want to cast it.

How would you short my current code? Thanks in advance!

Was it helpful?

Solution

You can't force strict types in function prototypes in PHP inherently, because it's not a strictly typed language. PHP is a weakly typed language and trying to go against the grain will only hurt you in many situations. Also, is_numeric does not guarantee that your value is of type int (for what it's worth).

What you can do is analyze your need for why you think this approach is necessary in the first place and decide on how to best implement this without creating potential for bugs.

For example, take the following scenario where what your method expects is an ID for a database query.

class MyClass {
    public function getUser($id) {
        if (!is_int($id)) {
            throw new Exception("Invalid argument supplied. Expecting (int), but argument is of type (" . gettype($id) . ").");
        }
        // Otherwise continue
        $db = new PDO($dsn);
        $stmt = $db->prepare("SELECT username FROM users WHERE user_id = ?");
        $stmt->execute(array($id));
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return $result;
    }
}

$MyObject = new MyClass;
$result = $MyObject->getUser($_POST['id']);
/* The problem here is $_POST will always be of type string. */

What this should tell you is that it makes no sense to force type checking here since PHP will have done the right thing for you had you just let it alone.

The question you need to be asking yourself is not "How do I force strict typing?", but rather "Why would I need to force strict typing at all?".

OTHER TIPS

You should look into typecasting:

Just use (int) when accessing the value to typecast it to an integer.

You could just typecast it:

public function function_b($myint) {
    $myint = (int) $myint;
}

Or better yet add a public setter to class A which will do it for you every time you set the value:

class A
{
    public function setMyInt($myInt)
    {
        $this->myInt = (int) $myInt;
    }
}

-- Update (based on comment) --

class A
{
    public function doSomethingWithAnArray(array $array)
    {
        ....
    }
}

Notice the keyword array in the signature of the doSomethingWithAnArray method, now if you don't pass an array to this function PHP will throw a fatal error and cease code execution. This is known as typehinting, and can be applied to objects as well.

function needsInteger($int) {
    if (((int) $int) != $int) return false;
    // ...
}

The advantage here is that you can still accept loosely typed parameters, but the non-strict equality check against the cast value will yield an acceptable result.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top