79123633

Date: 2024-10-24 21:19:01
Score: 0.5
Natty:
Report link

@Jaquarh convinced me it was way easier than I thought it would be by really testing. His version was the basis for this solution. Thanks, Jaquarh!

I haven't tested with Resources since I don't store them, if someone wants to add an answer with Resources please do.

<?php

function test_type(mixed $value, string $type): bool
{   $foundType =  strtolower(gettype($value)); 
    $foundType = ['boolean'=>'bool', 'integer'=>'int', 'double'=>'float'][$foundType] ?? $foundType;
    
    $type = str_replace('?', 'null|', $type);
    $typesUnion = explode('|', $type);
    $typesIntersection = explode('&', $type);
    if ( count($typesIntersection)>1) {
        if (  ! is_object($value) ) return false;
        foreach($typesIntersection as $subtype) {
            if ( ! ($value instanceof $subtype)) return false;
        }
        return true;
    }
    foreach($typesUnion as $subtype) {

        if ( is_null($value) && strtolower($subtype)=='null' )  return true;       
        if ( $value === false && strtolower($subtype)=='false' )  return true;       
        if ( $value === true && strtolower($subtype)=='true' )  return true;       
        if ( is_callable($value) && strtolower($subtype)=='callable' )  return true;       
        if ( is_object($value) ) { if ( $value instanceof $subtype) return true; }
        elseif ( $foundType == strtolower($subtype) ) return true;
    }
    return false;
}

enum hello { case world; case earth; case mars; };

echo (int) test_type(false,  "int|bool");                                   // 1
echo (int) test_type(null,  "?int");                                        // 1
echo (int) test_type(null,  "int|string");                                  // 0
echo (int) test_type("hello, world", "?bool");                              // 0
echo (int) test_type(hello::world, "hello");                                // 1
echo (int) test_type(false, "DateTimeInterface|false");                     // 1
echo (int) test_type(true, "DateTimeInterface|false");                      // 0
echo (int) test_type(new DateTime, "DateTimeInterface|false");              // 1
echo (int) test_type(new DateTime, "null|int|DateTime|DateTimeImmutable");  // 1
echo (int) test_type(new DateTime, "DateTime&DateTimeInterface");           // 1
echo (int) test_type([1,2,3,4], "Array");                                   // 1
echo (int) test_type(fn($x) => $x+1, "callable");                           // 1

https://onlinephp.io/c/fea67

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Jaquarh
  • Self-answer (0.5):
Posted by: Roemer