10

In my class I have a method which expects as array, and this array should be used differently depending on the collection type. The array items should be objects, and I need to know which class instance these objects are.

For example: in the array($obj1, $obj2), I need to check the instance of these objects, which class they were created from.

Here some code:

public function convertDataToInsert($data)
{
    if (is_array($data)) {
        foreach ($data as $obj) {
            if ($obj instanceof CriterioDigital) {
                //Ok, an array of CriterioDigital
            } elseif ($obj instanceof ArquivoDigital) {
                //Ok, an array of ArquivoDigital
            } else {
                throw new \Exception('Invalid parameter');
            }
            break;
        }
    }

Or maybe:

public function convertDataToInsert($data)
{
    if (is_array($data)) {
        $obj = $data[0];
        if ($obj instanceof CriterioDigital) {
            //Ok, an array of CriterioDigital
        } elseif ($obj instanceof ArquivoDigital) {
            //Ok, an array of ArquivoDigital
        } else {
            throw new \Exception('Invalid parameter');
        }
    }
}

I only need to check the collection type of this array. I know I can iterate it, but is there any better way in php to do so?

3
  • 1
    No, no better way until you show some code with some input data+what you tried so far+what you expected+where you stuck.Thanks Commented Jul 27, 2017 at 14:05
  • if you build the collections yourself and can be sure all objects in a collection are the same class, just test the first Commented Jul 27, 2017 at 14:06
  • Everything @AlivetoDie said. I downvoted until the question becomes answerable. Commented Jul 27, 2017 at 14:07

5 Answers 5

5

Use an array filter :

if (count(array_filter($data, function ($entry) {
        return !($entry instanceof CriterioDigital);
})) > 0) {
    throw new \DomainException('an array of CriterioDigital must be provided');
}
Sign up to request clarification or add additional context in comments.

1 Comment

You can write it more easily now like this : if (count(array_filter($data, fn($d) => !$d instanceof CriterioDigital)) > 0) {...}
1

A colleague showed me an easy way to check, if an array contains instances of one class only:

class A {}
class B {}
class C extends A {}

$tests = [
    1 => [new A(), new A()], // succeeds
    2 => [new A(), new B()], // fails
    3 => [new C(), new C()], // succeeds, because C extends A
];

foreach ($tests as $index => $collection) {
    try {
        \array_map(static function (A $object): void {}, $collection);
    } catch (\TypeError $e) {
        // Implement your error handling here.
    }
}

Here's an example with output: https://3v4l.org/1IVg9

Comments

0

If you use an array (not object) as collection then you do not have any other choice except to check the array items.

Comments

0

Checking instanceof would mean going through each type until you hit the right one. Instead, try get_class($object) and use a switch statement to figure out what to do next.

Or, create an interface with a getWhateverYouNeed() method, and in each of the relevant object types, implement it. That way, every object no matter what is an instance of GetWhateverYouNeedInterface. Look up 'Strategy Patterns'.

1 Comment

yeah.. I may use get_class then
0

There's another way to achieve this:

<?php // ConvertibleDataCollection.php

abstract class ConvertibleDataCollection
{
    protected $data = [];

    public function setData($data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }

    abstract public function convert();
}
<?php // CriterioDigitalCollection.php

class CriterioDigitalCollection extends ConvertibleDataCollection
{
    public function convert()
    {
    }
}
<?php // ArquivoDigitalCollection.php

class ArquivoDigitalCollection extends ConvertibleDataCollection
{
    public function convert()
    {
    }
}

And then in your class:


    public function convertDataToInsert(ConvertibleDataCollection $dataCollection)
    {
        return $dataCollection->convert();
    }

1 Comment

Please add some further explanation to your answer such that others can learn from it. Where in all this code is the check hidden?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.