Did you know you can do this?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Did you know you can do this?

Post 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.
User avatar
MrPotatoes
Forum Regular
Posts: 617
Joined: Wed May 24, 2006 6:42 am

Post 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 ;)
jamiel
Forum Contributor
Posts: 276
Joined: Wed Feb 22, 2006 5:17 am
Location: London, United Kingdom

Post 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.
Last edited by jamiel on Wed Jul 26, 2006 12:09 pm, edited 1 time in total.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post 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.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post 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.
jamiel
Forum Contributor
Posts: 276
Joined: Wed Feb 22, 2006 5:17 am
Location: London, United Kingdom

Post 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.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

I already have 5 or 6 different places I want to use that. :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

For future references, it's called type hinting in the manual and in many languages.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post 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)
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post 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.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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..
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post 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..
        }
    }
}
Last edited by Jenk on Wed Jul 26, 2006 3:49 pm, edited 1 time in total.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

Can you explain that?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

that's what i thought, and i like it very much.
Post Reply