6

i am wondering is it possible to restrict php variable to accept only certain type of variable it is defined to accept.

e-g if we see in C#

public int variable = 20;
public string variable2 = "Hello World";

so what would it be like in php if i want to restrict type for variable.

public int $variable = 20;

so that if i try to assign string to integer variable i get the error.

public int $varaible = "Hello World"; //As type is integer, it should throw error.

is there such thing defining types in PHP for variables before assigning values to it??

2
  • 7
    The answer is a simple "no".... PHP is a loosely-typed language, which means that you can't restrict that typing Commented Dec 31, 2014 at 13:10
  • 1
    You can only do that using Hacklang. docs.hhvm.com/manual/en/hack.annotations.php Commented Dec 31, 2014 at 13:16

3 Answers 3

17

TL;DR Not directly, no. PHP is not strictly-typed. There are, however, a few workarounds that may work for you in the context of function parameters or properties of classes.

Long answer: PHP is not a strictly-typed language, but loosely-typed. You can give a variable any value you want, regardless of how it was initialized. So, you can't simply type something like int $myVar and expect $myVar = "foo"; to throw an error. But PHP does offer a few handy features to get you to the same end when dealing with function parameters or properties of a class.

Option 1: Type hints

You can use a "type hint" for function parameters:

class SomeClass 
{
    /* code here */
}

function foo(SomeClass $data)
{
    /* code here */
}

foo() will only accept parameters of type SomeClass. Passing it, say, an int will throw a fatal error. This doesn't work in PHP < 7 if the parameters are intended to be base types, like int, string, etc., so you can't do function foo(int $data) {...}. That said, there are a few libraries out there that attempt to force it to work at the expense of a little speed. Also, PHP 7 adds a lot of support for this kind of thing, as does the Hack language based on PHP.

Pros:

  • Easy
  • Intuitive

Cons:

  • Only works for program-defined classes
  • Unavailable for base types

Option 2: Getters and Setters

You can also use getters and setters, like so:

class SomeClass 
{
    private $foo = 0;

    function setFoo($val = 0)
    {
        // force it to be an int
        if (is_integer($val) {
            $this->foo = $val;
        } else {
            // throw an error, raise an exception, or otherwise respond
        }
    }
}

Pros:

  • Relatively easy
  • Relatively intuitive

Cons:

  • Only works in program-defined classes
  • Unavailable for base types
  • Requires lots of code

Option 3: Magic Methods

This method is my favorite, but also the most complicated. Use the __set() magic method to deal with class properties.

class MyClass {
    private $type = 0; // we will force this to be an int
    private $string = ''; // we will force this to be a string
    private $arr = array(); // we will force this to be an array
    private $percent = 0; // we will force this to be a float in the range 0..100
    
    function __set($name, $value) {
        switch ($name) {
            case "type":
                $valid = is_integer($value);
                break;
            case "string":
                $valid = is_string($value);
                break;
            case "arr":
                $valid = is_array($value);
                break;
            case "percent":
                $valid = is_float($value) && $value >= 0 && $value <= 100;
                break;
            default:
                $valid = true; // allow all other attempts to set values (or make this false to deny them)
        }
        
        if ($valid) {
            $this->{$name} = $value;

            // just for demonstration
            echo "pass: Set \$this->$name = ";
            var_dump($value);
        } else {
            // throw an error, raise an exception, or otherwise respond

            // just for demonstration
            echo "FAIL: Cannot set \$this->$name = ";
            var_dump($value);
        }
    }
}

$myObject = new MyClass();
$myObject->type = 1; // okay
$myObject->type = "123"; // fail
$myObject->string = 1; // fail
$myObject->string = "123"; // okay
$myObject->arr = 1; // fail
$myObject->arr = "123"; // fail
$myObject->arr = array("123"); // okay
$myObject->percent = 25.6; // okay
$myObject->percent = "123"; // fail
$myObject->percent = array("123"); // fail
$myObject->percent = 123456; // fail

Pros:

  • Relatively easy
  • Intuitive
  • Extremely powerful: one setter to rule them all

Cons:

  • Only works in program-defined classes
  • Unavailable for base types
  • Requires lots of switching or if/else logic
  • Can cause problems with IDEs not auto-completing property types correctly

Here's a demo of this approach.

Closing Thoughts

Finally, if you're using an IDE like PHPStorm, don't forget about PHPDoc type hints:

/* @var integer */
$foo = 0; // will result in warnings if the IDE is configured properly and you try to do something like substr($foo, 1, 4);

And if you really want to go hard core, you can do strong typing using Hack, at the expense of making your code less portable and less compatible (for now) with major IDEs.

Of course, none of these is a substitute for explicitly validating user input and thoroughly testing the application's response to unexpected input types.

Sign up to request clarification or add additional context in comments.

2 Comments

PHPStorm is the IDE for PHP. thanks for mentioning this. +1.
@AyeshK :) No argument; it's the only one I have found useful.
4

No. PHP is not a strictly typed language. You can however use type hints in functions and methods.

If class or interface is specified as type hint then all its children or implementations are allowed too.

Type hints can not be used with scalar types such as int or string. Resources and Traits are not allowed either.

The Scalar types being:

  • string
  • bool
  • int
  • float

Examples:

function (array $theArr) {
  // body
}

class X {
  public function __construct(SomeOtherClass $arg) {
    // body
  }

  public function setFoo(Foo $foo) {

  }
}

See the manual for more specifics: http://php.net/manual/en/language.oop5.typehinting.php

5 Comments

And for int and string ?
Nope, not for int, string bool, float.
I know it, but maybe it should be included in your answer ;)
Worth pointing out the experimental auto-boxing-esque SPL Types Extension?
array (case insensitive) and class names only.
0

You have to made it by your own hands, example :

function setInt(&$var, $value) {
    if(!is_integer($value) {
        throw new Exception("Integer wanted " . gettype($value) . " received");
    }
    $var = $value;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.