I was reading through some PHP code, and I noticed a class calling a protected method on its sibling (inherited from a common parent). This strikes me as counter-intuitive.
Does in the same inheritance tree in PHP mean something like Java's part of the same package ?  
I'm more used to the C# meaning of protected.
Because I am more used to C#'s meaning of protected, I was not expecting to be able to call the protected method on a sibling class. In Java, the distinction is clear from the package. Is there anything, other than inheritance, that defines accessibility in this instance in PHP?
<?
class C1
{
    protected function f()
    {
        echo "c1\n";
    }
}
class C2 extends C1
{
    protected function f()
    {
        echo "c2\n";
    }
}
class C3 extends C1
{
    public function f()
    {
        // Calling protected method on parent.
        $c1 = new C1();
        $c1 -> f();
        // Calling protected method on sibling??!?
        $c2 = new C2();
        $c2 -> f();
        echo "c3\n";
    }
}
$c3 = new C3();
$c3 -> f();
// OUTPUT:
// c1
// c2
// c3
Here's me trying to the same thing in C# (and failing).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
    class c1
    {
        protected void f()
        {
            Console.WriteLine("c1");
        }
    }
    class c2: c1
    {
        protected void f()
        {
            Console.WriteLine("c2");
        }
        public void g()
        {
            Console.WriteLine("g!");
        }
    }
    class c3 : c1
    {
        protected void f()
        {
            // Error    1   Cannot access protected member 'ConsoleApplication2.c1.f()' 
            //  via a qualifier of type 'ConsoleApplication2.c1'; the qualifier must be 
            // of type 'ConsoleApplication2.c3' (or derived from it)    
            //c1 cone = new c1();
            //cone.f();
            base.f();
            c2 ctwo = new c2();
            //Error 1   'ConsoleApplication2.c2.f()' is inaccessible due to its protection level
            ctwo.f();
            ctwo.g();
            Console.WriteLine("c3");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            c3 cthree = new c3();
            // Error    2   'ConsoleApplication2.c3.f()' is inaccessible due to its protection level
            cthree.f();
        }
    }
}
It looks like the behaviour expected was the case prior to PHP 5.2. This RFC explains the issue a little more, and points to why the change happened in this bug.
I'm not sure it quite answers my question, but I thought I'd update the question, in case it helps anyone.
Thanks to Robin F., for pointing me to this discussion of the RFC, for some background.
 
     
     
    