Let's say you have a file like this:
<?php
declare(strict_types=1);
class Foo
{
protected $x;
public function __construct(array $x = [])
{
$this->x = $x;
}
public function bar(int $y): string
{
if (!array_key_exists($y, $this->z)) {
throw new Exception("Key not found");
}
}
public function baz(string $y): int
{
foreach ($this->x as $key => $value) {
if ($y === $value) {
return $key;
}
}
throw new Exception("Value not found");
}
}
PHP 7 enforces strictness on a per-file basis. So even though you're using them, if someone writes another script that calls it like this, it will work:
<?php
require "src/Foo.php";
$data = new Foo(['a', 'b', 'c', 'def']);
var_dump($data->bar('2')); // string(1) "c"
If you wanted to be completely hostile towards your users and demand they use strict types, here's how you do it:
<?php
declare(strict_types=1);
class Foo
{
protected $x;
public function __construct(array $x = [])
{
$this->x = $x;
}
// Notice: No parameter type declarations
public function bar($y): string
{
return $this->actualBar($y);
}
// Notice: No parameter type declarations
public function baz($y): int
{
return $this->actualBaz($y);
}
protected function actualBar(int $y): string
{
if (!array_key_exists($y, $this->z)) {
throw new Exception("Key not found");
}
}
protected function actualBaz(string $y): int
{
foreach ($this->x as $key => $value) {
if ($y === $value) {
return $key;
}
}
throw new Exception("Value not found");
}
Because the public API doesn't enforce types, PHP won't use weakly-typed conversion rules. It will pass them wholesale.
Then, when your public API methods (which exist in bat country a.k.a. strict_types=1 land) pass them to your protected methods, the strict types rules will be enforced. And thus, TypeError
gets thrown, regardless of your user's type preference.
Why.. you still end up with the types you need in the class regardless.