Authentication Services
Command Line Specific Extensions
Compression and Archive Extensions
Cryptography Extensions
Database Extensions
Date and Time Related Extensions
File System Related Extensions
Human Language and Character Encoding Support
Image Processing and Generation
Mail Related Extensions
Mathematical Extensions
Non-Text MIME Output
Process Control Extensions
Other Basic Extensions
Other Services
Search Engine Extensions
Server Specific Extensions
Session Extensions
Text Processing
Variable and Type Related Extensions
Web Services
Windows Only Extensions
XML Manipulation
GUI Extensions
Keyboard Shortcuts
?
This help
Next menu item
Previous menu item
Previous man page
Next man page
Scroll to bottom
Scroll to top
Goto homepage
Goto search
(current page)
Focus search box
<?php
class
SomeClass
{}
interface
SomeInterface
{}
trait
SomeTrait
{}
var_dump
(new class(
10
) extends
SomeClass
implements
SomeInterface
{
private
$num
;
public function
__construct
(
$num
)
{
$this
->
num
=
$num
;
}
use
SomeTrait
;
});
The above example will output:
object(class@anonymous)#1 (1) {
["Command line code0x104c5b612":"class@anonymous":private]=>
int(10)
Nesting an anonymous class within another class does not give it access to
any private or protected methods or properties of that outer class. In order
to use the outer class' protected properties or methods, the anonymous class
can extend the outer class. To use the private properties of
the outer class in the anonymous class, they must be passed through its
constructor:
<?php
class
Outer
{
private
$prop
=
1
;
protected
$prop2
=
2
;
protected function
func1
()
{
return
3
;
}
public function
func2
()
{
return new class(
$this
->
prop
) extends
Outer
{
private
$prop3
;
public function
__construct
(
$prop
)
{
$this
->
prop3
=
$prop
;
}
public function
func3
()
{
return
$this
->
prop2
+
$this
->
prop3
+
$this
->
func1
();
}
};
}
}
echo (new
Outer
)->
func2
()->
func3
();
The above example will output:
<?php
function
anonymous_class
()
{
return new class {};
}
if (
get_class
(
anonymous_class
()) ===
get_class
(
anonymous_class
())) {
echo
'same class'
;
} else {
echo
'different class'
;
}
The above example will output:
same class
Note that anonymous classes are assigned a name by the engine, as
demonstrated in the following example. This name has to be regarded an
implementation detail, which should not be relied upon.
<?php
echo
get_class
(new class {});
The above example will output
something similar to:
class@anonymous/in/oNi1A0x7f8636ad2021
Below three examples describe anonymous class with very simple and basic but quite understandable example
<?php
$ano_class_obj
= new class{
public
$prop1
=
'hello'
;
public
$prop2
=
754
;
const
SETT
=
'some config'
;
public function
getValue
()
{
return
'some returned value'
;
}
public function
getValueWithArgu
(
$str
)
{
return
'returned value is '
.
$str
;
}
};
echo
"\n"
;
var_dump
(
$ano_class_obj
);
echo
"\n"
;
echo
$ano_class_obj
->
prop1
;
echo
"\n"
;
echo
$ano_class_obj
->
prop2
;
echo
"\n"
;
echo
$ano_class_obj
::
SETT
;
echo
"\n"
;
echo
$ano_class_obj
->
getValue
();
echo
"\n"
;
echo
$ano_class_obj
->
getValueWithArgu
(
'OOP'
);
echo
"\n"
;
echo
"\n"
;
$ano_class_obj_with_func
=
ano_func
();
function
ano_func
()
{
return new class {
public
$prop1
=
'hello'
;
public
$prop2
=
754
;
const
SETT
=
'some config'
;
public function
getValue
()
{
return
'some returned value'
;
}
public function
getValueWithArgu
(
$str
)
{
return
'returned value is '
.
$str
;
}
};
}
echo
"\n"
;
var_dump
(
$ano_class_obj_with_func
);
echo
"\n"
;
echo
$ano_class_obj_with_func
->
prop1
;
echo
"\n"
;
echo
$ano_class_obj_with_func
->
prop2
;
echo
"\n"
;
echo
$ano_class_obj_with_func
::
SETT
;
echo
"\n"
;
echo
$ano_class_obj_with_func
->
getValue
();
echo
"\n"
;
echo
$ano_class_obj_with_func
->
getValueWithArgu
(
'OOP'
);
echo
"\n"
;
echo
"\n"
;
$arg
=
1
;
$config
= [
2
,
false
];
$ano_class_obj_with_arg
=
ano_func_with_arg
(
$arg
,
$config
);
function
ano_func_with_arg
(
$arg
,
$config
)
{
return new class(
$arg
,
$config
) {
public
$prop1
=
'hello'
;
public
$prop2
=
754
;
public
$prop3
,
$config
;
const
SETT
=
'some config'
;
public function
__construct
(
$arg
,
$config
)
{
$this
->
prop3
=
$arg
;
$this
->
config
=
$config
;
}
public function
getValue
()
{
return
'some returned value'
;
}
public function
getValueWithArgu
(
$str
)
{
return
'returned value is '
.
$str
;
}
};
}
echo
"\n"
;
var_dump
(
$ano_class_obj_with_arg
);
echo
"\n"
;
echo
$ano_class_obj_with_arg
->
prop1
;
echo
"\n"
;
echo
$ano_class_obj_with_arg
->
prop2
;
echo
"\n"
;
echo
$ano_class_obj_with_arg
::
SETT
;
echo
"\n"
;
echo
$ano_class_obj_with_arg
->
getValue
();
echo
"\n"
;
echo
$ano_class_obj_with_arg
->
getValueWithArgu
(
'OOP'
);
echo
"\n"
;
echo
"\n"
;
Anonymous classes are syntax sugar that may appear deceiving to some.
The 'anonymous' class is still parsed into the global scope, where it is auto assigned a name, and every time the class is needed, that global class definition is used. Example to illustrate....
The anonymous class version...
<?php
function
return_anon
(){
return new class{
public static
$str
=
"foo"
;
};
}
$test
=
return_anon
();
echo
$test
::
$str
;
$another
=
get_class
(
$test
);
echo
$another
::
$str
;
?>
The above is functionally the same as doing this....
<?php
class
I_named_this_one
{
public static
$str
=
"foo"
;
}
function
return_not_anon
(){
return
'I_named_this_one'
;
}
$clzz
=
return_not_anon
();
echo
$clzz
::
$str
;
?>
I wanted to share my findings on static properties of anonymous classes.
So, given an anonymous class' object generating function like this:
<?php
function
nc
() {
return new class {
public static
$prop
= [];
};
}
?>
Getting a new object and changing the static property:
<?php
$a
=
nc
();
$a
::
$prop
[] =
'a'
;
var_dump
(
$a
::
$prop
);
?>
Now getting another object and changing the static property will change the original one, meaning that the static property is truly static:
<?php
$b
=
nc
();
$b
::
$prop
[] =
'b'
;
var_dump
(
$b
::
$prop
);
assert
(
$a
::
$prop
===
$b
::
$prop
);
?>
/* I like the idea of OneShot classes.
Thanks to that Anonymous bro\sist for precising
new class( $a, $b )
¯¯¯¯¯¯¯¯¯
If you are looking for "Delayed OneShot Anonymous Classes" for any reason (like the reason: loading files in a readable manner while not using autoload), it would probably look something like this; */
$u = function()use(&$u){
$u = new class{private $name = 'Utils';};
};
$w = function(&$rewrite)use(&$w){
$w = null;
$rewrite = new class{private $name = 'DataUtils';};
};
// Usage;
var_dump(
array(
'Delayed',
'( Self Destructive )',
'Anonymous Class Creation',
array(
'Before ( $u )' => $u,
'Running ( $u() )' => $u(),
'After ( $u )' => $u,
),
0,0,
0,0,
0,0,
'Delayed',
'( Overwriting && Self Destructive )',
'Anonymous Class Creation',
array(
'Before ( $w )' => $w,
'Running ( $w($u) )' => $w($u),
'After ( $w )' => $w,
'After ( $u )' => $u
)
)
);
// btw : oh shoot I failed a spam challenge
The only way to type hint this would appear to be as object.
If you need multiple instances of an anonymous class in a function you can use:
$class = function(string $arg):object {
return new class($arg) {
public function __construct(string $arg) {
$this->ow = $arg;
}
};
};
Though for the sake of structure it's ill advised to do something like this outside of a single scope or that's used across multiple files. If you class is only used in one scope however then it's probably not a code mess problem.
you can try these
<?php
$oracle
=&
$_
[
'nice_php'
];
$_
[
'nice_php'
]=(function(){
return new class{
public static function
say
(
$msg
){
echo
$msg
;
}
public static function
sp
(){
echo
self
::
say
(
' '
);
}
};
});
$oracle
()::
say
(
'Hello'
);
$oracle
()::
sp
();
$oracle
()::
say
(
'World'
);
$oracle
()::
sp
();
$oracle
()::
say
(
'!'
);
?>
Please note that class name returned by `get_class` might contain null bytes, as is the case in my version of PHP (7.1.4).
Name will change when class starting line or it's body is changed.
Yes, name is implementation detail that should not be relied upon, but in some rare use cases it is required (annotating anonymous class).
eval() is workaround for generating multiple anonymous classes with static properties in loop
<?php
public function
generateClassMap
()
{
foreach (
$this
->
classMap
as
$tableName
=>
$class
)
{
$c
=
null
;
eval(
'$c = new class extends \common\MyStaticClass {
public static $tableName;
public static function tableName()
{
return static::$tableName;
}
};'
);
$c
::
$tableName
=
$this
->
replicationPrefix
.
$tableName
;
$this
->
classMap
[
$tableName
] =
$c
;
}
}
?>
thus every class will have its own $tableName instead of common ancestor.
<?php
class
A
{
private
$name
;
public function
__construct
(
$name
)
{
$this
->
name
=
$name
;
}
public function
getName
()
{
return
$this
->
name
;
}
}
$b
= new class(
'anonymous'
) extends
A
{
public function
getName
()
{
return
parent
::
getName
() .
' class'
;
}
};
echo
$b
->
getName
(),
PHP_EOL
;