Skip to content

Instantly share code, notes, and snippets.

@Pierstoval
Last active June 26, 2024 17:03
Show Gist options
  • Save Pierstoval/ed387a09d4a5e76108e60e8a7585ac2d to your computer and use it in GitHub Desktop.
Save Pierstoval/ed387a09d4a5e76108e60e8a7585ac2d to your computer and use it in GitHub Desktop.
`is_a()` vs `is_subclass_of()`

PHP is_a() vs is_subclass_of()

To compute the results, just use Melody and run the script:

melody run https://gist.github.com/Pierstoval/ed387a09d4a5e76108e60e8a7585ac2d
<?php
<<<CONFIG
packages:
- "symfony/console: ^4.1"
CONFIG;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Output\ConsoleOutput;
require __DIR__.'/vendor/autoload.php';
class A
{
}
class B extends A
{
}
interface It
{
}
trait T {
}
class C extends B implements It {
use T;
}
$classes = [
'A',
'B',
'It',
'T',
'C',
];
$rows = [];
foreach ($classes as $class1) {
foreach ($classes as $class2) {
$rows[] = [
$class1.' of '.$class2,
is_a($class1, $class2, true) ? '<fg=green>true</>' : '<fg=red>false</>',
is_subclass_of($class1, $class2, true) ? '<fg=green>true</>' : '<fg=red>false</>',
];
}
}
$table = new Table(new ConsoleOutput());
$table->setHeaders(['Operation', 'is_a()', 'is_subclass_of()']);
$table->setRows($rows);
$table->render();
+-----------+--------+------------------+
| Operation | is_a() | is_subclass_of() |
+-----------+--------+------------------+
| A of A | true | false |
| A of B | false | false |
| A of It | false | false |
| A of T | false | false |
| A of C | false | false |
| B of A | true | true |
| B of B | true | false |
| B of It | false | false |
| B of T | false | false |
| B of C | false | false |
| It of A | false | false |
| It of B | false | false |
| It of It | true | false |
| It of T | false | false |
| It of C | false | false |
| T of A | false | false |
| T of B | false | false |
| T of It | false | false |
| T of T | true | false |
| T of C | false | false |
| C of A | true | true |
| C of B | true | true |
| C of It | true | true |
| C of T | false | false |
| C of C | true | false |
+-----------+--------+------------------+
@gggeek
Copy link

gggeek commented Feb 3, 2023

Small change, adding instanceof to the mix

foreach ($classes as $class1) {
    if ($class1 == 'It' || $class1 == 'T') {
        continue;
    }
    $obj1 = new $class1();
    foreach ($classes as $class2) {
        $rows[] = [
            $class1.' of '.$class2,
            is_a($obj1, $class2, true) ? '<fg=green>true</>' : '<fg=red>false</>',
            is_subclass_of($obj1, $class2, true) ? '<fg=green>true</>' : '<fg=red>false</>',
            $obj1 instanceof $class2 ? '<fg=green>true</>' : '<fg=red>false</>',
        ];
    }
}

In case anyone is wondering about the result: instanceof gives the same results as is_a. It is marginally faster, but it is also more limited in scope (it only accepts an instance as first argument and not a string, and does not accept a variable value as 2nd argument)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment