Verification: a143cc29221c9be0

Parse error syntax error unexpected function php

Enum синтаксис

PHP 8.1 резервирует и использует ключевое слово enum для объявления Enums. Синтаксис аналогичен синтаксису трейта/класса/интерфейса:

enum Status
{
case CREATED;
case COMPLETED;
case CANCELED;
case REFUNDED;
case FAILED;
}

Чувствительность к регистру

Само имя Enum нечувствительно к регистру , и оно соответствует тому, как PHP обрабатывает классы и функции без учета регистра. Отдельные регистры в Enum нечувствительны к регистру.

enum Status
{
case created;
case Completed;
case canCeleD;
}

Enum методы

Перечисления могут содержать методы, как и классы. Это очень мощная функция, особенно в сочетании с оператором match:

enum Status
{
case CREATED;
case COMPLETED;
case CANCELED;

public function color(): string
{
return match($this)
{
Status::CREATED => 'grey',
Status::COMPLETED => 'green',
Status::CANCELED => 'red'
};
}
}

 и далее использовать в коде как:

$status = Status::COMPLETED;
$status->color(); // "green"

 Разрешено использовать статические методы. Также обратите внимание, что вы можете использовать в перечислении self:

enum Status
{
// …

public function color(): string
{
return match($this)
{
self::CREATED => 'grey',
self::COMPLETED => 'green',
self::CANCELED=> 'red',
};
}
}

Enum интерфейсы  

Перечисления могут реализовывать интерфейсы, как и обычные классы:

interface HasColor
{
public function color(): string;
}
enum Status implements HasColor
{
case CREATED;
case COMPLETED;
case CANCELED;

public function color(): string { /* … */ }
}

Перечисления не должны содержать свойств

Одно из наиболее важных различий между Enum и классом заключается в том, что Enums не могут иметь никакого состояния. Объявление или установка свойств не разрешены. Статические свойства также не допускаются. 

enum Foo {
private string $test;
private static string $test2;
}

// Fatal error: Enums may not include member variables in ... on line ...

Кроме того, не допускается динамическая установка свойств:

enum Foo {
case Bar;
}
$bar = Foo::Bar;
$bar->test = 42;

// Error: Enum properties are immutable in ...:...

Enum значения или "Поддерживаемые перечисления"

Изначально значения Enum представлены внутри объектами, но вы можете присвоить им какое-то значение, например для сериализации их в базу данных.

enum Status: string
{
case CREATED = 'created';
case COMPLETED = 'completed';
case CANCELED = 'canceled';
}

Обратите внимание на объявление типа в определении перечисления. Он указывает, что все значения перечисления имеют данный тип. Вы также можете сделать их целочисленными - int. Обратите внимание, что разрешены только типы int и string, как значения перечисления.  

enum Status: int
{
case CREATED = 1;
case COMPLETED = 2;
case CANCELED = 3;
}

Технический термин для такого ввода перечислений называется «поддерживаемые перечисления», поскольку они «подкреплены» более простым значением. Если вы решили присвоить значения перечисления, тогда все варианты должны иметь какое-то значение. Вы не можете смешивать и сочетать их. Перечисления без "поддержки" называются "чистыми перечислениями". 

Сериализация поддерживаемых перечислений

Если вы присвоите значения enum, вам вероятно понадобится способ их сериализации и десериализации. Их сериализация означает, что вам нужен способ доступа к значению перечисления. Это делается с помощью public свойства value, обратите внимание, что оно только для чтения:

$value = Status::CANCELED->value; // 3

Получить перечисление из значения можно с помощью Enum::from 

$status = Status::from(2); // Status::COMPLETED

Также можно использовать tryFrom для возврата null при неизвестном значении. Если бы вы использовали from, то возникло бы исключение. 

$status = Status::from('unknown'); // ValueError
$status = Status::tryFrom('unknown'); // null

Вы также можете использовать встроенные функции serialize и unserialize на перечислениях. Кроме того, вы можете использовать json_serialize в сочетании с поддерживаемыми перечислениями, ее результатом будет значение перечисления. Это поведение можно изменить, реализовав JsonSerializable. 

Список значений перечисления

