1--TEST-- 2Attributes AST can be exported. 3--INI-- 4zend.assertions=1 5--FILE-- 6<?php 7 8try { 9 assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) { })); 10} catch (AssertionError $e) { 11 echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL; 12} 13 14try { 15 assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn () => 1)); 16} catch (AssertionError $e) { 17 echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL; 18} 19 20try { 21assert(0 && ($a = new #[A1] class() { 22 #[A1]#[A2] const FOO = 'foo'; 23 #[A2] public $x; 24 #[A3] function a() { } 25})); 26} catch (AssertionError $e) { 27 echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL; 28} 29 30try { 31assert(0 && ($a = function () { 32 #[A1] class Test1 { } 33 #[A2] interface Test2 { } 34 #[A3] trait Test3 { } 35})); 36} catch (AssertionError $e) { 37 echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL; 38} 39 40?> 41--EXPECT-- 42assert(): assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) { 43})) failed 44assert(): assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn() => 1)) failed 45assert(): assert(0 && ($a = new #[A1] class { 46 #[A1] 47 #[A2] 48 public const FOO = 'foo'; 49 #[A2] 50 public $x; 51 #[A3] 52 public function a() { 53 } 54 55})) failed 56assert(): assert(0 && ($a = function () { 57 #[A1] 58 class Test1 { 59 } 60 61 #[A2] 62 interface Test2 { 63 } 64 65 #[A3] 66 trait Test3 { 67 } 68 69})) failed 70