In a weakly-typed language, type-casting exists to remove ambiguity in typed operations, when otherwise the compiler/interpreter would use order or other rules to make an assumption of which operation to use.
Normally I would say PHP follows this pattern, but of the cases I've checked, PHP has behaved counter-intuitively in each.
Here are those cases, using JavaScript as a comparison language.
String Concatentation
Obviously this is not a problem in PHP because there are separate string concatenation (.
) and addition (+
) operators.
JavaScript
var a = 5;
var b = "10"
var incorrect = a + b; // "510"
var correct = a + Number(b); // 15
String Comparison
Often in computer systems "5" is greater than "10" because it doesn't interpret it as a number. Not so in PHP, which, even if both are strings, realizes they are numbers and removes the need for a cast):
JavaScript
console.log("5" > "10" ? "true" : "false"); // true
PHP
echo "5" > "10" ? "true" : "false"; // false!
Function signature typing
PHP implements a bare-bones type-checking on function signatures, but unfortunately it's so flawed it's probably rarely usable.
I thought I might be doing something wrong, but a comment on the docs confirms that built-in types other than array cannot be used in PHP function signatures - though the error message is misleading.
PHP
function testprint(string $a) {
echo $a;
}
$test = 5;
testprint((string)5); // "Catchable fatal error: Argument 1 passed to testprint()
// must be an instance of string, string given" WTF?
And unlike any other language I know, even if you use a type it understands, null can no longer be passed to that argument (must be an instance of array, null given
). How stupid.
Boolean interpretation
[Edit]: This one is new. I thought of another case, and again the logic is reversed from JavaScript.
JavaScript
console.log("0" ? "true" : "false"); // True, as expected. Non-empty string.
PHP
echo "0" ? "true" : "false"; // False! This one probably causes a lot of bugs.
So in conclusion, the only useful case I can think of is... (drumroll)
Type truncation
In other words, when you have a value of one type (say string) and you want to interpret it as another type (int) and you want to force it to become one of the valid set of values in that type:
$val = "test";
$val2 = "10";
$intval = (int)$val; // 0
$intval2 = (int)$val2; // 10
$boolval = (bool)$intval // false
$boolval2 = (bool)$intval2 // true
$props = (array)$myobject // associative array of $myobject's properties
I can't see what upcasting (to a type that encompasses more values) would really ever gain you.
So while I disagree with your proposed use of typing (you essentially are proposing static typing, but with the ambiguity that only if it was force-cast into a type would it throw an error — which would cause confusion), I think it's a good question, because apparently casting has very little purpose in PHP.
Why? Because, although consistent terminology is generally good for the entire profession, language designers don't always respect the language use of other language designers, particularly if those other languages are perceived as competitors.
But really, neither use of 'reference' was a very good choice. "References" in C++ are simply a language construct to introduce aliases (alternative names for exactly the same entity) explicitly. Things would have been much clearer of they had simply called the new feature "aliases" in the first place. However, at that time the big difficulty was to make everyone understand the difference between pointers (which require dereferencing) and references (which don't), so the important thing was that it was called something other than "pointer", and not so much specifically what term to use.
Java doesn't have pointers, and is proud of it, so using "pointer" as a term was no option. However, the "references" that it does have behave quite a bit as C++'s pointers do when you pass them around - the big difference is that you can't do the nastier low-level operations (casting, adding...) on them, but they result in exactly the same semantics when you pass around handles to entities that are identical vs. entities that merely happen to be equal. Unfortunately, the term "pointer" carries so many negative low-level associations that it's unlikely ever to be accepted by the Java community.
The result is that both languages use the same vague term for two rather different things, both of which might profit from a more specific name, but neither of which is likely to be replaced any time soon. Natural language, too, can be frustrating sometimes!
Best Answer
Your assertion that references are rarely used is incorrect. As others have already mentioned there's a ton of native functions that use references, notable examples include the array sorting functions and
preg_match()
/preg_match_all()
. If you are using any of these functions in your code, you are also using references.Moving on, references in PHP are not pointers. Since you're coming from a C++ background I can understand the confusion, but PHP references are an entirely different beast, they are aliases to a symbol table. Any performance gains you might have expected from C++ references simply don't apply to PHP references.
In fact, in most scenarios passing by value is faster and less memory intensive than passing by reference. The Zend Engine, PHP's core, uses a copy-on-write optimization mechanism that does not create a copy of a variable until it is modified. Passing by reference usually breaks the copy-on-write pattern and requires a copy whether you modify the value or not.
Don't be afraid to use references in PHP when you need to, but don't just do it as an attempt to micro-optimize. Remember, premature optimization is the root of all evil.
Further reading: