Question

I have a parent classes:

namespace classes;
abstract class MyParent{ abstract function name(); }

Now, two children:

namespace classes;
class Foo extends MyParent{ function name(){ return "Foo class"; } }

namespace classes;
class Bar extends MyParent{ function name(){ return "Bar class"; } }

In java, I can do this:

public void doSomething(AnObject <?extends MyParent?> object){ }

The method above can recive all objects that are extended from MyParent class. How can I achive this in php? Of course, declaring the function simply like function doSomething($child){} does the trick, but I want to specify the type of object like:

function doSomething(classes\{any-children-of-MyParent} $class){}

If I do function doSomething(classes\MyParent $class){} and pass it an instance of Foo class I get this error:

Argument 1 passed to doSomething must be an instance of clasess\MyParent

Was it helpful?

Solution 2

You could write something like this.

public function doSomething(\clases\MyParent $object){ }
                         // ^ namespace from the root.

It's called type hinting

Demo: http://3v4l.org/tqV3s

OTHER TIPS

You were on the right track, @manix.

In PHP, it is exactly the same. If you wish to have any class extending a parent class in a method, simply give the name of the class before the object name. As @sectus said, this is what we call type-hinting.

The problem you seem to have is a namespace issue. Concerning namespaces, you need to know that if you already are in a namespace in your script, and you don't prefix the class name with a backslash (\), the namespace will be resolved relatively to your current namespace.

This means that if you are in

namespace Foo;

The following piece of code will interpret Bar as being part of the Foo namespace.

<?php

namespace Foo;

class Bar
{
    public function doSomething(Bar $bar)
    {
        // ...
    }
}

So if you have another class in the same namespace

<?php

namespace Foo;

class Baz extends Bar
{
    public function doSomething(Bar $bar)
    {
        // ...
    }
}

You don't need to specify the namespace once again. On the other hand, if your class was in another namespace (let's say Quz), Bar would be resolved as Quz\Bar, which is not defined yet.

<?php

namespace Quz;

class Baz extends Bar
{
    public function doSomething(Bar $bar)
    {
        // ...
    }
}

To fix this, you need to either:

  • import the namespace with a use statement
  • use an absolute reference to the Foo\Bar class

    namespace Quz;

    use Foo\Bar;

    class Baz extends Bar { public function doSomething(Bar $bar) { // ... } }

or

<?php

namespace Quz;

class Baz extends \Foo\Bar
{
    public function doSomething(\Foo\Bar $bar)
    {
        // ...
    }
}

The principle is exactly the same for arguments inside a class' methods. Oh, and by the way, if you take a look at the code here, you may see that you may totally do something like

<?php

$quz = new Quz\Baz();
$baz = new Foo\Baz();
$bar = new Foo\Bar();

$bar->doSomething($quz);
$bar->doSomething($bar);
$bar->doSomething($baz);

$quz->doSomething($quz);
$quz->doSomething($bar);
$quz->doSomething($baz);

$baz->doSomething($quz);
$baz->doSomething($bar);
$baz->doSomething($baz);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top