PHP code example of crell / attributeutils

1. Go to this page and download the library: Download crell/attributeutils library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

crell / attributeutils example snippets



#[MyAttribute(a: 1, b: 2)]
class Point
{
    public int $x;
    public int $y;
    public int $z;
}

$analyzer = new Crell\AttributeUtils\Analyzer();

$attrib = $analyzer->analyze(Point::class, MyAttribute::class);

// $attrib is now an instance of MyAttribute.
print $attrib->a . PHP_EOL; // Prints 1
print $attrib->b . PHP_EOL; // Prints 2

#[\Attribute]
class AttribWithName implements FromReflectionClass 
{
    public readonly string $name;
    
    public function __construct(?string $name = null) 
    {
        if ($name) {
            $this->name = $name;
        }
    }
    
    public function fromReflection(\ReflectionClass $subject): void
    {
        $this->name ??= $subject->getShortName();
    }
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class MyClass implements ParseProperties
{
    public readonly array $properties;

    public function propertyAttribute(): string
    {
        return MyProperty::class;
    }

    public function setProperties(array $properties): void
    {
        $this->properties = $properties;
    }

    public function ing::class, MyClass::class);

#[\Attribute(\Attribute::TARGET_PROPERTY)]
class MyProperty implements Excludable
{
    public function __construct(
        public readonly bool $exclude = false,
    ) {}
    
    public function exclude(): bool
    {
        return $this->exclude;
    }
}

class Something
{
    #[MyProperty(exclude: true)]
    private int $val;
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class MyClass implements Inheritable
{
    public function __construct(public string $name = '') {}
}

#[MyClass(name: 'Jorge')]
class A {}

class B extends A {}

$attrib = $analyzer->analyze(B::class, MyClass::class);

print $attrib->name . PHP_EOL; // prints Jorge

#[\Attribute(\Attribute::TARGET_CLASS)]
class MainAttrib implements HasSubAttributes
{
    public readonly int $age;

    public function __construct(
        public readonly string name = 'none',
    ) {}

    public function subAttributes(): array
    {
        return [Age::class => 'fromAge'];
    }
    
    public function fromAge(?Age $sub): void
    {
        $this->age = $sub?->age ?? 0;
    }
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class Age
{
    public function __construct(public readonly int $age = 0) {}
}

#[MainAttrib(name: 'Larry')]
#[Age(21)]
class A {}

class B {}

$attribA = $analyzer->analyze(A::class, MainAttrib::class);

print "$attribA->name, $attribA->age\n"; // prints "Larry, 21"

$attribB = $analyzer->analyze(B::class, MainAttrib::class);

print "$attribB->name, $attribB->age\n"; // prints "none, 0"

#[\Attribute(\Attribute::TARGET_CLASS)]
class MainAttrib implements HasSubAttributes
{
    public readonly int $age;
    public readonly string $name;

    public function __construct(
        public readonly string name = 'none',
    ) {}

    public function subAttributes(): array
    {
        return [
            Age::class => $this->fromAge(...),
            Name::class => function (?Name $sub) {
                $this->name = $sub?->name ?? 'Anonymous';
            }
        ];
    }

    private function fromAge(?Age $sub): void
    {
        $this->age = $sub?->age ?? 0;
    }
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class MainAttrib implements HasSubAttributes
{
    public readonly array $knows;

    public function __construct(
        public readonly string name = 'none',
    ) {}

    public function subAttributes(): array
    {
        return [Knows::class => 'fromKnows'];
    }
    
    public function fromKnows(array $knows): void
    {
        $this->knows = $knows;
    }
}

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
class Knows implements Multivalue
{
    public function __construct(public readonly string $name) {}
}

#[MainAttrib(name: 'Larry')]
#[Knows('Kai')]
#[Knows('Molly')]
class A {}

class B {}

$analyzer = new MemoryCacheAnalyzer(new Analyzer());

$anaylzer = new Psr6CacheAnalyzer(new Analyzer(), $somePsr6CachePoolObject);

$analyzer = new MemoryCacheAnalyzer(new Psr6CacheAnalyzer(new Analyzer(), $psr6CachePool));

#[\Attribute(\Attribute::TARGET_CLASS)]
class Labeled implements ParseProperties
{
    public readonly array $properties;

    public function setProperties(array $properties): void
    {
        $this->properties ??= $properties;
    }

    public function ic function __construct(
        public readonly string $name = 'Untitled',
        public readonly ?string $language = null,
        public readonly bool $exclude = false,
    ) {}

    public function scopes(): array
    {
        return [$this->language];
    }

    public function exclude(): bool
    {
        return $this->exclude;
    }
}

#[Labeled]
class App
{
    #[Label(name: 'Installation')]
    #[Label(name: 'Instalación', language: 'es')]
    public string $install;

    #[Label(name: 'Setup')]
    #[Label(name: 'Configurar', language: 'es')]
    #[Label(name: 'Einrichten', language: 'de')]
    public string $setup;

    #[Label(name: 'Einloggen', language: 'de')]
    #[Label(language: 'fr', exclude: true)]
    public string $login;

    public string $customization;
}

$labels = $analyzer->analyze(App::class, Labeled::class, scopes: ['es']);

$labels = $analyzer->analyze(SomeClass::class, AnAttribute::class, scopes: ['One', 'Two']);


#[\Attribute(\Attribute::TARGET_PROPERTY)]
class MyClass implements ParseProperties
{
    public readonly array $properties;

