1

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!

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
Mr. B.
  • 8,041
  • 14
  • 67
  • 117

4 Answers4

3

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?".

Sherif
  • 11,786
  • 3
  • 32
  • 57
  • Your example shows my scenario 1:1! Unfortunately it seems that I'm not able to abandon is_int() or is_numeric(). – Mr. B. Dec 07 '12 at 02:05
  • Why's that? You need to explain your use case otherwise I can only guess what you're trying to do. In my experience there's is no need to force type checking in PHP. In this scenario if I never check for the type there would still be absolutely nothing wrong with the code and it will work as I expect it to whether the type of value is string, int, or anything else. The code will do the right thing. – Sherif Dec 07 '12 at 02:14
  • Optional strict typing for scalars has now been added to PHP 7. – OCDev Feb 10 '16 at 11:50
2

You should look into typecasting:

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

kittycat
  • 14,983
  • 9
  • 55
  • 80
  • 1
    Thanks for your reply! Typecasting isn't what I need, I explained my problem the answer below. – Mr. B. Dec 07 '12 at 01:43
2

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.

Mike Purcell
  • 19,847
  • 10
  • 52
  • 89
  • Thanks for your reply. I know about casting, but I think I forgot to mention that my method has to return false when the value isn't an integer. function(Array $myarr = array()) if $myarr is not an array or a instance of Array. I hope you know what I mean. Thanks! :) – Mr. B. Dec 07 '12 at 01:42
  • 1
    You didn't mention anything about arrays, you can typehint arrays. Updated post. – Mike Purcell Dec 07 '12 at 01:48
  • Sorry, I forgot a few words in my last answer - too much coffee, too less sleep. I updated the post. Thanks and sorry again! – Mr. B. Dec 07 '12 at 02:11
1
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.

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174