Page 1 of 3

Did you know you can do this?

Posted: Wed Jul 26, 2006 11:49 am
by daedalus__

Code: Select all

function PrintString(string $string)
{
    print($string);
}

PrintString(9);
Outputs:

Fatal Error: Arguement 1 passed to PrintString() must be an object of class string, called in __FILE__ on line __LINE__ and defined in __FILE__ on line __LINE__

I had no idea that you could do that in PHP (I don't know what that is called btw), but I did, in PHP5.

It's sweet that PHP can go both ways because I hate having to declare what kind of thingy a variable is most of the time, but sometimes I really wish I could.

I don't remember seeing it in the manual, either.

Posted: Wed Jul 26, 2006 12:06 pm
by MrPotatoes
that's how it is in most languages. i prefer it. but then again i used to like working with memory until i just about forgot ;)

Posted: Wed Jul 26, 2006 12:08 pm
by jamiel
Yes, you can even do this ...

Code: Select all

class ClassA
{
    public function __construct() { }
}

class B
{
   public function __construct(ClassA $object) { }
}
When you instantiate ClassB , it MUST be an instance of ClassA.

Posted: Wed Jul 26, 2006 12:08 pm
by daedalus__
I know that it's like that in most languages, but I swear the other day someone said you can't do it in PHP.

So, this morning on the bus-ride to work I was working on my error handling class (which is going to be hawt when it's done btw) and I forgot the $ in front of my variable named object, and it flashed colors (i use dreamweaver) and i was like omg you are kidding.

Posted: Wed Jul 26, 2006 12:08 pm
by daedalus__
jamiel wrote:Yes, you can even do this ...

class ClassA
{
public function __construct() { }
}

class B
{
public function __construct(ClassA $object) { }
}

When you instantiate ClassB , it MUST be an instance of ClassA.
omg that is amazing.

Posted: Wed Jul 26, 2006 12:12 pm
by jamiel
Its not however a very desireable way of type checking , as it throw's a fatal error from which your script cannot recover. Only use it when your class can not function at all unless the parameter is a certain type, or an instance of a certain object.

Posted: Wed Jul 26, 2006 12:21 pm
by daedalus__
I already have 5 or 6 different places I want to use that. :)

Posted: Wed Jul 26, 2006 12:37 pm
by feyd
For future references, it's called type hinting in the manual and in many languages.

Posted: Wed Jul 26, 2006 12:40 pm
by Jenk
And has only fully been available since PHP 5.1.x, it is not available in PHP <= 5.0.x (or so I have heard)

Posted: Wed Jul 26, 2006 2:03 pm
by onion2k
If, like me, you're forced to maintain PHP4 code, you can sort of do the same with..

Code: Select all

<?php

function php4TypeHinting($var) {
	$type = gettype($var);
	if ($type=="resource") 	{ $type = get_resource_type($var); }
	if ($type=="object") 	{ $type = get_class($var); }
	return $type;
}

function myStringFunc($input) {
  if (php4TypeHinting($input)!="string") { return -1; }
  return "Input is a string!<br>";
}

function myDBFunc($input) {
  if (php4TypeHinting($input)!="mysql link") { return -1; }
  return "Input is a DB connection!<br>";
}

function myWombleFunc($input) {
  if (php4TypeHinting($input)!="womble") { return -1; }
  return "Input is a womble!<br>";
}

$string = "womble";
echo myStringFunc($string);

$db = mysql_connect("localhost","user","password");
echo myDBFunc($db);

class womble { }
$wom = new womble;
echo myWombleFunc($wom);

?>
Quite handy for library classes.

Posted: Wed Jul 26, 2006 3:35 pm
by timvw
I was possible with php5.0 too (but only for user-space types)....

Anyway, i'm still not sure if this is what i've been waiting for..

Posted: Wed Jul 26, 2006 3:44 pm
by Jenk
It's the overloading associated with typehinting that I am wanting.

Code: Select all

class MyClass
{
    public function __construct (string $var)
    {
    }

    public function __construct (int $var)
    {
    }
}
is much neater (imo) than:

Code: Select all

class MyClass
{
    public function __construct ($var)
    {
        if (is_string($var)) {
            //do something with string..
        } elseif (is_int($var)) {
            //do something with int..
        }
    }
}

Posted: Wed Jul 26, 2006 3:49 pm
by daedalus__
Can you explain that?

Posted: Wed Jul 26, 2006 3:53 pm
by feyd
The function name is the same, but the function signature (functionName@argument1type, for instance) is different. In languages that support such functionality, if I called

Code: Select all

new MyClass('hi');
it would call the first constructor. The similar works if I passed an integer, but calling the second constructor instead.

Posted: Wed Jul 26, 2006 3:55 pm
by daedalus__
that's what i thought, and i like it very much.