    public function setProperties(array $properties): void
    {
        $this->properties = $properties;
    }
    
    public function '') {}
}

class Stuff
{
    #[FancyName('A happy little integer')]
    protected int $foo;

    protected string $bar;
    
    protected Person $personOne;
    
    #[FancyName('Her Majesty Queen Elizabeth II')]
    protected Person $personTwo;
}

#[FancyName('I am not an object, I am a free man!')]
class Person
{
}

$attrib = $analyzer->analyze(Stuff::class, MyClass::class);

print $attrib->properties['foo']->name . PHP_EOL; // prints "A happy little integer"
print $attrib->properties['bar']->name . PHP_EOL; // prints ""
print $attrib->properties['personOne']->name . PHP_EOL; // prints "I am not an object, I am a free man!"
print $attrib->properties['personTwo']->name . PHP_EOL; // prints "Her Majesty Queen Elizabeth II"

use Crell\AttributeUtils\FuncAnalyzer;

#[MyFunc]
function beep(int $a) {}

$closure = #[MyClosure] fn(int $a) => $a + 1;

// For functions...
$analyzer = new FuncAnalyzer();
$funcDef = $analyzer->analyze('beep', MyFunc::class);

// For closures
$analyzer = new FuncAnalyzer();
$funcDef = $analyzer->analyze($closure, MyFunc::class);

# In-memory cache.
$analyzer = new MemoryCacheFunctionAnalyzer(new FuncAnalyzer());

# PSR-6 cache.
$anaylzer = new Psr6CacheFunctionAnalyzer(new FuncAnalyzer(), $somePsr6CachePoolObject);

# Both caches.
$analyzer = new MemoryCacheFunctionAnalyzer(
    new Psr6CacheFunctionAnalyzer(new FuncAnalyzer(), $psr6CachePool)
);

use Crell\AttributeUtls\Attributes\Reflect\ReflectClass;

$reflect = $analyzer->analyze($someClass, ReflectClass::class);

#[\Attribute(Attribute::TARGET_CLASS)]
class Names implements HasSubAttributes, IteratorAggregate, ArrayAccess
{
    protected readonly array $names;

    public function subAttributes(): array
    {
        return [Alias::class => 'fromAliases'];
    }

    public function fromAliases(array $aliases): void
    {
        $this->names = $aliases;
    }

    public function getIterator(): \ArrayIterator
    {
        return new ArrayIterator($this->names);
    }

    public function offsetExists(mixed $offset): bool
    {
        return array_key_exists($offset, $this->names);
    }

    public function offsetGet(mixed $offset): Alias
    {
        return $this->names[$offset];
    }

    public function offsetSet(mixed $offset, mixed $value): void
    {
        throw new InvalidArgumentException();
    }

    public function offsetUnset(mixed $offset): void
    {
        throw new InvalidArgumentException();
    }
}

#[\Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
class Alias implements Multivalue
{
    public function __construct(
        public readonly string $first,
        public readonly string $last,
    ) {}

    public function fullName(): string
    {
        return "$this->first $this->last";
    }
}

#[Alias(first: 'Bruce', last: 'Wayne')]
#[Alias(first: 'Bat', last: 'Man')]
class Hero
{
    // ...
}

$names = $analyzer->analyze(Hero::class, Names::class);

foreach ($names as $name) {
    print $name->fullName() . PHP_EOL;
}

// Output:
Bruce Wayne
Bat Man


#[\Attribute(\Attribute::TARGET_CLASS)]
class Names implements HasSubAttributes, IteratorAggregate, ArrayAccess
{
    protected readonly array $names;

    public function subAttributes(): array
    {
        return [Name::class => 'fromNames'];
    }

    public function fromNames(array $names): void
    {
        $this->names = $names;
    }

    // The same ArrayAccess and IteratorAggregate code as above.
}

interface Name extends Multivalue
{
    public function fullName(): string;
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class RealName implements Name
{
    public function __construct(
        public readonly string $first,
        public readonly string $last,
    ) {}

    public function fullName(): string
    {
        return "$this->first $this->last";
    }
}

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
class Alias implements Name
{
    public function __construct(public readonly string $name) {}

    public function fullName(): string
    {
        return $this->name;
    }
}

#[RealName(first: 'Bruce', last: 'Wayne')]
#[Alias('Batman')]
#[Alias('The Dark Knight')]
#[Alias('The Caped Crusader')]
class Hero
{
    // ...
}

interface DisplayType {}

#[\Attribute(\Attribute::TARGET_CLASS)]
class Screen implements DisplayType
{
    public function __construct(public readonly string $color) {}
}

#[\Attribute(\Attribute::TARGET_CLASS)]
class Audio implements DisplayType
{
    public function __construct(public readonly int $volume) {}
}

#[\Attribute(Attribute::TARGET_CLASS)]
class DisplayInfo implements HasSubAttributes
{
    public readonly ?DisplayType $type;

    public function subAttributes(): array
    {
        return [DisplayType::class => $this->fromDisplayType(...)];
    }

    public function fromDisplayType(?DisplayType $type): void
    {
        $this->type = $type;
    }
}

#[Screen('#00AA00')]
class A {}

#[Audio(10)]
class B {}

class C {}

$displayInfoA = $analyzer->analzyer(A::class, DisplayInfo::class);
$displayInfoB = $analyzer->analzyer(B::class, DisplayInfo::class);
$displayInfoC = $analyzer->analzyer(C::class, DisplayInfo::class);