Laravel Live Japan

Öznitelik Sözdizimi

Öznitelik sözdizimi çeşitli parçalardan oluşur. İlk olarak, öznitelik bildirimi her zaman bir #[ ile başlar ve bir ] biter. İçeride, virgüllerle ayrılmış bir veya daha fazla öznitelik bulunur. Öznitelik adı, İsim alanlarının kullanımı: Temeller bölümünde açıklandığı gibi nitelenmemiş, nitelenmiş veya tam nitelenmiş olabilir. Özniteliğin bağımsız değişkenleri isteğe bağlıdır, ancak normalde parantez () içine alınır. Özniteliklerin bağımsız değişkenleri yalnızca değişmez değerler veya sabit ifadeleri olabilir. Hem konumsal hem de isimli bağımsız değişken sözdizimi kullanılabilir.

Öznitelik adları ve bağımsız değişkenleri bir sınıfa çözümlenir, eğer özniteliğin bir örneği yansıtma arayüzü aracılığıyla istenirse bağımsız değişkenler kurucuya iletilir. Her öznitelik için böyle bir sınıf kullanılmalıdır.

Örnek 1 - Öznitelik Sözdizimi

<?php
// a.php
namespace MyExample;

use
Attribute;

#[
Attribute]
class
MyAttribute
{
const
VALUE = 'value';

private
$value;

public function
__construct($value = null)
{
$this->value = $value;
}
}

// b.php

namespace Another;

use
MyExample\MyAttribute;

#[
MyAttribute]
#[
\MyExample\MyAttribute]
#[
MyAttribute(1234)]
#[
MyAttribute(value: 1234)]
#[
MyAttribute(MyAttribute::VALUE)]
#[
MyAttribute(array("key" => "value"))]
#[
MyAttribute(100 + 200)]
class
Thing
{
}

#[
MyAttribute(1234), MyAttribute(5678)]
class
AnotherThing
{
}
add a note

User Contributed Notes 2 notes

up
3
yarns dot purport0n at icloud dot com
1 year ago
It wasn't obvious to me for a while but you can subclass attributes

https://3v4l.org/TrMTe

<?php

#[Attribute(Attribute::TARGET_PROPERTY)]
class PropertyAttributes
 {
    public function __construct(
        public readonly ?string $name = null,
        public readonly ?string $label = null,
    ) {}
 }

#[Attribute(Attribute::TARGET_PROPERTY)]
class IntegerPropertyAttributes extends PropertyAttributes
 {
    public function __construct(
        ?string $name = null,
        ?string $label = null,
        public readonly ?int $default = null,
        public readonly ?int $min = null,
        public readonly ?int $max = null,
        public readonly ?int $step = null,
    ) {
        parent::__construct($name, $label);
    }
 }

#[Attribute(Attribute::TARGET_PROPERTY)]
class FloatPropertyAttributes extends PropertyAttributes
 {
    public function __construct(
        ?string $name = null,
        ?string $label = null,
        public readonly ?float $default = null,
        public readonly ?float $min = null,
        public readonly ?float $max = null,
    ) {
        parent::__construct($name, $label);
    }
 }

class MyClass
 {
     #[IntegerPropertyAttributes('prop', 'property: ', 5, 0, 10, 1)]
     public int $prop;
 }

$refl = new ReflectionProperty('MyClass', 'prop');
$attributes = $refl->getAttributes();

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
?>
up
0
yarns_purport0n at icloud dot com
10 hours ago
Attribute Subclassing https://3v4l.org/8jqK3#vnull

<?php /** @author ciid */

#[Attribute(Attribute::TARGET_PROPERTY)]
class PropertyAttributes {
    public function __construct(
        public readonly ?string $name = null,
        public readonly ?string $label = null,
    ) {}
 }

#[Attribute(Attribute::TARGET_PROPERTY)]
class IntegerPropertyAttributes extends PropertyAttributes {
    public function __construct(
        ?string $name = null,
        ?string $label = null,
        public readonly ?int $default = null,
        public readonly ?int $min = null,
        public readonly ?int $max = null,
        public readonly ?int $step = null,
    ) { parent::__construct($name, $label); }
 }

#[Attribute(Attribute::TARGET_PROPERTY)]
class FloatPropertyAttributes extends PropertyAttributes {
    public function __construct(
        ?string $name = null,
        ?string $label = null,
        public readonly ?float $default = null,
        public readonly ?float $min = null,
        public readonly ?float $max = null,
    ) { parent::__construct($name, $label); }
 }

// model class with properties to edit in UI
class MyClass {
     #[IntegerPropertyAttributes('prop','property: ',5,0,10,1)]
     public int $prop;
     #[FloatPropertyAttributes('float','double: ',5.5,0.0,9.9)]
     public float $double;
 }

// index.php implementation
$props = [['MyClass', 'prop'], ['MyClass', 'double']];

foreach ($props as $prop) {        // class, property
    $refl = new ReflectionProperty($prop[0], $prop[1]);
    $reflAttrs = $refl->getAttributes();
    foreach ($reflAttrs as $attr)
        echo buildHtmlFormControl($attr->newInstance());
  }
/** TL:DR: */
function buildHtmlFormControl(PropertyAttributes $args): string {
    $html = [];
    $html[] = "<label>{$args->label} <input name=\"{$args->name}\" value=\"{$args->default}\"";
    switch ($args::class) {
        case 'IntegerPropertyAttributes':
            $html[] = " type=\"number\" min=\"{$args->min}\" max=\"{$args->max}\" step=\"{$args->step}\""; break;
        case 'FloatPropertyAttributes':
            $html[] = " type=\"number\" min=\"{$args->min}\" max=\"{$args->max}\""; break;
     }
    $html[] = "></label>\n";
    return implode('', $html);
 }
?>
To Top