Jump to content

Recommended Posts

I've been working with various strongly typed languages rather exclusively for a little while now and was hoping to work with the same features in PHP. I understand that PHP isn't inherently typed but I've come up with some sort of pseudo-typing mechanism outlined below. I was just wondering what your thoughts were on this?

 

class TypeException extends Exception {}
class Account {

private $ID;
private $Name;
private $Password;

private $TypeEnforce; 

public function __construct() {
	$this->TypeEnforce = array(
		'ID' => function($x){return is_numeric($x);},
		'Name' => function($x){ return is_string($x); },
		'Password' => function($x){ return is_string($x); }
	);
}

public function __get($key) {
	return $this->$key;
}

public function __set($key,$value) {
	if(property_exists($this,$key)) {
		if($this->TypeEnforce[$key] != null) {	// Type is enforced
			if($this->TypeEnforce[$key]($value)) {
				$this->$key = $value;
			}
			else {
				throw new TypeException('Type Exception: '. $key .' failed to be set to '. $value);
			}
		}
	}
}
}

try {
$Account = new Account();
$Account->ID = "49ga";
$Account->Name = 'Angelo';
$Account->Password = '49g10fc0q0weq'; 
}
catch(TypeException $e) {
echo $e->getMessage();
}

I don't see anything wrong with validating object vars like that for class variables. That way you know exactly what's in the object vars and there will probably be less bugs.

 

When passing objects into a function, I always use type checking like:

public function add(User $user)
{
   
}

 

I think this prevents bugs from happening down the road, and keeps things more neat.

The biggest problem I see is with maintenance.  With your current example, you'd have to write a valid set of metadata for every single object in your system.  Further, if your design changes, you'll have to go into each affected object and edit its metadata manually.  That will quickly grow tedious.

 

See if you can refactor.

 

@shlumph - type hinting only works with objects and arrays.  It doesn't work on primitives (integers, strings, etc.).  See: http://php.net/manual/en/language.oop5.typehinting.php.

You are Nightslyr, the post was more to see if there were any reasons not to pursue that method of type hinting. I've gone ahead and abstracted everything a bit more. There is now a TypeHinting class that you can extend or instantiate separately to give you access to the TypeHinting abstraction.

 

There is also a TypeDef class that gives you access to primitive Type Definitions, but of course, you are free to extend it and implement static versions of your own Type Definitions.

 

<?php
/**
* Allows you to tie in to the basic TypeHinting methods
* to allow pseudo-type hinting within PHP
*
* @author xangelo
*/
class TypeHinting {

    private $structs;

    /**
     *
     * @param string $type Class Property
     * @param function $cb Callback Method
     */
    protected function AddTypeDef($type,$cb) {
        $this->structs[$type] = $cb;
    }

    /**
     *
     * @param string $key Class Property
     * @param function $value Intented Property Value
     * @return bool
     */
    protected function IsValidType($key,$value) {
        if($this->structs[$key] != null) {
            if(!$this->structs[$key]($value)) {
                throw new TypeException('Type Exception: '.$key.' type mis-match');
                return false;
            }
        }
        return true;
    }
}
?>

 

<?php
/**
* Creates the default primitive and advanced Type Definitions
* for use in Strongly Typing your classes.
*
* @author xangelo
*/
class TypeDef {

    /**
     *
     * @param string $x
     * @return bool
     */
    public static function string($x) {
        return is_string($x);
    }

    /**
     *
     * @param int $x
     * @return bool
     */
    public static function int($x) {
        return is_numeric($x);
    }

    /**
     *
     * @param bool $x
     * @return bool
     */
    public static function bool($x) {
        return is_bool($x);
    }

    /**
     *
     * @param double $x
     * @return double
     */
    public static function double($x) {
        return is_double($x);
    }

    /**
     *
     * @param float $x
     * @return float
     */
    public static function float($x) {
        return is_float($x);
    }


}

/**
* Creates base TypeException class
*
* @author xangelo
*/
class TypeException extends Exception {}
?>

 

And once again, our account class that implements TypeHinting utilizing our TypeDef helper:

<?php
/**
* Sample Account class to implement type hinting
*
* @author xangelo
*/
require_once('TypeDef.php');
require_once('TypeHinting.php');

class Account extends TypeHinting{

private $ID;
private $Name;
private $Password;

public function __construct() {
            $this->AddTypeDef('ID',function($x){return TypeDef::int($x);});
            $this->AddTypeDef('Name',function($x){return TypeDef::string($x);});
            $this->AddTypeDef('Password',function($x){return TypeDef::string($x);});
}

public function __get($key) {
            return $this->$key;
}

public function __set($key,$value) {
            if(property_exists($this,$key)) {
                if($this->IsValidType($key,$value)) {
                    $this->$key = $value;
                }
            }
}
}


try {
$Account = new Account();
$Account->ID = 521;
$Account->Name = 'Angelo';
$Account->Password = '49g10fc0q0weq';
        echo '<pre>'.print_r($Account,true).'</pre>';
}
catch(TypeException $e) {
echo $e->getMessage();
}
?>

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.