Strongly Typed PHP

Often you'll hear the term "strongly typed" which refers to certain constraints being enforced regarding variables.

PHP is a "weakly typed" language which means php doesn't require (nor support it for that matter) explicit type declaration of variables.

Whatever value one assign to a variable, determines its type and when you assign something else to it, it changes type according again. (Most uncompiled languages use this technique) (which can lead to very dodge code)

But what if you want to make your classes strongly typed? (Force whoever use your class to assign the correct values to your class properties) - surely we can put checks in our code, but that can get a bit tedious.

Overloading in PHP 5 is a quick solution, one can overload the get and set members and control whatever variables get assigned and retrieved from your class.

Here is a quick snippet:

 
<?php
 
class StronglyTyped
{
	private $x;
 
	private function __get($name)
	{	
		if (!isset($this->enforcetype[$name]))
		{
			die("<b>Exception occured: </b>calling property $name which does not exist or set private");
		}		
		return $this->x[$name];
	}
 
	private function __set($name,$value)
	{		
		$type = $this->enforcetype[$name];
 
		if (isset($type) && $type != "")
		{
			$given = gettype($value);
 
			if ($given == $type) 
				$this->x[$name] = $value;
			else
			{	
				$exception = ($given != "") ? "<b>Exception occured on $name property:</b> 
												Type <i>$type</i> expected, type <i>$given</i> was supplied"
											: "<b>Exception occured:</b> no type specified for property $name";
				die($exception);
			}
		}
		else die("<b>Exception occured:</b> property $name not defined<br/>");
	}
}
 
?>
 
In the next snippet we inherit from the top class our "constraining class", we need to create an array, which contains our variable names and our preset types we want to constraint on.

 
class test extends StronglyTyped
{
	public $enforcetype = array("stringy" => "string",
							"inty" => "integer",
							"booly" => "bool");
}
 
Once we instantiate the class, and try to assign an integer value for example, to the stringy member, we get an exception, since we specified we only accept string types for that member. If we try to assign to undefined members we get an exception as well, all much like we see in languages like C#.



Comments

Yes, this is what they call type hinting in PHP 5 http://www.php.net/oop5.typehinting Another way of doing this, is to create getters/setters for these properties you wish to be "strongly typed" and define your "constraints" within these methods. http://www.codebooth.com/snippets/24


Using wrappers

What one could do to implement strongly typed variables, is to use wrapper classes just as it is done in Java, where everything is object. And do not forget that you can specify the class of a function parameter, like : public static final myFunction(Animal $oAnimal) And if you call that function with anything else than an Animal class instance, it will fail. Then, all you have to do, is to create a wrapper class for all the "basic types" you use (int, string, boolean, double, ...) See you !


Can do

Hey Thoward, it should be quite easy to modify the solution, one can simply remove the die in the set method, maybe register it as warning against PHP's trigger_error method (If you wish to check up on things later on) This was just a quick solution I came up with when I wanted some C# functionality in my PHP classes - always looking for better ways to do things, maybe give it a PHP flavour like you suggested?


I can see both points.

I came across this article looking for information on strong-typing in PHP because I'm a C# developer needing to do some OO work in PHP5. The lack of strong typing makes my poor brain twitch and quiver and leaves me running screaming from my IDE. That said, I think your implementation of strong typing shouldn't be so absolute. The way I would expect the behaviour to work would be: I have a variable that I want to strongly type, I register it in the strongly typed associative array (keyed by variable name, value of type name). The strongly typed base class get and set overloads check the array, and if the property is in the array, it enforces the type defined there strictly. If not, it does nothing (i.e., behaves in the normal dynamically typed PHP way). From what I can tell, in your implementation, if a variable is not registered in the array, it will throw an exception... Making it far to strict for Rome.


Strongly Typed PHP

This is gr8. Because a language that isn't strongly typed leaves the loophole open for erroneous code and code that is hard to read and debug. Although I'm a huge fan of strongly typed languages, there must also be a way to declare a "variant" type that only infer the type at initialization so that the type cannot change after it has been assigned, which makes "type inference" possible (For example the var keyword in C#).


Think about it

Thank you for your comment. When creating this class, my first and obvious design was to check existing class members, so yes i did think about it. The problem was that once you defined your class members, it fell outside the jurisdiction of the class get/set (don't know why PHP 5 behaves this way...) which we need to get this working, since I want to control everything that goes into and comes out of my class. So unfortunately I had to resort to doing it with an array, there will probably be a better way, this is a work in progress :) Assign all types to class members - yes thats the whole idea, and not being able to create new members not defined within the class is also correct, isn't it a bit dodgy doing that outside the class and inheritance in any case? There is quite a few pros in strongly typing (google it), mostly its supposed to help us to write better code, help enforce constraints on our classes, sooo when others use it, they cant assign crap to it. I think it all boils down to best practices and what we consider to be standards etc. Think about it - try a language like C# for a bit. Tell me what you think?


Not that great!

You'd seriously have to assign types to _all_ class members!! And you can't create any new members like this. It's a weird class. IF I'd use "strong typing", I wouldnt create the $enforcetype array, but just have the class check the type of the existing class members. That means you'd have to init all class members in your class. It means, though, that you can't set any class member to NULL, which sucks. I don't think this "strongly typed" stuff is that awesome!


Post comment

Name *
Email
Title
Body *
Security Code
*
* Required fields