Data types should be very specific. Anyone using a variable should know exactly what type it is, how it looks like (if it’s a structure). While for some languages it’s common sense and really enforced, others will let you mess with a variable’s type, no matter it’s a primitive, an object, an array.
I’m going to talk about data coming from JSON, databases or other sources, which can be represented into data structures.
In a language like Go, you map data into well defined structures.
package main import ( "encoding/json" "fmt" ) type Person struct { ID int Age int Name string } func main() { string := `{ "id":453, "age":26, "name":"John Doe" }` input := []byte(string) person := Person{} err := json.Unmarshal(input, &person) if err != nil { panic(err) } fmt.Println(person) // Person struct fmt.Println(person.ID) // integer fmt.Println(person.Age) // integer fmt.Println(person.Name) // string }
You know exactly that you have an object of type Person, with integer ID, integer Age, and string Name. No need to check anything anywhere. If you mess up, you’ll know at compile time.
A dynamic typed language like PHP has a different approach.
$string = '{ "id":453, "age":26, "name":"John Doe" }'; $person = json_decode($string); print_r($person); echo "\n"; echo $person->id . "\n"; echo $person->age . "\n"; echo $person->name . "\n";
You’ll get a generic object, with some properties not defined anywhere, you just assume you have them. A developer using your API won’t know what the object his working with looks like. It’s just an obscure object.
But you can handle this even in PHP, and you really should. You should avoid as much as possible using generic objects, and arrays for variables that represent an entity, a structure. You can do this by having a type (a data structure class).
<?php class Person { /** * @var int */ private $id; /** * @var int */ private $age; /** * @var string */ private $name; /** * @return int */ public function getId() { return $this->id; } /** * @param int $id */ public function setId($id) { $this->id = $id; } /** * @return int */ public function getAge() { return $this->age; } /** * @param int $age */ public function setAge($age) { $this->age = $age; } /** * @return string */ public function getName() { return $this->name; } /** * @param string $name */ public function setName($name) { $this->name = $name; } } $string = '{"id":453, "age":26, "name":"John Doe"}'; $response = json_decode($string); $person = new Person(); $person->setId($response->id); $person->setName($response->name); echo $person->getId(). "\n"; // You can also declare the argument type in a function, so you know exactly what type you're working with function display(Person $person) { print_r($person->getName()); } display($person);
Wait… I still used the generic object and just passed its assumed values into another object. Indeed, it’s out of scope how you get the data into the object.
The purpose of this type short presentation is to encourage you to return well defined objects from your functions, and use well defined types for functions arguments, so that anyone who interacts with your API knows what they’re dealing with.
The “overhead” is worth every extra bit used, things are transparent, type hinting saves a lot of validation, developers will be happy to know exactly the type they’re using.