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.
Example 2 is quite bad for testing... and I don't mean that you can't test the internals. You also can't replace your XmlReader
object by a mock object as you have no object at all.
Example 1 is needlessly hard to use. What about
XmlReader reader = new XmlReader(url);
Document result = reader.getDocument();
which is not any harder to use than your static method.
Things like opening the URL, reading XML, converting bytes to strings, parsing, closing sockets, and whatever, are uninteresting. Creating an object and using it is important.
So IMHO the proper OO Design is to make just the two things public (unless you really need the intermediate steps for some reason). Static is evil.
Best Answer
The classic attributes of OOP are: inheritance, polymorphism and encapsulation. No mention of strong typing.
I do not know PHP, but I have coded OOP Python and it feels just like OOP C#.