Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use wrapper classes like in JAVA, when type hinting [duplicate]

In php-s type hinting, I cannot use scalar types, like integer, or string. So this is invalid:

function myFunc(int $num) {
    //...
}

Is it possible to use wrapper classes, like in JAVA? Integer, String, Boolean, etc...

I would like to use it like this:

function myFunc(Integer $num) {
    //...
}

myFunc(5);     // ok
myFunc("foo"); // error

I know, there are no wrapper classes in php by default. But how is it possible, to write one?

like image 704
Iter Ator Avatar asked Nov 17 '14 11:11

Iter Ator


People also ask

Which is better primitive or wrapper class in Java?

Verdict. Generally, choose primitive types over wrapper classes unless using a wrapper class is necessary. Primitive Types will never be slower than Wrapper Objects, however Wrapper Objects have the advantage of being able to be null.

Why should we use wrapper class in Java?

Wrapper Class will convert primitive data types into objects. The objects are necessary if we wish to modify the arguments passed into the method (because primitive types are passed by value). The classes in java. util package handles only objects and hence wrapper classes help in this case also.

What is the wrapper class for double?

For every primitive type in Java, there is a built-in object type called a wrapper class. For example, the wrapper class for int is called Integer; for double it is called Double.

Is double A wrapper class in Java?

Summary. The Integer class and Double class are wrapper classes that create objects from primitive types. The following Integer methods and constructors, including what they do and when they are used, are part of the Java Quick Reference.


2 Answers

Since PHP 5, PHP allows type hinting using classes (forcing a function/method's parameter to be an instance of a classs).

So you can create an int class that takes a PHP integer in constructor (or parsing an integer if you allow a string containing an integer, such as in the example below), and expect it in a function's parameter.

The int class

<?php

class int
{

   protected $value;

   public function __construct($value)
   {
      if (!preg_match("/^(0|[-]?[1-9][0-9])*$/", "$value"))
      {
         throw new \Exception("{$value} is not a valid integer.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return '' . $this->value;
   }

}

Demo

$test = new int(42);
myFunc($test);

function myFunc(int $a) {
  echo "The number is: $a\n";
}

Result

KolyMac:test ninsuo$ php types.php 
The number is: 42
KolyMac:test ninsuo$ 

But you should be careful about side effects.

Your int instance will evaluate to true if you're using it inside an expression (such as, $test + 1), instead of 42 in our case. You should use the "$test" + 1 expression to get 43, as the __toString is only called when trying to cast your object to a string.

Note: you don't need to wrap the array type, as you can natively type-hint it on function/method's parameters.

The float class

<?php

class float
{

   protected $value;

   public function __construct($value)
   {
      if (!preg_match("/^(0|[-]?[1-9][0-9]*[\.]?[0-9]*)$/", "$value"))
      {
         throw new \Exception("{$value} is not a valid floating number.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return $this->value;
   }

}

The string class

<?php

class string
{

   protected $value;

   public function __construct($value)
   {
      if (is_array($value) || is_resource($value) || (is_object($value) && (!method_exists($value, '__toString'))))
      {
         throw new \Exception("{$value} is not a valid string or can't be converted to string.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return $this->value;
   }

}

The bool class

class bool
{

   protected $value;

   public function __construct($value)
   {
      if (!strcasecmp('true', $value) && !strcasecmp('false', $value) 
          && !in_array($value, array(0, 1, false, true)))
      {
         throw new \Exception("{$value} is not a valid boolean.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return $this->value;
   }

}

The object class

class object
{

   protected $value;

   public function __construct($value)
   {
      if (!is_object($value))
      {
         throw new \Exception("{$value} is not a valid object.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return $this->value; // your object itself should implement __tostring`
   }

}
like image 182
Alain Tiemblo Avatar answered Oct 23 '22 15:10

Alain Tiemblo


There are no wrapper classes for primitive values, no. I guess you could manually check the type:

function myFunc($num) {
    if( !is_int($num) ) {
        throw new Exception('First parameter must be a number');
    }
    // ...
}

It wouldn't be true type hinting, though.

The best way would probably be documenting your code well and hoping it is used correctly.

/**
 * @param int $num
 */
function myFunc($num) {
    // ...
}
like image 23
TiiJ7 Avatar answered Oct 23 '22 17:10

TiiJ7