PHP allows for polymorphic code that would generate an compile error in other languages.  A simple illustrates this. First C++ code that generates an expected compile error:
class Base {};
class CommonDerivedBase {
   public:
    // The "= 0" makes the method and class abstract
    // virtual means polymorphic method
    virtual whoami() = 0;
};
class DerivedBase : public CommonDerivedBase {
   public:    
     void  whoami() { cout << "I am DerivedBase \n"; }
};
class Derived1 : public CommonDerivedBase {
  public:
    void  whoami() { cout << "I am Derived1\n"; }
};
class Derived2 : public CommonDerivedBase {
public:
 void whoami() { cout <<  "I am Derived2\n"; }
};
/* This will not compile */
void  test_error(Base& db)
{
   db.whoami();
}
The C++ compiler will issue this error message for the line db.whoami()
error: no member named 'whoami' in 'Base'
because Base does not have a method called whoami(). However, the analogous PHP code does not find such errors until run time. 
class Base {}
abstract class DerivedCommonBase {
  abstract function whoami();
}
class Derived1 extends DerivedCommonBase {
 public function whoami() { echo "I am Derived1\n"; }
}
class Derived2 extends DerivedCommonBase {
 public function whoami() { echo "I am Derived2\n"; }
}
/* In PHP, test(Base $b) does not give a runtime error, as long as the object 
 * passed at run time derives from Base and implements whoami().
 */
function test(Base $b)
{
  $b->whoami(); 
}
$b = new Base();
$d1 = new Derived1();
$d2 = new Derived2();
$a = array();
$a[] = $d1;
$a[] = $d2;
foreach($a as $x) {
  echo  test($x);
}
test($d1);
test($d2);
test($b); //<-- A run time error will result.
The foreach loop works with the output
I am Derived1
I am Derived2
Not until you call test($b) and pass an instance of Base will your get a run time error. So after the foreach, the output will be
I am Derived1
I am Derived2
PHP Fatal error:  Call to undefined method Base::whoami() in
home/kurt/public_html/spl/observer/test.php on line 22
About the only thing you can do to make the PHP safer would be to add a run time check
to test if $b is an instance of the class you intended.
function test(Base $b)
{
  if ($b instanceof DerivedCommonBase) {
     $b->whoami(); 
  } 
}
But the whole point of polymorphism is to eliminate such run time checks.