3

I know PHP is a very error tolerant language and I guess that is why you can have mixed variables for function calls like:

/**
 * @param mixed $bar
 **/
function foo($bar) {
    // Do something with $bar, but check it's type!
}

Is there a recommended way of NOT using such mixed variables?

For my own projects, I try to avoid such mixed variables, just to have less problems with errors later and for code clarity.

And with PHP 7, it should be possible to declare what type of variable this function is expecting, shouldn't it? How is this done?

Jurik
  • 3,244
  • 1
  • 31
  • 52
  • we can add type to function foo (array $bar) { //$bar should be array} – vijaykumar May 30 '16 at 10:00
  • @vijaykumar but this works only with PHP 7, correct? – Jurik May 30 '16 at 10:01
  • Type checking is nice for a whole slew of reasons, and using the interpreter to do it (instead of by hand) when you can is always best. But there will always be instances where code can be cleaner with mixed variables than with strong typing. – Kittsil May 30 '16 at 10:02
  • 2
    No it will work on 5.3 + – Pratik Soni May 30 '16 at 10:02
  • No Please check this http://php.net/manual/en/language.oop5.typehinting.php – vijaykumar May 30 '16 at 10:02
  • http://php.net/manual/de/migration70.new-features.php says PHP5 accepted already `class names`, `interfaces`, `array` and `callable`. – Jurik May 30 '16 at 10:04
  • PHP 7 added some value types, but others have existed since 5.0: http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration – Kittsil May 30 '16 at 10:05
  • PHP is **loosely typed**, which is entirely different from being **very error tolerant** (please note I'm not supporting or denying the latter). – Álvaro González May 30 '16 at 10:20

2 Answers2

2

This could quickly become a matter of opinion, but, I feel that loose typing introduces more possibilities for bugs to occur. There may be some cases where it's appropriate, but generally, for code that needs to be reliable and maintainable (possibly above "flexible"), strict typing is safer.

PHP 5 has "type hinting":

As of PHP 5.0, you can use class or interface names as a type hint, or self:

<?php
function testFunction(User $user) {
    // `$user` must be a User() object.
}

As of PHP 5.1, you can also use array as a type hint:

<?php
function getSortedArray(array $array) {
    // $user must be an array
}

PHP 5.4 adds callable for functions/closures.

<?php
function openWithCallback(callable $callback) {
    // $callback must be an callable/function
}

As of PHP 7.0, scalar types can be used as well (int, string, bool, float):

<?php
function addToLedger(string $item, int $quantity, bool $confirmed, float $price) {
    ...
}

As of PHP 7, this is now called a Type Declaration.

PHP 7 also introduces Return Type Declarations, allowing you to specify what type a function returns. This function must return a float:

<?php
function sum($a, $b): float {
    return $a + $b;
}

If you're not using PHP7, you can use the type hints that are available, and fill the remaining gaps with proper PHPDoc documentation:

<?php

/**
 * Generates a random string of the specified length, composed of upper-
 * and lower-case letters and numbers.
 *
 * @param int $length Number of characters to return.
 * @return string Random string of $length characters.
 */
public function generateRandomString($length)
{
    // ...

    return $randomString;
}

Many editors can parse these comments and warn you about improper typing (PHPStorm, for example).

Will
  • 24,082
  • 14
  • 97
  • 108
  • Strict typing also opens your code to bugs, just different bugs. Ask the ESA about about their Arianne 5 rocket, Flight 501, and conversions from 64-bit floating point to 16-bit signed integer ;-) – Álvaro González May 30 '16 at 10:33
  • I agree it could. But less-so in PHP. Types are simple; there are no sizes. – Will May 30 '16 at 11:12
2

This will likely get closed as being "based on opinion", but it's still a good question.

A function should do one thing. If you need to do this:

if it's a string
    do this
else if it's a Foo object
    do this other thing

Then it's doing more than one thing, which is "less than ideal" form.

Why don't you just provide two well-named methods instead, eg: getThingById(int) and getThingByFilters(Filters) or getThingLike(string) etc? It'll make your code more readable and predictable, too.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
  • I think in case of good quality code you can not see this as an opinion based question. Of course good and bad code could output same correct result, but one has so many more advantages ... – Jurik May 30 '16 at 14:02
  • Who says that a function should do one thing? I guess that is the true answer. – Jurik May 30 '16 at 14:03
  • Bob Martin probably has something to say about it vis-a-vis Clean Code (read his book on the subject: it's gold), but I think it's just "received wisdom" innit? I've heard plenty of people espouse it (I always will when I'm reviewing code), and I've never heard or read of anyone presenting a cogent case which counters it. Of course everything should be measured with "it depends", but for this question right here, I think it's the right advice. Do you not? – Adam Cameron May 30 '16 at 17:15
  • Oh and when I suggested it'll likely get closed because of any answer being opinion based... I was not meaning to suggest that's a *good* thing. It's just one of the less-well-thought-out rules of this joint which community moderators like exercising their "close" fingers on, because they've got nothing better to add, but still want validation here. It's a bit toxic, but that's how some ppl in the IT industry are, I guess :-( – Adam Cameron May 30 '16 at 17:17
  • Okay, maybe I should have asked for the advantages of function calls without mixed variables? – Jurik May 30 '16 at 17:39