Вы можете использовать статический метод cases(), чтобы получить список всех доступных "случаев" в перечислении: Enum::cases()

Status::cases();

// [Status::CREATED, Status::COMPLETED, Status::CANCELED]

Перечисления - это объекты

Как уже выше упоминалось, значения перечислений представлены как объекты, хотя на самом деле это одноэлементные объекты. Это означает, что вы можете сравнивать их так:

$statusA = Status::COMPLETED;
$statusB = Status::COMPLETED;
$statusC = Status::CANCELED;

$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true

Перечисления как ключи массива

Поскольку значения перечислений на самом деле являются объектами, в настоящее время их невозможно использовать в качестве ключей массива. Следующий код приведет к ошибке:

$list = [
Status::CREATED => 'created',
// …
];

Существует RFC для изменения этого поведения, но он еще не был принят.

Это означает, что вы можете использовать только перечисления в качестве ключей в SplObjectStorage и WeakMaps. 

Перечисления могут иметь ноль или более значений

Внутри структуры enum может содержаться любое количество case от нуля до бесконечности. Оба этих объявления Enum валидны:

enum ErrorStates {
}
enum HTTPMethods {
case GET;
case POST;
}

Создание экземпляров с помощью new запрещено

Хотя кеймы Enum сами по себе являются объектами, их нельзя создавать с помощью конструкции new. Обе следующие new конструкции не допускаются:

enum Foo {
case Bar;
}

new Foo(); // Fatal error: Uncaught Error: Cannot instantiate enum Foo
new Foo::Bar(); Parse error: syntax error, unexpected identifier "Bar", expecting variable or "$"

Перечисления не могут быть расширены и не должны наследовать

Перечисления объявляются как final, и Enum не может наследоваться от другого Enum или класса.

enum Foo extends Bar {}

// Parse error: syntax error, unexpected token "extends", expecting "{" in ... on line ...

enum Foo {}
class Bar extends Foo {}

// Fatal error: Class Bar may not inherit from final class (Foo) in ... on line ...

vergessenes Semikolon

Ein absoluter Spitzenreiter ist das vergessene Semikolon (;) - als Fehlermeldung erhalten Sie dann auch prompt wie im Beispiel gezeigt, die falsche Zeile. Es ist nicht Zeile 4, die Probleme macht, sondern 3. Und warum kommt der Fehler laut der Fehlermeldung in der vierten Zeile? Ganz einfach - durch das fehlende Semikolon war der Befehl in der dritten Zeile noch nicht abgeschlossen und geht so in der folgenden Zeile weiter!

Resultierende Fehlermeldung:

Resultierende Fehlermeldung

Parse error: syntax error, unexpected T_ECHO, expecting ',' or ';'
in C:\xampp\htdocs\fehler-suchen.php on line 4

Zum Vermeiden, am besten immer nur 1 Befehl pro Zeile (dann ist es übersichtlicher) und am besten sofort das Semikolon schreiben

Merke: Bei einer Fehlermeldung ab der angegebenen Zeile nach oben weg suchen!

vergessenes zweites Anführungszeichen

Obwohl Anführungszeichen meistens im Doppelpack auftauchen und Inhalt umschließen, wird auch dort gern das zweite vergessen - Beispiel Zeile 5

Resultierende Fehlermeldung:

Resultierende Fehlermeldung

Parse error: syntax error, unexpected T_STRING, expecting ',' or ';'
in C:\xampp\htdocs\fehler-suchen.php on line 6

Am besten sofort beide Anführungszeichen schreiben und dann erst den Inhalt zwischen den Anführungszeichen.

vergessene Abschlussklammer

Auch sehr häufig kommt das Vergessen der Abschlussklammer vor (siehe Beispiel Zeile 7).

Resultierende Fehlermeldung:

Resultierende Fehlermeldung bei vergessenen Abschlussklammern

Parse error: syntax error, unexpected ';' in C:\xampp\htdocs\fehler-suchen.php on line 7

Das Vergessen der Abschlussklammern lässt sich am besten dadurch vermeiden, dass bei Benötigen der Anfangsklammer sofort die Abschlussklammer geschrieben wird und dann erst der Inhalt zwischen den Klammern.